From 75fbf8809df91afb51382128203e439f56156b5b Mon Sep 17 00:00:00 2001 From: Thomas Laduguie Date: Fri, 4 Sep 2026 09:57:30 +0200 Subject: [PATCH] init --- Appli/.DS_Store | Bin 0 -> 8196 bytes Appli/Core/.DS_Store | Bin 0 -> 8196 bytes Appli/Core/Inc/FreeRTOSConfig.h | 179 + Appli/Core/Inc/RTE_Components.h | 28 + Appli/Core/Inc/jpeg_utils_conf.h | 62 + Appli/Core/Inc/main.h | 90 + Appli/Core/Inc/stm32h7rsxx_hal_conf.h | 520 + Appli/Core/Inc/stm32h7rsxx_it.h | 75 + Appli/Core/Inc/stm32h7s78_discovery_conf.h | 65 + Appli/Core/Src/freertos.c | 79 + Appli/Core/Src/main.c | 1030 + Appli/Core/Src/stm32h7rsxx_hal_msp.c | 803 + Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c | 192 + Appli/Core/Src/stm32h7rsxx_it.c | 337 + Appli/Core/Src/system_stm32h7rsxx.c | 304 + Appli/Middlewares/.DS_Store | Bin 0 -> 6148 bytes Appli/TouchGFX/App/app_touchgfx.c | 90 + Appli/TouchGFX/App/app_touchgfx.h | 60 + .../ApplicationTemplate.touchgfx.part | 34 + Appli/TouchGFX/CelloEffects.touchgfx | 193 + Appli/TouchGFX/CelloEffectsOld.touchgfx | 68 + Appli/TouchGFX/application.config | 24 + Appli/TouchGFX/assets/fonts/arial.ttf | Bin 0 -> 275572 bytes ...images_backgrounds_800x480_meteor_rain.png | Bin 0 -> 327784 bytes ...egular_height_50_medium_rounded_normal.png | Bin 0 -> 890 bytes ...gular_height_50_medium_rounded_pressed.png | Bin 0 -> 895 bytes ...idgets_gauge_medium_backgrounds_active.png | Bin 0 -> 15408 bytes ...es_widgets_gauge_medium_needles_smooth.png | Bin 0 -> 847 bytes ..._slider_horizontal_thick_filler_medium.png | Bin 0 -> 279 bytes ...s_slider_horizontal_thick_rounded_dark.png | Bin 0 -> 303 bytes ...s_slider_horizontal_thick_track_medium.png | Bin 0 -> 303 bytes ...s_backgrounds_800x480_gradient_rainbow.png | Bin 0 -> 128968 bytes ...me_images_action_done_50_50_E8F6FB.svg.png | Bin 0 -> 301 bytes ...e_images_action_input_50_50_E8F6FB.svg.png | Bin 0 -> 291 bytes Appli/TouchGFX/assets/texts/texts.xml | 14 + Appli/TouchGFX/assets/texts/texts.xsd | 168 + .../gui/common/FrontendApplication.hpp | 24 + .../gui/include/gui/common/FrontendHeap.hpp | 74 + .../initscreen_screen/InitScreenPresenter.hpp | 36 + .../gui/initscreen_screen/InitScreenView.hpp | 17 + .../TouchGFX/gui/include/gui/model/Model.hpp | 21 + .../gui/include/gui/model/ModelListener.hpp | 21 + .../gui/screen1_screen/Screen1Presenter.hpp | 36 + .../gui/screen1_screen/Screen1View.hpp | 18 + .../gui/src/common/FrontendApplication.cpp | 7 + .../initscreen_screen/InitScreenPresenter.cpp | 18 + .../src/initscreen_screen/InitScreenView.cpp | 16 + Appli/TouchGFX/gui/src/model/Model.cpp | 12 + .../src/screen1_screen/Screen1Presenter.cpp | 18 + .../gui/src/screen1_screen/Screen1View.cpp | 20 + .../target/CortexMMCUInstrumentation.cpp | 48 + .../target/CortexMMCUInstrumentation.hpp | 74 + .../TouchGFX/target/STM32TouchController.cpp | 94 + .../TouchGFX/target/STM32TouchController.hpp | 72 + Appli/TouchGFX/target/TouchGFXGPIO.cpp | 176 + Appli/TouchGFX/target/TouchGFXHAL.cpp | 189 + Appli/TouchGFX/target/TouchGFXHAL.hpp | 174 + .../DirectFrameBufferVideoController.hpp | 370 + .../target/generated/HardwareMJPEGDecoder.cpp | 934 + .../target/generated/HardwareMJPEGDecoder.hpp | 107 + .../target/generated/MJPEGDecoder.hpp | 89 + .../TouchGFX/target/generated/OSWrappers.cpp | 156 + Appli/TouchGFX/target/generated/STM32DMA.cpp | 1030 + Appli/TouchGFX/target/generated/STM32DMA.hpp | 263 + .../generated/TouchGFXConfiguration.cpp | 95 + .../target/generated/TouchGFXGeneratedHAL.cpp | 222 + .../target/generated/TouchGFXGeneratedHAL.hpp | 211 + Appli/TouchGFX/target/generated/nema_hal.c | 275 + Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld | 304 + Boot/Core/Inc/extmem_manager.h | 67 + Boot/Core/Inc/main.h | 90 + Boot/Core/Inc/stm32_extmem_conf.h | 118 + Boot/Core/Inc/stm32h7rsxx_hal_conf.h | 520 + Boot/Core/Inc/stm32h7rsxx_it.h | 66 + Boot/Core/Src/extmem_manager.c | 104 + Boot/Core/Src/main.c | 491 + Boot/Core/Src/stm32h7rsxx_hal_msp.c | 316 + Boot/Core/Src/stm32h7rsxx_it.c | 203 + Boot/Core/Src/system_stm32h7rsxx.c | 304 + Boot/stm32h7s7xx_flash.ld | 258 + Drivers/.DS_Store | Bin 0 -> 8196 bytes Drivers/CMSIS/Core/Include/cachel1_armv7.h | 411 + Drivers/CMSIS/Core/Include/cmsis_armcc.h | 888 + Drivers/CMSIS/Core/Include/cmsis_armclang.h | 1503 + .../CMSIS/Core/Include/cmsis_armclang_ltm.h | 1928 ++ Drivers/CMSIS/Core/Include/cmsis_compiler.h | 283 + Drivers/CMSIS/Core/Include/cmsis_gcc.h | 2211 ++ Drivers/CMSIS/Core/Include/cmsis_iccarm.h | 1002 + Drivers/CMSIS/Core/Include/cmsis_version.h | 39 + Drivers/CMSIS/Core/Include/core_armv81mml.h | 4228 +++ Drivers/CMSIS/Core/Include/core_armv8mbl.h | 2222 ++ Drivers/CMSIS/Core/Include/core_armv8mml.h | 3209 ++ Drivers/CMSIS/Core/Include/core_cm0.h | 952 + Drivers/CMSIS/Core/Include/core_cm0plus.h | 1087 + Drivers/CMSIS/Core/Include/core_cm1.h | 979 + Drivers/CMSIS/Core/Include/core_cm23.h | 2297 ++ Drivers/CMSIS/Core/Include/core_cm3.h | 1943 ++ Drivers/CMSIS/Core/Include/core_cm33.h | 3277 ++ Drivers/CMSIS/Core/Include/core_cm35p.h | 3277 ++ Drivers/CMSIS/Core/Include/core_cm4.h | 2129 ++ Drivers/CMSIS/Core/Include/core_cm55.h | 4817 +++ Drivers/CMSIS/Core/Include/core_cm7.h | 2366 ++ Drivers/CMSIS/Core/Include/core_cm85.h | 4672 +++ Drivers/CMSIS/Core/Include/core_sc000.h | 1030 + Drivers/CMSIS/Core/Include/core_sc300.h | 1917 ++ Drivers/CMSIS/Core/Include/core_starmc1.h | 3592 +++ Drivers/CMSIS/Core/Include/mpu_armv7.h | 275 + Drivers/CMSIS/Core/Include/mpu_armv8.h | 352 + Drivers/CMSIS/Core/Include/pac_armv81.h | 206 + Drivers/CMSIS/Core/Include/pmu_armv8.h | 337 + Drivers/CMSIS/Core/Include/tz_context.h | 70 + Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c | 58 + .../CMSIS/Core/Template/ARMv8-M/tz_context.c | 200 + Drivers/CMSIS/Core_A/Include/cmsis_armcc.h | 563 + Drivers/CMSIS/Core_A/Include/cmsis_armclang.h | 614 + Drivers/CMSIS/Core_A/Include/cmsis_compiler.h | 213 + Drivers/CMSIS/Core_A/Include/cmsis_cp15.h | 514 + Drivers/CMSIS/Core_A/Include/cmsis_gcc.h | 917 + Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h | 573 + Drivers/CMSIS/Core_A/Include/core_ca.h | 2614 ++ Drivers/CMSIS/Core_A/Include/irq_ctrl.h | 192 + Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c | 418 + .../CMSIS/DAP/Firmware/Config/DAP_config.h | 561 + Drivers/CMSIS/DAP/Firmware/Include/DAP.h | 367 + Drivers/CMSIS/DAP/Firmware/Source/DAP.c | 1812 ++ .../CMSIS/DAP/Firmware/Source/DAP_vendor.c | 100 + Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c | 370 + Drivers/CMSIS/DAP/Firmware/Source/SWO.c | 798 + Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c | 286 + Drivers/CMSIS/DAP/Firmware/Source/UART.c | 652 + .../ST/STM32H7RSxx/Include/stm32h7rsxx.h | 234 + .../ST/STM32H7RSxx/Include/stm32h7s7xx.h | 24680 ++++++++++++++++ .../STM32H7RSxx/Include/system_stm32h7rsxx.h | 95 + .../CMSIS/Device/ST/STM32H7RSxx/LICENSE.md | 201 + .../CMSIS/Device/ST/STM32H7RSxx/LICENSE.txt | 6 + .../Documentation/General/html/LICENSE.txt | 201 + Drivers/CMSIS/Include/cachel1_armv7.h | 441 + Drivers/CMSIS/Include/cmsis_armcc.h | 888 + Drivers/CMSIS/Include/cmsis_armclang.h | 1503 + Drivers/CMSIS/Include/cmsis_armclang_ltm.h | 1928 ++ Drivers/CMSIS/Include/cmsis_compiler.h | 283 + Drivers/CMSIS/Include/cmsis_gcc.h | 2211 ++ Drivers/CMSIS/Include/cmsis_iccarm.h | 1002 + Drivers/CMSIS/Include/cmsis_version.h | 39 + Drivers/CMSIS/Include/core_armv81mml.h | 4228 +++ Drivers/CMSIS/Include/core_armv8mbl.h | 2222 ++ Drivers/CMSIS/Include/core_armv8mml.h | 3209 ++ Drivers/CMSIS/Include/core_cm0.h | 952 + Drivers/CMSIS/Include/core_cm0plus.h | 1087 + Drivers/CMSIS/Include/core_cm1.h | 979 + Drivers/CMSIS/Include/core_cm23.h | 2297 ++ Drivers/CMSIS/Include/core_cm3.h | 1943 ++ Drivers/CMSIS/Include/core_cm33.h | 3277 ++ Drivers/CMSIS/Include/core_cm35p.h | 3277 ++ Drivers/CMSIS/Include/core_cm4.h | 2129 ++ Drivers/CMSIS/Include/core_cm55.h | 4817 +++ Drivers/CMSIS/Include/core_cm7.h | 2366 ++ Drivers/CMSIS/Include/core_cm85.h | 4672 +++ Drivers/CMSIS/Include/core_sc000.h | 1030 + Drivers/CMSIS/Include/core_sc300.h | 1917 ++ Drivers/CMSIS/Include/core_starmc1.h | 3592 +++ Drivers/CMSIS/Include/mpu_armv7.h | 275 + Drivers/CMSIS/Include/mpu_armv8.h | 352 + Drivers/CMSIS/Include/pac_armv81.h | 206 + Drivers/CMSIS/Include/pmu_armv8.h | 337 + Drivers/CMSIS/Include/tz_context.h | 70 + Drivers/CMSIS/LICENSE.txt | 201 + Drivers/CMSIS/RTOS/Template/cmsis_os.h | 698 + Drivers/CMSIS/RTOS2/Include/cmsis_os2.h | 756 + Drivers/CMSIS/RTOS2/Include/os_tick.h | 80 + Drivers/CMSIS/RTOS2/Source/os_systick.c | 133 + Drivers/CMSIS/RTOS2/Source/os_tick_gtim.c | 187 + Drivers/CMSIS/RTOS2/Source/os_tick_ptim.c | 165 + Drivers/CMSIS/RTOS2/Template/cmsis_os.h | 922 + Drivers/CMSIS/RTOS2/Template/cmsis_os1.c | 361 + Drivers/STM32H7RSxx_BSP/.DS_Store | Bin 0 -> 6148 bytes Drivers/STM32H7RSxx_BSP/Components/.DS_Store | Bin 0 -> 6148 bytes .../Components/Common/.DS_Store | Bin 0 -> 6148 bytes .../Components/Common/LICENSE.md | 27 + .../Components/Common/LICENSE.txt | 6 + .../Components/Common/Release_Notes.html | 252 + .../Components/Common/Release_Notes.md | 337 + .../Components/Common/_htmresc/Add button.svg | 2 + .../Components/Common/_htmresc/Update.svg | 2 + .../Components/Common/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../Components/Common/_htmresc/mini-st.css | 1711 ++ .../Components/Common/_htmresc/st_logo.png | Bin 0 -> 7520 bytes .../STM32H7RSxx_BSP/Components/Common/audio.h | 105 + .../Components/Common/camera.h | 106 + .../Components/Common/dpredriver.h | 102 + .../Components/Common/env_sensor.h | 95 + .../STM32H7RSxx_BSP/Components/Common/epd.h | 94 + .../Components/Common/hybrid_sensor.h | 108 + .../STM32H7RSxx_BSP/Components/Common/idd.h | 95 + .../STM32H7RSxx_BSP/Components/Common/io.h | 87 + .../STM32H7RSxx_BSP/Components/Common/lcd.h | 130 + .../Components/Common/light_sensor.h | 85 + .../Components/Common/motion_sensor.h | 99 + .../Components/Common/pwrmon.h | 251 + .../Components/Common/ranging_sensor.h | 83 + .../STM32H7RSxx_BSP/Components/Common/ts.h | 90 + .../Components/Common/usbtypecswitch.h | 112 + .../Components/aps256xx/LICENSE.md | 27 + .../Components/aps256xx/LICENSE.txt | 6 + .../Components/aps256xx/Release_Notes.html | 110 + .../Components/aps256xx/Release_Notes.md | 120 + .../aps256xx/_htmresc/Add button.svg | 2 + .../Components/aps256xx/_htmresc/Update.svg | 2 + .../Components/aps256xx/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../Components/aps256xx/_htmresc/mini-st.css | 1711 ++ .../aps256xx/_htmresc/mini-st_2020.css | 1711 ++ .../Components/aps256xx/_htmresc/st_logo.png | Bin 0 -> 18616 bytes .../aps256xx/_htmresc/st_logo_2020.png | Bin 0 -> 7520 bytes .../Components/aps256xx/aps256xx.c | 536 + .../Components/aps256xx/aps256xx.h | 287 + .../aps256xx/aps256xx_conf_template.h | 49 + .../Components/mx66uw1g45g/LICENSE.md | 27 + .../Components/mx66uw1g45g/LICENSE.txt | 6 + .../Components/mx66uw1g45g/Release_Notes.html | 61 + .../Components/mx66uw1g45g/Release_Notes.md | 58 + .../mx66uw1g45g/_htmresc/Add button.svg | 2 + .../mx66uw1g45g/_htmresc/Update.svg | 2 + .../mx66uw1g45g/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../mx66uw1g45g/_htmresc/mini-st_2020.css | 1711 ++ .../mx66uw1g45g/_htmresc/st_logo_2020.png | Bin 0 -> 7520 bytes .../Components/mx66uw1g45g/mx66uw1g45g.c | 1815 ++ .../Components/mx66uw1g45g/mx66uw1g45g.h | 384 + .../mx66uw1g45g/mx66uw1g45g_conf_template.h | 51 + .../Components/wm8904/LICENSE.md | 27 + .../Components/wm8904/LICENSE.txt | 6 + .../Components/wm8904/Release_Notes.html | 98 + .../Components/wm8904/Release_Notes.md | 75 + .../Components/wm8904/_htmresc/Add button.svg | 2 + .../Components/wm8904/_htmresc/Update.svg | 2 + .../Components/wm8904/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../wm8904/_htmresc/mini-st_2020.css | 1711 ++ .../wm8904/_htmresc/st_logo_2020.png | Bin 0 -> 7520 bytes .../Components/wm8904/wm8904.c | 1045 + .../Components/wm8904/wm8904.h | 224 + .../Components/wm8904/wm8904_reg.c | 88 + .../Components/wm8904/wm8904_reg.h | 228 + .../STM32H7RSxx_BSP/STM32H7S78-DK/.DS_Store | Bin 0 -> 6148 bytes .../STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.md | 27 + .../STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.txt | 6 + .../STM32H7RSxx_BSP/STM32H7S78-DK/README.md | 44 + .../STM32H7S78-DK/Release_Notes.html | 137 + .../STM32H7S78-DK/Release_Notes.md | 146 + .../STM32H7S78-DK_BSP_User_Manual.chm | Bin 0 -> 1361888 bytes .../STM32H7S78-DK/_htmresc/Add button.svg | 2 + .../STM32H7S78-DK/_htmresc/Update.svg | 2 + .../STM32H7S78-DK/_htmresc/favicon.png | Bin 0 -> 4126 bytes .../STM32H7S78-DK/_htmresc/mini-st_2020.css | 1711 ++ .../STM32H7S78-DK/_htmresc/st_logo_2020.png | Bin 0 -> 7520 bytes .../STM32H7S78-DK/bumpversion.cfg | 27 + .../STM32H7RSxx_BSP/STM32H7S78-DK/md2html.sh | 1 + .../STM32H7S78-DK/stm32h7s78_discovery.c | 841 + .../STM32H7S78-DK/stm32h7s78_discovery.h | 336 + .../stm32h7s78_discovery_audio.c | 3352 +++ .../stm32h7s78_discovery_audio.h | 358 + .../STM32H7S78-DK/stm32h7s78_discovery_bus.c | 885 + .../STM32H7S78-DK/stm32h7s78_discovery_bus.h | 135 + .../stm32h7s78_discovery_conf_template.h | 66 + .../stm32h7s78_discovery_errno.h | 70 + .../STM32H7S78-DK/stm32h7s78_discovery_lcd.c | 1613 + .../STM32H7S78-DK/stm32h7s78_discovery_lcd.h | 299 + .../STM32H7S78-DK/stm32h7s78_discovery_sd.c | 925 + .../STM32H7S78-DK/stm32h7s78_discovery_sd.h | 162 + .../STM32H7S78-DK/stm32h7s78_discovery_ts.c | 690 + .../STM32H7S78-DK/stm32h7s78_discovery_ts.h | 217 + .../stm32h7s78_discovery_usbpd_pwr.c | 1870 ++ .../stm32h7s78_discovery_usbpd_pwr.h | 337 + .../STM32H7S78-DK/stm32h7s78_discovery_xspi.c | 2482 ++ .../STM32H7S78-DK/stm32h7s78_discovery_xspi.h | 530 + Drivers/STM32H7RSxx_HAL_Driver/.DS_Store | Bin 0 -> 10244 bytes .../Inc/Legacy/stm32_hal_legacy.h | 4435 +++ .../Inc/stm32h7rsxx_hal.h | 791 + .../Inc/stm32h7rsxx_hal_cortex.h | 413 + .../Inc/stm32h7rsxx_hal_crc.h | 342 + .../Inc/stm32h7rsxx_hal_crc_ex.h | 150 + .../Inc/stm32h7rsxx_hal_def.h | 199 + .../Inc/stm32h7rsxx_hal_dma.h | 874 + .../Inc/stm32h7rsxx_hal_dma2d.h | 715 + .../Inc/stm32h7rsxx_hal_dma_ex.h | 719 + .../Inc/stm32h7rsxx_hal_exti.h | 347 + .../Inc/stm32h7rsxx_hal_flash.h | 803 + .../Inc/stm32h7rsxx_hal_flash_ex.h | 262 + .../Inc/stm32h7rsxx_hal_gpio.h | 326 + .../Inc/stm32h7rsxx_hal_gpio_ex.h | 266 + .../Inc/stm32h7rsxx_hal_gpu2d.h | 321 + .../Inc/stm32h7rsxx_hal_i2c.h | 842 + .../Inc/stm32h7rsxx_hal_i2c_ex.h | 156 + .../Inc/stm32h7rsxx_hal_i2s.h | 668 + .../Inc/stm32h7rsxx_hal_i2s_ex.h | 26 + .../Inc/stm32h7rsxx_hal_icache.h | 216 + .../Inc/stm32h7rsxx_hal_jpeg.h | 654 + .../Inc/stm32h7rsxx_hal_ltdc.h | 720 + .../Inc/stm32h7rsxx_hal_ltdc_ex.h | 87 + .../Inc/stm32h7rsxx_hal_mdf.h | 781 + .../Inc/stm32h7rsxx_hal_pwr.h | 589 + .../Inc/stm32h7rsxx_hal_pwr_ex.h | 610 + .../Inc/stm32h7rsxx_hal_rcc.h | 4814 +++ .../Inc/stm32h7rsxx_hal_rcc_ex.h | 1996 ++ .../Inc/stm32h7rsxx_hal_smbus.h | 787 + .../Inc/stm32h7rsxx_hal_smbus_ex.h | 133 + .../Inc/stm32h7rsxx_hal_tim.h | 2547 ++ .../Inc/stm32h7rsxx_hal_tim_ex.h | 1124 + .../Inc/stm32h7rsxx_hal_uart.h | 1777 ++ .../Inc/stm32h7rsxx_hal_uart_ex.h | 409 + .../Inc/stm32h7rsxx_hal_xspi.h | 1275 + .../Inc/stm32h7rsxx_ll_bus.h | 2734 ++ .../Inc/stm32h7rsxx_ll_cortex.h | 714 + .../Inc/stm32h7rsxx_ll_crc.h | 461 + .../Inc/stm32h7rsxx_ll_crs.h | 786 + .../Inc/stm32h7rsxx_ll_dma.h | 6677 +++++ .../Inc/stm32h7rsxx_ll_dma2d.h | 2230 ++ .../Inc/stm32h7rsxx_ll_exti.h | 1505 + .../Inc/stm32h7rsxx_ll_gpio.h | 994 + .../Inc/stm32h7rsxx_ll_i2c.h | 2372 ++ .../Inc/stm32h7rsxx_ll_icache.h | 453 + .../Inc/stm32h7rsxx_ll_pwr.h | 1887 ++ .../Inc/stm32h7rsxx_ll_rcc.h | 5934 ++++ .../Inc/stm32h7rsxx_ll_system.h | 2219 ++ .../Inc/stm32h7rsxx_ll_utils.h | 368 + Drivers/STM32H7RSxx_HAL_Driver/LICENSE.md | 3 + Drivers/STM32H7RSxx_HAL_Driver/LICENSE.txt | 6 + .../Src/stm32h7rsxx_hal.c | 1552 + .../Src/stm32h7rsxx_hal_cortex.c | 569 + .../Src/stm32h7rsxx_hal_crc.c | 520 + .../Src/stm32h7rsxx_hal_crc_ex.c | 230 + .../Src/stm32h7rsxx_hal_dma.c | 1755 ++ .../Src/stm32h7rsxx_hal_dma2d.c | 2186 ++ .../Src/stm32h7rsxx_hal_dma_ex.c | 4680 +++ .../Src/stm32h7rsxx_hal_exti.c | 639 + .../Src/stm32h7rsxx_hal_flash.c | 962 + .../Src/stm32h7rsxx_hal_flash_ex.c | 1322 + .../Src/stm32h7rsxx_hal_gpio.c | 556 + .../Src/stm32h7rsxx_hal_gpu2d.c | 750 + .../Src/stm32h7rsxx_hal_i2c.c | 7824 +++++ .../Src/stm32h7rsxx_hal_i2c_ex.c | 359 + .../Src/stm32h7rsxx_hal_i2s.c | 2806 ++ .../Src/stm32h7rsxx_hal_icache.c | 512 + .../Src/stm32h7rsxx_hal_jpeg.c | 4285 +++ .../Src/stm32h7rsxx_hal_ltdc.c | 2216 ++ .../Src/stm32h7rsxx_hal_ltdc_ex.c | 154 + .../Src/stm32h7rsxx_hal_mdf.c | 2236 ++ .../Src/stm32h7rsxx_hal_pwr.c | 692 + .../Src/stm32h7rsxx_hal_pwr_ex.c | 1601 + .../Src/stm32h7rsxx_hal_rcc.c | 2332 ++ .../Src/stm32h7rsxx_hal_rcc_ex.c | 3242 ++ .../Src/stm32h7rsxx_hal_smbus.c | 2771 ++ .../Src/stm32h7rsxx_hal_smbus_ex.c | 245 + .../Src/stm32h7rsxx_hal_tim.c | 8297 ++++++ .../Src/stm32h7rsxx_hal_tim_ex.c | 3351 +++ .../Src/stm32h7rsxx_hal_uart.c | 4886 +++ .../Src/stm32h7rsxx_hal_uart_ex.c | 1040 + .../Src/stm32h7rsxx_hal_xspi.c | 3473 +++ EWARM/Appli/STM32H7S78-DK_Appli.ewd | 1534 + EWARM/Appli/STM32H7S78-DK_Appli.ewp | 1307 + EWARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.icf | 69 + EWARM/Boot/STM32H7S78-DK_Boot.ewd | 1534 + EWARM/Boot/STM32H7S78-DK_Boot.ewp | 1207 + EWARM/Boot/stm32h7s7xx_flash.icf | 44 + EWARM/Project.eww | 9 + EWARM/startup_stm32h7s7xx.s | 1031 + MDK-ARM/Appli/STM32H7S78-DK_Appli.uvoptx | 1281 + MDK-ARM/Appli/STM32H7S78-DK_Appli.uvprojx | 2575 ++ .../Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.sct | 48 + MDK-ARM/Appli/stm32h7rsxx_ROMxspi1.sct | 34 + .../Appli/stm32h7rsxx_ROMxspi1_RAMxspi2.sct | 37 + MDK-ARM/Appli/stm32h7rsxx_ROMxspi2.sct | 34 + MDK-ARM/Appli/stm32h7s7xx_flash.sct | 34 + MDK-ARM/Appli/stm32h7s7xx_sram.sct | 34 + MDK-ARM/Boot/STM32H7S78-DK_Boot.uvoptx | 585 + MDK-ARM/Boot/STM32H7S78-DK_Boot.uvprojx | 1716 ++ MDK-ARM/Boot/stm32h7s7xx_flash.sct | 39 + MDK-ARM/Boot/stm32h7s7xx_sram.sct | 34 + MDK-ARM/Project.uvmpw | 23 + MDK-ARM/startup_stm32h7s7xx.s | 633 + Middlewares/.DS_Store | Bin 0 -> 6148 bytes .../ST/STM32_ExtMem_Manager/LICENSE.md | 80 + .../boot/stm32_boot_xip.c | 191 + .../boot/stm32_boot_xip.h | 76 + .../nor_sfdp/stm32_sfdp_data.c | 2906 ++ .../nor_sfdp/stm32_sfdp_data.h | 147 + .../nor_sfdp/stm32_sfdp_driver.c | 816 + .../nor_sfdp/stm32_sfdp_driver_api.h | 121 + .../nor_sfdp/stm32_sfdp_driver_type.h | 156 + .../psram/stm32_psram_driver.c | 283 + .../psram/stm32_psram_driver_api.h | 87 + .../psram/stm32_psram_driver_type.h | 106 + .../STM32_ExtMem_Manager/sal/stm32_sal_sd.c | 236 + .../sal/stm32_sal_sd_api.h | 77 + .../sal/stm32_sal_sd_type.h | 74 + .../STM32_ExtMem_Manager/sal/stm32_sal_xspi.c | 1245 + .../sal/stm32_sal_xspi_api.h | 100 + .../sal/stm32_sal_xspi_type.h | 130 + .../sdcard/stm32_sdcard_driver.c | 354 + .../sdcard/stm32_sdcard_driver_api.h | 91 + .../sdcard/stm32_sdcard_driver_type.h | 91 + .../ST/STM32_ExtMem_Manager/stm32_extmem.c | 1189 + .../ST/STM32_ExtMem_Manager/stm32_extmem.h | 165 + .../STM32_ExtMem_Manager/stm32_extmem_type.h | 158 + .../user/stm32_user_driver.c | 212 + .../user/stm32_user_driver_api.h | 103 + .../user/stm32_user_driver_type.h | 72 + Middlewares/Third_Party/FreeRTOS/LICENSE.md | 19 + .../FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h | 34 + .../FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c | 2957 ++ .../Source/CMSIS_RTOS_V2/freertos_mpool.h | 63 + .../Source/CMSIS_RTOS_V2/freertos_os2.h | 310 + .../Third_Party/FreeRTOS/Source/LICENSE | 19 + .../Third_Party/FreeRTOS/Source/croutine.c | 363 + .../FreeRTOS/Source/event_groups.c | 799 + .../FreeRTOS/Source/include/FreeRTOS.h | 1460 + .../FreeRTOS/Source/include/StackMacros.h | 34 + .../FreeRTOS/Source/include/atomic.h | 419 + .../FreeRTOS/Source/include/croutine.h | 755 + .../Source/include/deprecated_definitions.h | 281 + .../FreeRTOS/Source/include/event_groups.h | 827 + .../FreeRTOS/Source/include/list.h | 503 + .../FreeRTOS/Source/include/message_buffer.h | 887 + .../FreeRTOS/Source/include/mpu_prototypes.h | 476 + .../Source/include/mpu_syscall_numbers.h | 106 + .../FreeRTOS/Source/include/mpu_wrappers.h | 297 + .../FreeRTOS/Source/include/newlib-freertos.h | 62 + .../Source/include/picolibc-freertos.h | 90 + .../FreeRTOS/Source/include/portable.h | 271 + .../FreeRTOS/Source/include/projdefs.h | 131 + .../FreeRTOS/Source/include/queue.h | 1764 ++ .../FreeRTOS/Source/include/semphr.h | 1214 + .../FreeRTOS/Source/include/stack_macros.h | 137 + .../FreeRTOS/Source/include/stream_buffer.h | 945 + .../FreeRTOS/Source/include/task.h | 3235 ++ .../FreeRTOS/Source/include/timers.h | 1403 + .../Third_Party/FreeRTOS/Source/list.c | 226 + .../Source/portable/Common/mpu_wrappers.c | 2545 ++ .../Source/portable/Common/mpu_wrappers_v2.c | 5054 ++++ .../Source/portable/GCC/ARM_CM4F/port.c | 857 + .../Source/portable/GCC/ARM_CM4F/portmacro.h | 254 + .../FreeRTOS/Source/portable/MemMang/heap_4.c | 555 + .../Third_Party/FreeRTOS/Source/queue.c | 3148 ++ .../FreeRTOS/Source/stream_buffer.c | 1455 + .../Third_Party/FreeRTOS/Source/tasks.c | 5534 ++++ .../Third_Party/FreeRTOS/Source/timers.c | 1146 + STM32CubeIDE/.DS_Store | Bin 0 -> 8196 bytes STM32CubeIDE/.osx.project | 0 STM32CubeIDE/.project | 102 + STM32CubeIDE/Appli/.DS_Store | Bin 0 -> 6148 bytes STM32CubeIDE/Appli/.cproject | 355 + STM32CubeIDE/Appli/.project | 594 + .../Appli/Application/User/Core/syscalls.c | 176 + .../Appli/Application/User/Core/sysmem.c | 79 + .../User/Startup/startup_stm32h7s7l8hxh.s | 780 + STM32CubeIDE/Appli/Drivers/.DS_Store | Bin 0 -> 6148 bytes STM32CubeIDE/Appli/STM32H7S78-DK_Appli.launch | 90 + .../Appli/STM32H7S7L8HXH_OEMiROT_Appli.ld | 236 + .../Appli/STM32H7S7L8HXH_RAMxspi1_ROMxspi2.ld | 212 + STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1.ld | 208 + .../Appli/STM32H7S7L8HXH_ROMxspi1_RAMxspi2.ld | 211 + STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi2.ld | 208 + .../Appli/STM32H7S7L8HXH_STiROT_Appli.ld | 214 + STM32CubeIDE/Appli/STM32H7S7L8HXH_default.ld | 208 + STM32CubeIDE/Appli/STM32H7S7L8HXH_sram.ld | 209 + STM32CubeIDE/Boot/.cproject | 256 + STM32CubeIDE/Boot/.project | 177 + .../Boot/Application/User/Core/syscalls.c | 176 + .../Boot/Application/User/Core/sysmem.c | 79 + .../User/Startup/startup_stm32h7s7l8hxh.s | 780 + STM32CubeIDE/Boot/STM32H7S78-DK_Boot.launch | 83 + STM32CubeIDE/Boot/STM32H7S7L8HXH_FLASH.ld | 208 + STM32CubeIDE/ExtMemLoader/postbuild.sh | 94 + STM32H7S78-DK.ioc | 988 + Utilities/JPEG/jpeg_utils.c | 1984 ++ Utilities/JPEG/jpeg_utils.h | 101 + Utilities/JPEG/jpeg_utils_conf_template.h | 66 + changelog.txt | 48 + gcc/MX66UW1G45G_STM32H7S78-DK.stldr | Bin 0 -> 239516 bytes gcc/Makefile | 9 + .../Source/portable/GCC/ARM_CM4F/port.c | 775 + .../Source/portable/GCC/ARM_CM4F/portmacro.h | 243 + gcc/include/cube_programmer.mk | 38 + gcc/include/flash_sections_int_ext.mk | 10 + gcc/makefile_appli | 469 + gcc/makefile_boot | 295 + gcc/startup_stm32h7s7l8hxh_appli.s | 780 + gcc/startup_stm32h7s7l8hxh_boot.s | 780 + gcc/syscalls.c | 176 + gcc/sysmem.c | 79 + readme.md | 22 + 489 files changed, 398278 insertions(+) create mode 100644 Appli/.DS_Store create mode 100644 Appli/Core/.DS_Store create mode 100644 Appli/Core/Inc/FreeRTOSConfig.h create mode 100644 Appli/Core/Inc/RTE_Components.h create mode 100644 Appli/Core/Inc/jpeg_utils_conf.h create mode 100644 Appli/Core/Inc/main.h create mode 100644 Appli/Core/Inc/stm32h7rsxx_hal_conf.h create mode 100644 Appli/Core/Inc/stm32h7rsxx_it.h create mode 100644 Appli/Core/Inc/stm32h7s78_discovery_conf.h create mode 100644 Appli/Core/Src/freertos.c create mode 100644 Appli/Core/Src/main.c create mode 100644 Appli/Core/Src/stm32h7rsxx_hal_msp.c create mode 100644 Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c create mode 100644 Appli/Core/Src/stm32h7rsxx_it.c create mode 100644 Appli/Core/Src/system_stm32h7rsxx.c create mode 100644 Appli/Middlewares/.DS_Store create mode 100644 Appli/TouchGFX/App/app_touchgfx.c create mode 100644 Appli/TouchGFX/App/app_touchgfx.h create mode 100644 Appli/TouchGFX/ApplicationTemplate.touchgfx.part create mode 100644 Appli/TouchGFX/CelloEffects.touchgfx create mode 100644 Appli/TouchGFX/CelloEffectsOld.touchgfx create mode 100644 Appli/TouchGFX/application.config create mode 100644 Appli/TouchGFX/assets/fonts/arial.ttf create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_backgrounds_800x480_meteor_rain.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_button_regular_height_50_medium_rounded_normal.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_button_regular_height_50_medium_rounded_pressed.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_gauge_medium_backgrounds_active.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_gauge_medium_needles_smooth.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_filler_medium.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_rounded_dark.png create mode 100644 Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_track_medium.png create mode 100644 Appli/TouchGFX/assets/images/__generated/glass_theme_images_backgrounds_800x480_gradient_rainbow.png create mode 100644 Appli/TouchGFX/assets/images/__generated/icon_theme_images_action_done_50_50_E8F6FB.svg.png create mode 100644 Appli/TouchGFX/assets/images/__generated/icon_theme_images_action_input_50_50_E8F6FB.svg.png create mode 100644 Appli/TouchGFX/assets/texts/texts.xml create mode 100644 Appli/TouchGFX/assets/texts/texts.xsd create mode 100644 Appli/TouchGFX/gui/include/gui/common/FrontendApplication.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/common/FrontendHeap.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenPresenter.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenView.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/model/Model.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/model/ModelListener.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1Presenter.hpp create mode 100644 Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1View.hpp create mode 100644 Appli/TouchGFX/gui/src/common/FrontendApplication.cpp create mode 100644 Appli/TouchGFX/gui/src/initscreen_screen/InitScreenPresenter.cpp create mode 100644 Appli/TouchGFX/gui/src/initscreen_screen/InitScreenView.cpp create mode 100644 Appli/TouchGFX/gui/src/model/Model.cpp create mode 100644 Appli/TouchGFX/gui/src/screen1_screen/Screen1Presenter.cpp create mode 100644 Appli/TouchGFX/gui/src/screen1_screen/Screen1View.cpp create mode 100644 Appli/TouchGFX/target/CortexMMCUInstrumentation.cpp create mode 100644 Appli/TouchGFX/target/CortexMMCUInstrumentation.hpp create mode 100644 Appli/TouchGFX/target/STM32TouchController.cpp create mode 100644 Appli/TouchGFX/target/STM32TouchController.hpp create mode 100644 Appli/TouchGFX/target/TouchGFXGPIO.cpp create mode 100644 Appli/TouchGFX/target/TouchGFXHAL.cpp create mode 100644 Appli/TouchGFX/target/TouchGFXHAL.hpp create mode 100644 Appli/TouchGFX/target/generated/DirectFrameBufferVideoController.hpp create mode 100644 Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp create mode 100644 Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.hpp create mode 100644 Appli/TouchGFX/target/generated/MJPEGDecoder.hpp create mode 100644 Appli/TouchGFX/target/generated/OSWrappers.cpp create mode 100644 Appli/TouchGFX/target/generated/STM32DMA.cpp create mode 100644 Appli/TouchGFX/target/generated/STM32DMA.hpp create mode 100644 Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp create mode 100644 Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp create mode 100644 Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.hpp create mode 100644 Appli/TouchGFX/target/generated/nema_hal.c create mode 100644 Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld create mode 100644 Boot/Core/Inc/extmem_manager.h create mode 100644 Boot/Core/Inc/main.h create mode 100644 Boot/Core/Inc/stm32_extmem_conf.h create mode 100644 Boot/Core/Inc/stm32h7rsxx_hal_conf.h create mode 100644 Boot/Core/Inc/stm32h7rsxx_it.h create mode 100644 Boot/Core/Src/extmem_manager.c create mode 100644 Boot/Core/Src/main.c create mode 100644 Boot/Core/Src/stm32h7rsxx_hal_msp.c create mode 100644 Boot/Core/Src/stm32h7rsxx_it.c create mode 100644 Boot/Core/Src/system_stm32h7rsxx.c create mode 100644 Boot/stm32h7s7xx_flash.ld create mode 100644 Drivers/.DS_Store create mode 100644 Drivers/CMSIS/Core/Include/cachel1_armv7.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_armcc.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_armclang.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_armclang_ltm.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_compiler.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_gcc.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_iccarm.h create mode 100644 Drivers/CMSIS/Core/Include/cmsis_version.h create mode 100644 Drivers/CMSIS/Core/Include/core_armv81mml.h create mode 100644 Drivers/CMSIS/Core/Include/core_armv8mbl.h create mode 100644 Drivers/CMSIS/Core/Include/core_armv8mml.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm0.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm0plus.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm1.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm23.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm3.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm33.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm35p.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm4.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm55.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm7.h create mode 100644 Drivers/CMSIS/Core/Include/core_cm85.h create mode 100644 Drivers/CMSIS/Core/Include/core_sc000.h create mode 100644 Drivers/CMSIS/Core/Include/core_sc300.h create mode 100644 Drivers/CMSIS/Core/Include/core_starmc1.h create mode 100644 Drivers/CMSIS/Core/Include/mpu_armv7.h create mode 100644 Drivers/CMSIS/Core/Include/mpu_armv8.h create mode 100644 Drivers/CMSIS/Core/Include/pac_armv81.h create mode 100644 Drivers/CMSIS/Core/Include/pmu_armv8.h create mode 100644 Drivers/CMSIS/Core/Include/tz_context.h create mode 100644 Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c create mode 100644 Drivers/CMSIS/Core/Template/ARMv8-M/tz_context.c create mode 100644 Drivers/CMSIS/Core_A/Include/cmsis_armcc.h create mode 100644 Drivers/CMSIS/Core_A/Include/cmsis_armclang.h create mode 100644 Drivers/CMSIS/Core_A/Include/cmsis_compiler.h create mode 100644 Drivers/CMSIS/Core_A/Include/cmsis_cp15.h create mode 100644 Drivers/CMSIS/Core_A/Include/cmsis_gcc.h create mode 100644 Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h create mode 100644 Drivers/CMSIS/Core_A/Include/core_ca.h create mode 100644 Drivers/CMSIS/Core_A/Include/irq_ctrl.h create mode 100644 Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c create mode 100644 Drivers/CMSIS/DAP/Firmware/Config/DAP_config.h create mode 100644 Drivers/CMSIS/DAP/Firmware/Include/DAP.h create mode 100644 Drivers/CMSIS/DAP/Firmware/Source/DAP.c create mode 100644 Drivers/CMSIS/DAP/Firmware/Source/DAP_vendor.c create mode 100644 Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c create mode 100644 Drivers/CMSIS/DAP/Firmware/Source/SWO.c create mode 100644 Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c create mode 100644 Drivers/CMSIS/DAP/Firmware/Source/UART.c create mode 100644 Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7rsxx.h create mode 100644 Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7s7xx.h create mode 100644 Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/system_stm32h7rsxx.h create mode 100644 Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.md create mode 100644 Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.txt create mode 100644 Drivers/CMSIS/Documentation/General/html/LICENSE.txt create mode 100644 Drivers/CMSIS/Include/cachel1_armv7.h create mode 100644 Drivers/CMSIS/Include/cmsis_armcc.h create mode 100644 Drivers/CMSIS/Include/cmsis_armclang.h create mode 100644 Drivers/CMSIS/Include/cmsis_armclang_ltm.h create mode 100644 Drivers/CMSIS/Include/cmsis_compiler.h create mode 100644 Drivers/CMSIS/Include/cmsis_gcc.h create mode 100644 Drivers/CMSIS/Include/cmsis_iccarm.h create mode 100644 Drivers/CMSIS/Include/cmsis_version.h create mode 100644 Drivers/CMSIS/Include/core_armv81mml.h create mode 100644 Drivers/CMSIS/Include/core_armv8mbl.h create mode 100644 Drivers/CMSIS/Include/core_armv8mml.h create mode 100644 Drivers/CMSIS/Include/core_cm0.h create mode 100644 Drivers/CMSIS/Include/core_cm0plus.h create mode 100644 Drivers/CMSIS/Include/core_cm1.h create mode 100644 Drivers/CMSIS/Include/core_cm23.h create mode 100644 Drivers/CMSIS/Include/core_cm3.h create mode 100644 Drivers/CMSIS/Include/core_cm33.h create mode 100644 Drivers/CMSIS/Include/core_cm35p.h create mode 100644 Drivers/CMSIS/Include/core_cm4.h create mode 100644 Drivers/CMSIS/Include/core_cm55.h create mode 100644 Drivers/CMSIS/Include/core_cm7.h create mode 100644 Drivers/CMSIS/Include/core_cm85.h create mode 100644 Drivers/CMSIS/Include/core_sc000.h create mode 100644 Drivers/CMSIS/Include/core_sc300.h create mode 100644 Drivers/CMSIS/Include/core_starmc1.h create mode 100644 Drivers/CMSIS/Include/mpu_armv7.h create mode 100644 Drivers/CMSIS/Include/mpu_armv8.h create mode 100644 Drivers/CMSIS/Include/pac_armv81.h create mode 100644 Drivers/CMSIS/Include/pmu_armv8.h create mode 100644 Drivers/CMSIS/Include/tz_context.h create mode 100644 Drivers/CMSIS/LICENSE.txt create mode 100644 Drivers/CMSIS/RTOS/Template/cmsis_os.h create mode 100644 Drivers/CMSIS/RTOS2/Include/cmsis_os2.h create mode 100644 Drivers/CMSIS/RTOS2/Include/os_tick.h create mode 100644 Drivers/CMSIS/RTOS2/Source/os_systick.c create mode 100644 Drivers/CMSIS/RTOS2/Source/os_tick_gtim.c create mode 100644 Drivers/CMSIS/RTOS2/Source/os_tick_ptim.c create mode 100644 Drivers/CMSIS/RTOS2/Template/cmsis_os.h create mode 100644 Drivers/CMSIS/RTOS2/Template/cmsis_os1.c create mode 100644 Drivers/STM32H7RSxx_BSP/.DS_Store create mode 100644 Drivers/STM32H7RSxx_BSP/Components/.DS_Store create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/.DS_Store create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.txt create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.html create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Add button.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Update.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/favicon.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/mini-st.css create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/st_logo.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/audio.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/camera.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/dpredriver.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/env_sensor.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/epd.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/hybrid_sensor.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/idd.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/io.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/lcd.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/light_sensor.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/motion_sensor.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/pwrmon.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/ranging_sensor.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/ts.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/Common/usbtypecswitch.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.txt create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.html create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Add button.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Update.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/favicon.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st.css create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st_2020.css create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/st_logo.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/st_logo_2020.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.c create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx_conf_template.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.txt create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.html create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Add button.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Update.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/favicon.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/mini-st_2020.css create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/st_logo_2020.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.c create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g_conf_template.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.txt create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.html create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.md create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Add button.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Update.svg create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/favicon.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/mini-st_2020.css create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/st_logo_2020.png create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.c create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.h create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.c create mode 100644 Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/.DS_Store create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.md create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.txt create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/README.md create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.html create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.md create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/STM32H7S78-DK_BSP_User_Manual.chm create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/Add button.svg create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/Update.svg create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/favicon.png create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/mini-st_2020.css create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/st_logo_2020.png create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/bumpversion.cfg create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/md2html.sh create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_conf_template.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_errno.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.h create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.c create mode 100644 Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/.DS_Store create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_cortex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_def.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma2d.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_exti.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpu2d.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_icache.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_jpeg.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_mdf.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart_ex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_xspi.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_bus.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_cortex.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crc.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crs.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma2d.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_exti.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_gpio.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_i2c.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_icache.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_pwr.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_rcc.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_system.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_utils.h create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/LICENSE.md create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/LICENSE.txt create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart_ex.c create mode 100644 Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c create mode 100644 EWARM/Appli/STM32H7S78-DK_Appli.ewd create mode 100644 EWARM/Appli/STM32H7S78-DK_Appli.ewp create mode 100644 EWARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.icf create mode 100644 EWARM/Boot/STM32H7S78-DK_Boot.ewd create mode 100644 EWARM/Boot/STM32H7S78-DK_Boot.ewp create mode 100644 EWARM/Boot/stm32h7s7xx_flash.icf create mode 100644 EWARM/Project.eww create mode 100644 EWARM/startup_stm32h7s7xx.s create mode 100644 MDK-ARM/Appli/STM32H7S78-DK_Appli.uvoptx create mode 100644 MDK-ARM/Appli/STM32H7S78-DK_Appli.uvprojx create mode 100644 MDK-ARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.sct create mode 100644 MDK-ARM/Appli/stm32h7rsxx_ROMxspi1.sct create mode 100644 MDK-ARM/Appli/stm32h7rsxx_ROMxspi1_RAMxspi2.sct create mode 100644 MDK-ARM/Appli/stm32h7rsxx_ROMxspi2.sct create mode 100644 MDK-ARM/Appli/stm32h7s7xx_flash.sct create mode 100644 MDK-ARM/Appli/stm32h7s7xx_sram.sct create mode 100644 MDK-ARM/Boot/STM32H7S78-DK_Boot.uvoptx create mode 100644 MDK-ARM/Boot/STM32H7S78-DK_Boot.uvprojx create mode 100644 MDK-ARM/Boot/stm32h7s7xx_flash.sct create mode 100644 MDK-ARM/Boot/stm32h7s7xx_sram.sct create mode 100644 MDK-ARM/Project.uvmpw create mode 100644 MDK-ARM/startup_stm32h7s7xx.s create mode 100644 Middlewares/.DS_Store create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/LICENSE.md create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_api.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_type.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_api.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_type.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_api.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_type.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_api.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_type.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_api.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_type.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem_type.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_api.h create mode 100644 Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_type.h create mode 100644 Middlewares/Third_Party/FreeRTOS/LICENSE.md create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/LICENSE create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/croutine.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/event_groups.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/list.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/mpu_syscall_numbers.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/newlib-freertos.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/picolibc-freertos.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/portable.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/queue.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/task.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/include/timers.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/list.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers_v2.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/queue.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/tasks.c create mode 100644 Middlewares/Third_Party/FreeRTOS/Source/timers.c create mode 100644 STM32CubeIDE/.DS_Store create mode 100644 STM32CubeIDE/.osx.project create mode 100644 STM32CubeIDE/.project create mode 100644 STM32CubeIDE/Appli/.DS_Store create mode 100644 STM32CubeIDE/Appli/.cproject create mode 100644 STM32CubeIDE/Appli/.project create mode 100644 STM32CubeIDE/Appli/Application/User/Core/syscalls.c create mode 100644 STM32CubeIDE/Appli/Application/User/Core/sysmem.c create mode 100644 STM32CubeIDE/Appli/Application/User/Startup/startup_stm32h7s7l8hxh.s create mode 100644 STM32CubeIDE/Appli/Drivers/.DS_Store create mode 100644 STM32CubeIDE/Appli/STM32H7S78-DK_Appli.launch create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_OEMiROT_Appli.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_RAMxspi1_ROMxspi2.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1_RAMxspi2.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi2.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_STiROT_Appli.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_default.ld create mode 100644 STM32CubeIDE/Appli/STM32H7S7L8HXH_sram.ld create mode 100644 STM32CubeIDE/Boot/.cproject create mode 100644 STM32CubeIDE/Boot/.project create mode 100644 STM32CubeIDE/Boot/Application/User/Core/syscalls.c create mode 100644 STM32CubeIDE/Boot/Application/User/Core/sysmem.c create mode 100644 STM32CubeIDE/Boot/Application/User/Startup/startup_stm32h7s7l8hxh.s create mode 100644 STM32CubeIDE/Boot/STM32H7S78-DK_Boot.launch create mode 100644 STM32CubeIDE/Boot/STM32H7S7L8HXH_FLASH.ld create mode 100644 STM32CubeIDE/ExtMemLoader/postbuild.sh create mode 100644 STM32H7S78-DK.ioc create mode 100644 Utilities/JPEG/jpeg_utils.c create mode 100644 Utilities/JPEG/jpeg_utils.h create mode 100644 Utilities/JPEG/jpeg_utils_conf_template.h create mode 100644 changelog.txt create mode 100644 gcc/MX66UW1G45G_STM32H7S78-DK.stldr create mode 100644 gcc/Makefile create mode 100644 gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c create mode 100644 gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h create mode 100644 gcc/include/cube_programmer.mk create mode 100644 gcc/include/flash_sections_int_ext.mk create mode 100644 gcc/makefile_appli create mode 100644 gcc/makefile_boot create mode 100644 gcc/startup_stm32h7s7l8hxh_appli.s create mode 100644 gcc/startup_stm32h7s7l8hxh_boot.s create mode 100644 gcc/syscalls.c create mode 100644 gcc/sysmem.c create mode 100644 readme.md diff --git a/Appli/.DS_Store b/Appli/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2b2e0f3f6c877fe4a2ee7c233552b7faec150e59 GIT binary patch literal 8196 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 U>OT+a{@G93aR0C5@tUT811c(UIsgCw literal 0 HcmV?d00001 diff --git a/Appli/Core/Inc/FreeRTOSConfig.h b/Appli/Core/Inc/FreeRTOSConfig.h new file mode 100644 index 0000000..6eaf4ee --- /dev/null +++ b/Appli/Core/Inc/FreeRTOSConfig.h @@ -0,0 +1,179 @@ +/* USER CODE BEGIN Header */ +/* + * FreeRTOS Kernel V10.5.1 + * Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE . + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ +/* USER CODE END Header */ +#ifndef __FREERTOS_CONFIG_H +#define __FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +/* USER CODE BEGIN Includes */ +/* Section where include file can be added */ +/* USER CODE END Includes */ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +#include +extern uint32_t SystemCoreClock; +#endif +#ifndef CMSIS_device_header +#define CMSIS_device_header "stm32h7rsxx.h" +#endif /* CMSIS_device_header */ + +#define configENABLE_FPU 0 +#define configENABLE_MPU 0 + +#define configUSE_PREEMPTION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES ( 56 ) +#define configUSE_SB_COMPLETED_CALLBACK ( 0 ) +#define configUSE_MINI_LIST_ITEM ( 1 ) +#define configMINIMAL_STACK_SIZE ((uint16_t)128) +#define configTOTAL_HEAP_SIZE ((size_t)50000) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configHEAP_CLEAR_MEMORY_ON_FREE 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ +/* Defaults to size_t for backward compatibility, but can be changed + if lengths will always be less than the number of bytes in a size_t. */ +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( 2 ) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 256 + +/* The following flag must be enabled only when using newlib */ +#define configUSE_NEWLIB_REENTRANT 1 + +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 1 +#define configTEX_S_C_B_SRAM ( 0x03UL ) +#define configTOTAL_MPU_REGIONS 16 +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_eTaskGetState 1 + +/* + * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used + * by the application thus the correct define need to be enabled below + */ +#define USE_FreeRTOS_HEAP_4 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 4 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ + +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +/* USER CODE BEGIN 1 */ +#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} +/* USER CODE END 1 */ + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ + +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0 + +/* USER CODE BEGIN Defines */ +/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook( pxCurrentTCB, (void*)1 ) +#define traceTASK_SWITCHED_IN() xTaskCallApplicationTaskHook( pxCurrentTCB, (void*)0 ) +/* USER CODE END Defines */ + +#endif /* __FREERTOS_CONFIG_H */ diff --git a/Appli/Core/Inc/RTE_Components.h b/Appli/Core/Inc/RTE_Components.h new file mode 100644 index 0000000..0b53b3a --- /dev/null +++ b/Appli/Core/Inc/RTE_Components.h @@ -0,0 +1,28 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file + * @author MCD Application Team + * @version V2.0.0 + ****************************************************************************** + * @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 __RTE_COMPONENTS_H__ +#define __RTE_COMPONENTS_H__ + +/* Defines ------------------------------------------------------------------*/ +/* STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1 */ +#define TOUCHGFX_APP + +#endif /* __RTE_COMPONENTS_H__ */ diff --git a/Appli/Core/Inc/jpeg_utils_conf.h b/Appli/Core/Inc/jpeg_utils_conf.h new file mode 100644 index 0000000..52ad456 --- /dev/null +++ b/Appli/Core/Inc/jpeg_utils_conf.h @@ -0,0 +1,62 @@ +/** + ****************************************************************************** + * @file jpeg_utils_conf.h + * @author MCD Application Team + * @brief jpeg_utils configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 __JPEG_UTILS_CONF_H__ +#define __JPEG_UTILS_CONF_H__ + +/* Includes ------------------------------------------------------------------*/ + +#include "stm32h7rsxx_hal.h" +#include "stm32h7rsxx_hal_jpeg.h" + +/* Private define ------------------------------------------------------------*/ +/** @addtogroup JPEG_Private_Defines + * @{ + */ +/* RGB Color format definition for JPEG encoding/Decoding : Should not be modified*/ +#define JPEG_ARGB8888 0 /* ARGB8888 Color Format */ +#define JPEG_RGB888 1 /* RGB888 Color Format */ +#define JPEG_RGB565 2 /* RGB565 Color Format */ + +/* + * Define USE_JPEG_DECODER + */ + +#define USE_JPEG_DECODER 1 /* 1 or 0 ********* Value different from default value : 1 ********** */ +/* + * Define USE_JPEG_ENCODER + */ + +#define USE_JPEG_ENCODER 0 /* 1 or 0 */ + +/* + * Define JPEG_RGB_FORMAT + */ +#define JPEG_RGB_FORMAT JPEG_ARGB8888 /* JPEG_ARGB8888, JPEG_RGB888, JPEG_RGB565 ********* Value different from default value : 0 ********** */ + +/* + * Define JPEG_SWAP_RB + */ +#define JPEG_SWAP_RB 0 /* 0 or 1 ********* Value different from default value : 0 ********** */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __JPEG_UTILS_CONF_H__ */ diff --git a/Appli/Core/Inc/main.h b/Appli/Core/Inc/main.h new file mode 100644 index 0000000..5908d05 --- /dev/null +++ b/Appli/Core/Inc/main.h @@ -0,0 +1,90 @@ +/* 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 "stm32h7rsxx_hal.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 FRAME_RATE_Pin GPIO_PIN_3 +#define FRAME_RATE_GPIO_Port GPIOF +#define RENDER_TIME_Pin GPIO_PIN_2 +#define RENDER_TIME_GPIO_Port GPIOF +#define ADF1_CK_Pin GPIO_PIN_2 +#define ADF1_CK_GPIO_Port GPIOE +#define MCU_ACTIVE_Pin GPIO_PIN_4 +#define MCU_ACTIVE_GPIO_Port GPIOF +#define VSYNC_FREQ_Pin GPIO_PIN_1 +#define VSYNC_FREQ_GPIO_Port GPIOF +#define LCD_EN_Pin GPIO_PIN_15 +#define LCD_EN_GPIO_Port GPIOE +#define ADF1_D_Pin GPIO_PIN_6 +#define ADF1_D_GPIO_Port GPIOD +#define TP_IRQ_Pin GPIO_PIN_3 +#define TP_IRQ_GPIO_Port GPIOE +#define TP_IRQ_EXTI_IRQn EXTI3_IRQn +#define LCD_BL_CTRL_Pin GPIO_PIN_15 +#define LCD_BL_CTRL_GPIO_Port GPIOG +#define MIC_DET_Pin GPIO_PIN_1 +#define MIC_DET_GPIO_Port GPIOH + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Appli/Core/Inc/stm32h7rsxx_hal_conf.h b/Appli/Core/Inc/stm32h7rsxx_hal_conf.h new file mode 100644 index 0000000..66aded6 --- /dev/null +++ b/Appli/Core/Inc/stm32h7rsxx_hal_conf.h @@ -0,0 +1,520 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32h7rsxx_hal_conf.h. + * + ****************************************************************************** + * @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 STM32H7RSxx_HAL_CONF_H +#define STM32H7RSxx_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_CORDIC_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DCMIPP_MODULE_ENABLED */ +#define HAL_DMA2D_MODULE_ENABLED +/* #define HAL_DTS_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_FDCAN_MODULE_ENABLED */ +/* #define HAL_GFXMMU_MODULE_ENABLED */ +/* #define HAL_GFXTIM_MODULE_ENABLED */ +#define HAL_GPU2D_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_JPEG_MODULE_ENABLED +/* #define HAL_LPTIM_MODULE_ENABLED */ +#define HAL_LTDC_MODULE_ENABLED +/* #define HAL_MCE_MODULE_ENABLED */ +#define HAL_MDF_MODULE_ENABLED +/* #define HAL_MMC_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_PKA_MODULE_ENABLED */ +/* #define HAL_PSSI_MODULE_ENABLED */ +/* #define HAL_RAMECC_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_SDIO_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_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 */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_EXTI_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 24000000UL /*!< 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 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 Low-power 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 (HSI48) value for USB OTG FS 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 OTG FS/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. + Value of the Internal Low Speed oscillator in Hz. + The real value may vary depending on the variations + in voltage and temperature.*/ +#endif /* LSI_VALUE */ + +/** +* @brief External Low Speed oscillator (LSE) value. +*/ +#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 digital audio interfaces: SPI/I2S, SAI and ADF + * This value is used by the RCC HAL module to provide the digital audio interfaces + * frequency. This clock source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 48000UL /*!< Value of the external clock source 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 (4UL)/*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U + +/* ########################## 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 stm32h7rsxx_hal_ppp.h file +* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef +* for each PPP peripheral). +*/ +#define USE_HAL_ADC_REGISTER_CALLBACKS 1U +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DCMIPP_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 1U +#define USE_HAL_I2S_REGISTER_CALLBACKS 1U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_MDF_REGISTER_CALLBACKS 1U +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U +#define USE_HAL_PSSI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 1U +#define USE_HAL_SD_REGISTER_CALLBACKS 0U +#define USE_HAL_SDIO_REGISTER_CALLBACKS 0U +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 1U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 1U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_XSPI_REGISTER_CALLBACKS 1U + +/* ################## 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 + +/* ################## CRYP peripheral configuration ########################## */ + +/** + * @brief For code optimization purpose, uncomment and set to "1U" the USE_HAL_CRYP_ONLY or USE_HAL_SAES_ONLY, + * to use only one peripheral. Both defines cannot be set to "1U" at the same time. + */ + +/* #define USE_HAL_CRYP_ONLY 1U */ +/* #define USE_HAL_SAES_ONLY 0U */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 0U + +/* ################## HASH peripheral configuration ########################## */ + +#define USE_HAL_HASH_SUSPEND_RESUME 0U + +/* ################## SDMMC peripheral configuration ######################### */ + +#define USE_SD_TRANSCEIVER 0U + +/* ################## SDIO peripheral configuration ######################### */ + +#define USE_SDIO_TRANSCEIVER 0U +#define SDIO_MAX_IO_NUMBER 7U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32h7rsxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32h7rsxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32h7rsxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32h7rsxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32h7rsxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32h7rsxx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED + #include "stm32h7rsxx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32h7rsxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32h7rsxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DCMIPP_MODULE_ENABLED + #include "stm32h7rsxx_hal_dcmipp.h" +#endif /* HAL_DCMIPP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32h7rsxx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DTS_MODULE_ENABLED + #include "stm32h7rsxx_hal_dts.h" +#endif /* HAL_DTS_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32h7rsxx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32h7rsxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED + #include "stm32h7rsxx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32h7rsxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GFXMMU_MODULE_ENABLED + #include "stm32h7rsxx_hal_gfxmmu.h" +#endif /* HAL_GFXMMU_MODULE_ENABLED */ + +#ifdef HAL_GFXTIM_MODULE_ENABLED + #include "stm32h7rsxx_hal_gfxtim.h" +#endif /* HAL_GFXTIM_MODULE_ENABLED */ + +#ifdef HAL_GPU2D_MODULE_ENABLED + #include "stm32h7rsxx_hal_gpu2d.h" +#endif /* HAL_GPU2D_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32h7rsxx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32h7rsxx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32h7rsxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32h7rsxx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_I3C_MODULE_ENABLED + #include "stm32h7rsxx_hal_i3c.h" +#endif /* HAL_I3C_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED + #include "stm32h7rsxx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32h7rsxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32h7rsxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32h7rsxx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32h7rsxx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32h7rsxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MCE_MODULE_ENABLED + #include "stm32h7rsxx_hal_mce.h" +#endif /* HAL_MCE_MODULE_ENABLED */ + +#ifdef HAL_MDF_MODULE_ENABLED + #include "stm32h7rsxx_hal_mdf.h" +#endif /* HAL_MDF_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32h7rsxx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32h7rsxx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32h7rsxx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32h7rsxx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32h7rsxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED + #include "stm32h7rsxx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32h7rsxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RAMECC_MODULE_ENABLED + #include "stm32h7rsxx_hal_ramecc.h" +#endif /* HAL_RAMECC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32h7rsxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32h7rsxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32h7rsxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32h7rsxx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SDIO_MODULE_ENABLED +#include "stm32h7rsxx_hal_sdio.h" +#endif /* HAL_SDIO_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32h7rsxx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32h7rsxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32h7rsxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32h7rsxx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32h7rsxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32h7rsxx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32h7rsxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32h7rsxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32h7rsxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32h7rsxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED + #include "stm32h7rsxx_hal_xspi.h" +#endif /* HAL_XSPI_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 /* STM32H7RSxx_HAL_CONF_H */ + diff --git a/Appli/Core/Inc/stm32h7rsxx_it.h b/Appli/Core/Inc/stm32h7rsxx_it.h new file mode 100644 index 0000000..d04a0df --- /dev/null +++ b/Appli/Core/Inc/stm32h7rsxx_it.h @@ -0,0 +1,75 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 __STM32H7RSxx_IT_H +#define __STM32H7RSxx_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 DebugMon_Handler(void); +void EXTI3_IRQHandler(void); +void GPDMA1_Channel0_IRQHandler(void); +void GPDMA1_Channel2_IRQHandler(void); +void TIM6_IRQHandler(void); +void HPDMA1_Channel0_IRQHandler(void); +void HPDMA1_Channel1_IRQHandler(void); +void LTDC_IRQHandler(void); +void DMA2D_IRQHandler(void); +void JPEG_IRQHandler(void); +void ADF1_FLT0_IRQHandler(void); +void GPU2D_IRQHandler(void); +void GPU2D_ER_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H7RSxx_IT_H */ diff --git a/Appli/Core/Inc/stm32h7s78_discovery_conf.h b/Appli/Core/Inc/stm32h7s78_discovery_conf.h new file mode 100644 index 0000000..300ef55 --- /dev/null +++ b/Appli/Core/Inc/stm32h7s78_discovery_conf.h @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_conf.h + * @author MCD Application Team + * @brief STM32H7S78-DK board 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7S78_DISCOVERY_CONF_H +#define STM32H7S78_DISCOVERY_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/* COM defines */ +#define USE_COM_LOG 0U +#define USE_BSP_COM_FEATURE 1U + +/* Touch Sensing controller defines */ +#define USE_FT5336_TS_CTRL 1U +/* TS supported features defines */ +#define USE_TS_GESTURE 1U +#define USE_TS_MULTI_TOUCH 1U +/* Default TS touch number */ +#define TS_TOUCH_NBR 2U + +/* LCD defines */ +#define LCD_LAYER_0_ADDRESS 0x90000000U +#define LCD_LAYER_1_ADDRESS 0x90200000U + +/* Default Audio IN internal buffer size */ +#define DEFAULT_AUDIO_IN_BUFFER_SIZE 2048U + +/* IRQ priorities (Default is 15 as lowest priority level) */ +#define BSP_SDRAM_IT_PRIORITY 15U +#define BSP_BUTTON_USER_IT_PRIORITY 15U +#define BSP_AUDIO_OUT_IT_PRIORITY 2U // testé à 1 (au-dessus du micro) sur plusieurs redémarrages : aucun effet -> la contention NVIC n'est pas en cause +#define BSP_AUDIO_IN_IT_PRIORITY 2U +#define BSP_SD_IT_PRIORITY 14U +#define BSP_SD_RX_IT_PRIORITY 14U +#define BSP_SD_TX_IT_PRIORITY 15U +#define BSP_TS_IT_PRIORITY 15U +#define BSP_XSPI_RAM_IT_PRIORITY 15U +#define BSP_XSPI_RAM_DMA_IT_PRIORITY 15U + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_CONF_H */ diff --git a/Appli/Core/Src/freertos.c b/Appli/Core/Src/freertos.c new file mode 100644 index 0000000..78adfad --- /dev/null +++ b/Appli/Core/Src/freertos.c @@ -0,0 +1,79 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : freertos.c + * Description : Code for freertos applications + ****************************************************************************** + * @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 "FreeRTOS.h" +#include "task.h" +#include "main.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 ---------------------------------------------------------*/ +/* USER CODE BEGIN Variables */ + +/* USER CODE END Variables */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN FunctionPrototypes */ +extern portBASE_TYPE IdleTaskHook(void* p); +/* USER CODE END FunctionPrototypes */ + +/* Hook prototypes */ +void vApplicationIdleHook(void); + +/* USER CODE BEGIN 2 */ +void vApplicationIdleHook( void ) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ + + vTaskSetApplicationTaskTag(NULL, IdleTaskHook); +} +/* USER CODE END 2 */ + +/* Private application code --------------------------------------------------*/ +/* USER CODE BEGIN Application */ + +/* USER CODE END Application */ + diff --git a/Appli/Core/Src/main.c b/Appli/Core/Src/main.c new file mode 100644 index 0000000..8cc26b4 --- /dev/null +++ b/Appli/Core/Src/main.c @@ -0,0 +1,1030 @@ +/* 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 "FreeRTOS.h" +#include "cmsis_os2.h" +#include "app_touchgfx.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "stm32h7s78_discovery_audio.h" +#include +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +#define AUDIO_SAMPLES 512 + +/* AXI SRAM, aligné 32 (cache H7S) */ + +int32_t adf_buf[AUDIO_SAMPLES] __attribute__((section("noncacheable_buffer"),aligned(32))); +MDF_DmaConfigTypeDef sDmaConfig; + +#define AUDIO_OUT_SAMPLES (AUDIO_SAMPLES * 2) // = 1024 int16_t, stéréo entrelacé +int16_t audio_out_buf[AUDIO_OUT_SAMPLES] __attribute__((section("noncacheable_buffer"),aligned(32))); + +#define FIFO_SIZE 2048 // en trames stéréo - doit rester une puissance de 2 +int16_t audio_fifo[FIFO_SIZE * 2] __attribute__((section("noncacheable_buffer"),aligned(32))); // stéréo entrelacé : FIFO_SIZE trames = FIFO_SIZE*2 int16_t (L+R) +/* Index monotones (jamais repliés) : write_idx n'est écrit que par push_to_fifo (IRQ ADF), + * read_idx que par pull_from_fifo (IRQ audio out) -> pas de race condition entre les deux IRQ. */ +volatile uint32_t fifo_write_idx = 0; +volatile uint32_t fifo_read_idx = 0; + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +MDF_HandleTypeDef AdfHandle0; +MDF_FilterConfigTypeDef AdfFilterConfig0; +DMA_NodeTypeDef Node_GPDMA1_Channel0 __attribute__((section("noncacheable_buffer"))); +DMA_QListTypeDef List_GPDMA1_Channel0; +DMA_HandleTypeDef handle_GPDMA1_Channel0; + +CRC_HandleTypeDef hcrc; + +DMA2D_HandleTypeDef hdma2d; + +GPU2D_HandleTypeDef hgpu2d; + +I2C_HandleTypeDef hi2c1; + +JPEG_HandleTypeDef hjpeg; +DMA_HandleTypeDef handle_HPDMA1_Channel1; +DMA_HandleTypeDef handle_HPDMA1_Channel0; + +LTDC_HandleTypeDef hltdc; + +/* Definitions for defaultTask */ +osThreadId_t defaultTaskHandle; +const osThreadAttr_t defaultTask_attributes = { + .name = "defaultTask", + .stack_size = 128 * 4, + .priority = (osPriority_t) osPriorityNormal, +}; +/* Definitions for TouchGFXTask */ +osThreadId_t TouchGFXTaskHandle; +const osThreadAttr_t TouchGFXTask_attributes = { + .name = "TouchGFXTask", + .stack_size = 4096 * 4, + .priority = (osPriority_t) osPriorityNormal, +}; +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +static void MPU_Config(void); +static void MX_GPIO_Init(void); +static void MX_HPDMA1_Init(void); +static void MX_GPDMA1_Init(void); +static void MX_LTDC_Init(void); +static void MX_CRC_Init(void); +static void MX_DMA2D_Init(void); +static void MX_JPEG_Init(void); +static void MX_FLASH_Init(void); +static void MX_I2C1_Init(void); +static void MX_GPU2D_Init(void); +static void MX_ICACHE_GPU2D_Init(void); +static void MX_ADF1_Init(void); +void StartDefaultTask(void *argument); +extern void TouchGFX_Task(void *argument); + +/* 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 */ + + /* MPU Configuration--------------------------------------------------------*/ + MPU_Config(); + + /* Enable the CPU Cache */ + + /* Enable I-Cache---------------------------------------------------------*/ + SCB_EnableICache(); + + /* Enable D-Cache---------------------------------------------------------*/ + SCB_EnableDCache(); + + /* MCU Configuration--------------------------------------------------------*/ + + /* Update SystemCoreClock variable according to RCC registers values. */ + SystemCoreClockUpdate(); + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_HPDMA1_Init(); + MX_GPDMA1_Init(); + MX_LTDC_Init(); + MX_CRC_Init(); + MX_DMA2D_Init(); + MX_JPEG_Init(); + MX_FLASH_Init(); + MX_I2C1_Init(); + MX_GPU2D_Init(); + MX_ICACHE_GPU2D_Init(); + MX_ADF1_Init(); + MX_TouchGFX_Init(); + /* Call PreOsInit function */ + MX_TouchGFX_PreOSInit(); + /* USER CODE BEGIN 2 */ + + + /* FIFO initialisée à moitié pleine de silence avant de démarrer les DMA */ + memset(audio_fifo, 0, sizeof(audio_fifo)); + fifo_write_idx = FIFO_SIZE / 2; + fifo_read_idx = 0; + + sDmaConfig.Address = (uint32_t)adf_buf; + sDmaConfig.DataLength = AUDIO_SAMPLES * sizeof(int32_t); /* OCTETS */ + sDmaConfig.MsbOnly = DISABLE; /* 32-bit/sample ; ENABLE si buffer int16 */ + + if (HAL_MDF_AcqStart_DMA(&AdfHandle0, &AdfFilterConfig0, &sDmaConfig) != HAL_OK) + { + Error_Handler(); + } + + BSP_AUDIO_Init_t audioOutInit = { + .Device = AUDIO_OUT_HEADPHONE, + .SampleRate = AUDIO_FREQUENCY_48K, + .BitsPerSample = AUDIO_RESOLUTION_16B, + .ChannelsNbr = 2, + .Volume = 70 + }; + + if (BSP_AUDIO_OUT_Init(0, &audioOutInit) != BSP_ERROR_NONE) + { + Error_Handler(); + } + if (BSP_AUDIO_OUT_Play(0, (uint8_t *)audio_out_buf, AUDIO_OUT_SAMPLES * sizeof(int16_t)) != BSP_ERROR_NONE) + { + Error_Handler(); + } + + + /* USER CODE END 2 */ + + /* Init scheduler */ + osKernelInitialize(); + + /* USER CODE BEGIN RTOS_MUTEX */ + /* add mutexes, ... */ + /* USER CODE END RTOS_MUTEX */ + + /* USER CODE BEGIN RTOS_SEMAPHORES */ + /* add semaphores, ... */ + /* USER CODE END RTOS_SEMAPHORES */ + + /* USER CODE BEGIN RTOS_TIMERS */ + /* start timers, add new ones, ... */ + /* USER CODE END RTOS_TIMERS */ + + /* USER CODE BEGIN RTOS_QUEUES */ + /* add queues, ... */ + /* USER CODE END RTOS_QUEUES */ + + /* Create the thread(s) */ + /* creation of defaultTask */ + defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes); + + /* creation of TouchGFXTask */ + TouchGFXTaskHandle = osThreadNew(TouchGFX_Task, NULL, &TouchGFXTask_attributes); + + /* USER CODE BEGIN RTOS_THREADS */ + /* add threads, ... */ + /* USER CODE END RTOS_THREADS */ + + /* USER CODE BEGIN RTOS_EVENTS */ + /* add events, ... */ + /* USER CODE END RTOS_EVENTS */ + + /* Start scheduler */ + osKernelStart(); + + /* We should never get here as control is now taken by the scheduler */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + } + /* USER CODE END 3 */ +} + +/** + * @brief ADF1 Initialization Function + * @param None + * @retval None + */ +static void MX_ADF1_Init(void) +{ + + /* USER CODE BEGIN ADF1_Init 0 */ + + /* USER CODE END ADF1_Init 0 */ + + /* USER CODE BEGIN ADF1_Init 1 */ + + /* USER CODE END ADF1_Init 1 */ + + /** + AdfHandle0 structure initialization and HAL_MDF_Init function call + */ + AdfHandle0.Instance = ADF1_Filter0; + AdfHandle0.Init.CommonParam.ProcClockDivider = 2; + AdfHandle0.Init.CommonParam.OutputClock.Activation = ENABLE; + AdfHandle0.Init.CommonParam.OutputClock.Pins = MDF_OUTPUT_CLOCK_0; + AdfHandle0.Init.CommonParam.OutputClock.Divider = 4; + AdfHandle0.Init.CommonParam.OutputClock.Trigger.Activation = DISABLE; + AdfHandle0.Init.SerialInterface.Activation = ENABLE; + AdfHandle0.Init.SerialInterface.Mode = MDF_SITF_NORMAL_SPI_MODE; + AdfHandle0.Init.SerialInterface.ClockSource = MDF_SITF_CCK0_SOURCE; + AdfHandle0.Init.SerialInterface.Threshold = 31; + AdfHandle0.Init.FilterBistream = MDF_BITSTREAM0_FALLING; + if (HAL_MDF_Init(&AdfHandle0) != HAL_OK) + { + Error_Handler(); + } + + /** + AdfFilterConfig0 structure initialization + + WARNING : only structure is filled, no specific init function call for filter + */ + AdfFilterConfig0.DataSource = MDF_DATA_SOURCE_BSMX; + AdfFilterConfig0.Delay = 0; + AdfFilterConfig0.CicMode = MDF_ONE_FILTER_SINC4; + AdfFilterConfig0.DecimationRatio = 16; + AdfFilterConfig0.Gain = 10; + AdfFilterConfig0.ReshapeFilter.Activation = ENABLE; + AdfFilterConfig0.ReshapeFilter.DecimationRatio = MDF_RSF_DECIMATION_RATIO_4; + AdfFilterConfig0.HighPassFilter.Activation = ENABLE; + AdfFilterConfig0.HighPassFilter.CutOffFrequency = MDF_HPF_CUTOFF_0_000625FPCM; + AdfFilterConfig0.SoundActivity.Activation = DISABLE; + AdfFilterConfig0.AcquisitionMode = MDF_MODE_ASYNC_CONT; + AdfFilterConfig0.FifoThreshold = MDF_FIFO_THRESHOLD_NOT_EMPTY; + AdfFilterConfig0.DiscardSamples = 0; + /* USER CODE BEGIN ADF1_Init 2 */ + + /* USER CODE END ADF1_Init 2 */ + +} + +/** + * @brief CRC Initialization Function + * @param None + * @retval None + */ +static void MX_CRC_Init(void) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + if (HAL_CRC_Init(&hcrc) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ + +} + +/** + * @brief DMA2D Initialization Function + * @param None + * @retval None + */ +static void MX_DMA2D_Init(void) +{ + + /* USER CODE BEGIN DMA2D_Init 0 */ + + /* USER CODE END DMA2D_Init 0 */ + + /* USER CODE BEGIN DMA2D_Init 1 */ + + /* USER CODE END DMA2D_Init 1 */ + hdma2d.Instance = DMA2D; + hdma2d.Init.Mode = DMA2D_R2M; + hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB888; + hdma2d.Init.OutputOffset = 0; + if (HAL_DMA2D_Init(&hdma2d) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN DMA2D_Init 2 */ + + /* USER CODE END DMA2D_Init 2 */ + +} + +/** + * @brief FLASH Initialization Function + * @param None + * @retval None + */ +static void MX_FLASH_Init(void) +{ + + /* USER CODE BEGIN FLASH_Init 0 */ + + /* USER CODE END FLASH_Init 0 */ + + FLASH_OBProgramInitTypeDef pOBInit = {0}; + + /* USER CODE BEGIN FLASH_Init 1 */ + + /* USER CODE END FLASH_Init 1 */ + HAL_FLASHEx_OBGetConfig(&pOBInit); + if ((pOBInit.USERConfig1 & OB_IWDG_SW) != OB_IWDG_SW|| +(pOBInit.USERConfig1 & OB_XSPI1_HSLV_ENABLE) != OB_XSPI1_HSLV_ENABLE|| +(pOBInit.USERConfig1 & OB_XSPI2_HSLV_ENABLE) != OB_XSPI2_HSLV_ENABLE|| +(pOBInit.USERConfig2 & OB_I2C_NI3C_I2C) != OB_I2C_NI3C_I2C) + { + if (HAL_FLASH_Unlock() != HAL_OK) + { + Error_Handler(); + } + if (HAL_FLASH_OB_Unlock() != HAL_OK) + { + Error_Handler(); + } + pOBInit.OptionType = OPTIONBYTE_USER; + pOBInit.USERType = OB_USER_IWDG_SW|OB_USER_XSPI1_HSLV + |OB_USER_XSPI2_HSLV|OB_USER_I2C_NI3C; + pOBInit.USERConfig1 = OB_IWDG_SW|OB_XSPI1_HSLV_ENABLE + |OB_XSPI2_HSLV_ENABLE; + pOBInit.USERConfig2 = OB_I2C_NI3C_I2C; + if (HAL_FLASHEx_OBProgram(&pOBInit) != HAL_OK) + { + Error_Handler(); + } + if (HAL_FLASH_OB_Lock() != HAL_OK) + { + Error_Handler(); + } + if (HAL_FLASH_Lock() != HAL_OK) + { + Error_Handler(); + } + } + /* USER CODE BEGIN FLASH_Init 2 */ + + /* USER CODE END FLASH_Init 2 */ + +} + +/** + * @brief GPDMA1 Initialization Function + * @param None + * @retval None + */ +static void MX_GPDMA1_Init(void) +{ + + /* USER CODE BEGIN GPDMA1_Init 0 */ + + /* USER CODE END GPDMA1_Init 0 */ + + /* Peripheral clock enable */ + __HAL_RCC_GPDMA1_CLK_ENABLE(); + + /* GPDMA1 interrupt Init */ + HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 2, 0); + HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn); + + /* USER CODE BEGIN GPDMA1_Init 1 */ + + /* USER CODE END GPDMA1_Init 1 */ + /* USER CODE BEGIN GPDMA1_Init 2 */ + + /* USER CODE END GPDMA1_Init 2 */ + +} + +/** + * @brief GPU2D Initialization Function + * @param None + * @retval None + */ +static void MX_GPU2D_Init(void) +{ + + /* USER CODE BEGIN GPU2D_Init 0 */ + + /* USER CODE END GPU2D_Init 0 */ + + /* USER CODE BEGIN GPU2D_Init 1 */ + + /* USER CODE END GPU2D_Init 1 */ + hgpu2d.Instance = GPU2D; + if (HAL_GPU2D_Init(&hgpu2d) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN GPU2D_Init 2 */ + + /* USER CODE END GPU2D_Init 2 */ + +} + +/** + * @brief HPDMA1 Initialization Function + * @param None + * @retval None + */ +static void MX_HPDMA1_Init(void) +{ + + /* USER CODE BEGIN HPDMA1_Init 0 */ + + /* USER CODE END HPDMA1_Init 0 */ + + /* Peripheral clock enable */ + __HAL_RCC_HPDMA1_CLK_ENABLE(); + + /* HPDMA1 interrupt Init */ + HAL_NVIC_SetPriority(HPDMA1_Channel0_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(HPDMA1_Channel0_IRQn); + HAL_NVIC_SetPriority(HPDMA1_Channel1_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(HPDMA1_Channel1_IRQn); + + /* USER CODE BEGIN HPDMA1_Init 1 */ + + /* USER CODE END HPDMA1_Init 1 */ + /* USER CODE BEGIN HPDMA1_Init 2 */ + + /* USER CODE END HPDMA1_Init 2 */ + +} + +/** + * @brief I2C1 Initialization Function + * @param None + * @retval None + */ +static void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + hi2c1.Instance = I2C1; + hi2c1.Init.Timing = 0x00E063FF; + hi2c1.Init.OwnAddress1 = 0; + hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c1.Init.OwnAddress2 = 0; + hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; + hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Analogue filter + */ + if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Digital filter + */ + if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ + +} + +/** + * @brief ICACHE_GPU2D Initialization Function + * @param None + * @retval None + */ +static void MX_ICACHE_GPU2D_Init(void) +{ + + /* USER CODE BEGIN ICACHE_GPU2D_Init 0 */ + + /* USER CODE END ICACHE_GPU2D_Init 0 */ + + /* USER CODE BEGIN ICACHE_GPU2D_Init 1 */ + + /* USER CODE END ICACHE_GPU2D_Init 1 */ + + /** Enable instruction cache (default 2-ways set associative cache) + */ + if (HAL_ICACHE_Enable() != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ICACHE_GPU2D_Init 2 */ + + /* USER CODE END ICACHE_GPU2D_Init 2 */ + +} + +/** + * @brief JPEG Initialization Function + * @param None + * @retval None + */ +static void MX_JPEG_Init(void) +{ + + /* USER CODE BEGIN JPEG_Init 0 */ + + /* USER CODE END JPEG_Init 0 */ + + /* USER CODE BEGIN JPEG_Init 1 */ + + /* USER CODE END JPEG_Init 1 */ + hjpeg.Instance = JPEG; + if (HAL_JPEG_Init(&hjpeg) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN JPEG_Init 2 */ + + /* USER CODE END JPEG_Init 2 */ + +} + +/** + * @brief LTDC Initialization Function + * @param None + * @retval None + */ +static void MX_LTDC_Init(void) +{ + + /* USER CODE BEGIN LTDC_Init 0 */ + + /* USER CODE END LTDC_Init 0 */ + + LTDC_LayerCfgTypeDef pLayerCfg = {0}; + + /* USER CODE BEGIN LTDC_Init 1 */ + + /* USER CODE END LTDC_Init 1 */ + hltdc.Instance = LTDC; + hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL; + hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL; + hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL; + hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC; + hltdc.Init.HorizontalSync = 4; + hltdc.Init.VerticalSync = 4; + hltdc.Init.AccumulatedHBP = 12; + hltdc.Init.AccumulatedVBP = 12; + hltdc.Init.AccumulatedActiveW = 812; + hltdc.Init.AccumulatedActiveH = 492; + hltdc.Init.TotalWidth = 820; + hltdc.Init.TotalHeigh = 506; + hltdc.Init.Backcolor.Blue = 0; + hltdc.Init.Backcolor.Green = 0; + hltdc.Init.Backcolor.Red = 0; + if (HAL_LTDC_Init(&hltdc) != HAL_OK) + { + Error_Handler(); + } + pLayerCfg.WindowX0 = 0; + pLayerCfg.WindowX1 = 800; + pLayerCfg.WindowY0 = 0; + pLayerCfg.WindowY1 = 480; + pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; + pLayerCfg.Alpha = 255; + pLayerCfg.Alpha0 = 0; + pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA; + pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA; + pLayerCfg.FBStartAdress = 0; + pLayerCfg.ImageWidth = 800; + pLayerCfg.ImageHeight = 480; + pLayerCfg.Backcolor.Blue = 0; + pLayerCfg.Backcolor.Green = 0; + pLayerCfg.Backcolor.Red = 0; + if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN LTDC_Init 2 */ + + /* USER CODE END LTDC_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_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOF, FRAME_RATE_Pin|RENDER_TIME_Pin|MCU_ACTIVE_Pin|VSYNC_FREQ_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LCD_EN_GPIO_Port, LCD_EN_Pin, GPIO_PIN_SET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_SET); + + /*Configure GPIO pins : FRAME_RATE_Pin RENDER_TIME_Pin VSYNC_FREQ_Pin */ + GPIO_InitStruct.Pin = FRAME_RATE_Pin|RENDER_TIME_Pin|VSYNC_FREQ_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + /*Configure GPIO pin : MCU_ACTIVE_Pin */ + GPIO_InitStruct.Pin = MCU_ACTIVE_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(MCU_ACTIVE_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LCD_EN_Pin */ + GPIO_InitStruct.Pin = LCD_EN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LCD_EN_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : TP_IRQ_Pin */ + GPIO_InitStruct.Pin = TP_IRQ_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(TP_IRQ_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LCD_BL_CTRL_Pin */ + GPIO_InitStruct.Pin = LCD_BL_CTRL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LCD_BL_CTRL_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : MIC_DET_Pin */ + GPIO_InitStruct.Pin = MIC_DET_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + HAL_GPIO_Init(MIC_DET_GPIO_Port, &GPIO_InitStruct); + + /* EXTI interrupt init*/ + HAL_NVIC_SetPriority(TP_IRQ_EXTI_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(TP_IRQ_EXTI_IRQn); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + + /* USER CODE END MX_GPIO_Init_2 */ +} + +/* USER CODE BEGIN 4 */ + +static inline int16_t adf_sample_to_pcm16(int32_t raw) +{ + int32_t v = raw >> 8; // 24 bits -> 16 bits (comme le fait le BSP) + if (v > 32767) v = 32767; + if (v < -32768) v = -32768; + return (int16_t)v; +} + +static void push_to_fifo(int32_t raw) +{ + if ((fifo_write_idx - fifo_read_idx) >= FIFO_SIZE) + { + return; // FIFO pleine : on jette l'échantillon plutôt que d'écraser du non-lu + } + int16_t s = adf_sample_to_pcm16(raw); + uint32_t idx = fifo_write_idx & (FIFO_SIZE - 1); + audio_fifo[idx * 2] = s; + audio_fifo[idx * 2 + 1] = s; + fifo_write_idx++; +} + +static void pull_from_fifo(int16_t *dst, uint32_t nbFrames) +{ + for (uint32_t i = 0; i < nbFrames; i++) + { + if (fifo_write_idx == fifo_read_idx) + { + uint32_t last = (fifo_read_idx - 1) & (FIFO_SIZE - 1); + dst[2*i] = audio_fifo[last * 2]; + dst[2*i + 1] = audio_fifo[last * 2 + 1]; + } + else + { + uint32_t idx = fifo_read_idx & (FIFO_SIZE - 1); + dst[2*i] = audio_fifo[idx * 2]; + dst[2*i + 1] = audio_fifo[idx * 2 + 1]; + fifo_read_idx++; + } + } +} + +void HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf) +{ + (void)hmdf; + for (int i = 0; i < AUDIO_SAMPLES/2; i++) + { + push_to_fifo(adf_buf[i]); + } +} + +void HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf) +{ + (void)hmdf; + for (int i = AUDIO_SAMPLES/2; i < AUDIO_SAMPLES; i++) + { + push_to_fifo(adf_buf[i]); + } +} + +void BSP_AUDIO_OUT_HalfTransfer_CallBack(uint32_t Instance) +{ + pull_from_fifo(&audio_out_buf[0], AUDIO_OUT_SAMPLES/2 / 2); // /2 car stéréo +} + +void BSP_AUDIO_OUT_TransferComplete_CallBack(uint32_t Instance) +{ + pull_from_fifo(&audio_out_buf[AUDIO_OUT_SAMPLES/2], AUDIO_OUT_SAMPLES/2 / 2); +} + +HAL_StatusTypeDef MX_I2S6_ClockConfig(I2S_HandleTypeDef *hi2s, uint32_t SampleRate) +{ + UNUSED(hi2s); + UNUSED(SampleRate); + + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + /* PLL2Q est déjà actif (614.4 MHz VCO / 13 = 47.26 MHz) via SystemClock_Config(). + On se contente de router SPI6 dessus, sans reconfigurer aucun PLL. */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6; + PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PLL2Q; + + return HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); +} +/* USER CODE END 4 */ + +/* USER CODE BEGIN Header_StartDefaultTask */ +/** + * @brief Function implementing the defaultTask thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_StartDefaultTask */ +void StartDefaultTask(void *argument) +{ + /* USER CODE BEGIN 5 */ + /* Infinite loop */ + for (;;) + { + osDelay(1); + } + /* USER CODE END 5 */ +} + + /* MPU Configuration */ + +static void MPU_Config(void) +{ + MPU_Region_InitTypeDef MPU_InitStruct = {0}; + + /* Disables the MPU */ + HAL_MPU_Disable(); + + /* Disables all MPU regions */ + for(uint8_t i=0; i<__MPU_REGIONCOUNT; i++) + { + HAL_MPU_DisableRegion(i); + } + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = MPU_REGION_NUMBER0; + MPU_InitStruct.BaseAddress = 0x0; + MPU_InitStruct.Size = MPU_REGION_SIZE_4GB; + MPU_InitStruct.SubRegionDisable = 0x87; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER1; + MPU_InitStruct.BaseAddress = 0x70000000; + MPU_InitStruct.Size = MPU_REGION_SIZE_128MB; + MPU_InitStruct.SubRegionDisable = 0x0; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; + MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER2; + MPU_InitStruct.Size = MPU_REGION_SIZE_2MB; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER3; + MPU_InitStruct.BaseAddress = 0x90000000; + MPU_InitStruct.Size = MPU_REGION_SIZE_32MB; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER4; + MPU_InitStruct.BaseAddress = 0x20000000; + MPU_InitStruct.Size = MPU_REGION_SIZE_64KB; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER5; + MPU_InitStruct.BaseAddress = 0x24000000; + MPU_InitStruct.Size = MPU_REGION_SIZE_512KB; + MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER6; + MPU_InitStruct.BaseAddress = 0x24060000; + MPU_InitStruct.Size = MPU_REGION_SIZE_64KB; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; + MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + + /** Initializes and configures the Region and the memory to be protected + */ + MPU_InitStruct.Number = MPU_REGION_NUMBER7; + MPU_InitStruct.BaseAddress = 0x24070000; + MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + /* Enables the MPU */ + HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); + +} + +/** + * @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 + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM6) { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @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/Appli/Core/Src/stm32h7rsxx_hal_msp.c b/Appli/Core/Src/stm32h7rsxx_hal_msp.c new file mode 100644 index 0000000..b342908 --- /dev/null +++ b/Appli/Core/Src/stm32h7rsxx_hal_msp.c @@ -0,0 +1,803 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 */ + +/* USER CODE END Includes */ +extern DMA_NodeTypeDef Node_GPDMA1_Channel0; + +extern DMA_QListTypeDef List_GPDMA1_Channel0; + +extern DMA_HandleTypeDef handle_GPDMA1_Channel0; + +extern DMA_HandleTypeDef handle_HPDMA1_Channel1; + +extern DMA_HandleTypeDef handle_HPDMA1_Channel0; + +/* 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*/ + /* PendSV_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** + * @brief MDF MSP Initialization + * This function configures the hardware resources used in this example + * @param hmdf: MDF handle pointer + * @retval None + */ +void HAL_MDF_MspInit(MDF_HandleTypeDef* hmdf) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + DMA_NodeConfTypeDef NodeConfig; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(IS_MDF_ALL_INSTANCE(hmdf->Instance)) + { + /* USER CODE BEGIN ADF1_MspInit 0 */ + + /* USER CODE END ADF1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADF1; + PeriphClkInit.Adf1ClockSelection = RCC_ADF1CLKSOURCE_PLL2P; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_ADF1_CLK_ENABLE(); + + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + /**ADF1 GPIO Configuration + PE2 ------> ADF1_CCK0 + PD6 ------> ADF1_SDI0 + */ + GPIO_InitStruct.Pin = ADF1_CK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // était LOW : bien trop lent pour piloter proprement une horloge à 6-12MHz+ vers le micro PDM + GPIO_InitStruct.Alternate = GPIO_AF1_ADF1; + HAL_GPIO_Init(ADF1_CK_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = ADF1_D_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF3_ADF1; + HAL_GPIO_Init(ADF1_D_GPIO_Port, &GPIO_InitStruct); + + /* ADF1 DMA Init */ + /* GPDMA1_REQUEST_ADF1_FLT0 Init */ + NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE; + NodeConfig.Init.Request = GPDMA1_REQUEST_ADF1_FLT0; + NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY; + NodeConfig.Init.SrcInc = DMA_SINC_FIXED; + NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED; + NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + NodeConfig.Init.SrcBurstLength = 1; + NodeConfig.Init.DestBurstLength = 1; + NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1; + NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + NodeConfig.Init.Mode = DMA_NORMAL; + NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED; + NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel0) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel0, NULL, &Node_GPDMA1_Channel0) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel0) != HAL_OK) + { + Error_Handler(); + } + + handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0; + handle_GPDMA1_Channel0.InitLinkedList.Priority = DMA_HIGH_PRIORITY; + handle_GPDMA1_Channel0.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION; + handle_GPDMA1_Channel0.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1; + handle_GPDMA1_Channel0.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + handle_GPDMA1_Channel0.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR; + if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel0) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &List_GPDMA1_Channel0) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hmdf, hdma, handle_GPDMA1_Channel0); + + if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK) + { + Error_Handler(); + } + + /* ADF1 interrupt Init */ + HAL_NVIC_SetPriority(ADF1_FLT0_IRQn, 2, 0); + HAL_NVIC_EnableIRQ(ADF1_FLT0_IRQn); + /* USER CODE BEGIN ADF1_MspInit 1 */ + + /* USER CODE END ADF1_MspInit 1 */ + + } + +} + +/** + * @brief MDF MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hmdf: MDF handle pointer + * @retval None + */ +void HAL_MDF_MspDeInit(MDF_HandleTypeDef* hmdf) +{ + if(IS_MDF_ALL_INSTANCE(hmdf->Instance)) + { + /* USER CODE BEGIN ADF1_MspDeInit 0 */ + + /* USER CODE END ADF1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADF1_CLK_DISABLE(); + + /**ADF1 GPIO Configuration + PE2 ------> ADF1_CCK0 + PD6 ------> ADF1_SDI0 + */ + HAL_GPIO_DeInit(ADF1_CK_GPIO_Port, ADF1_CK_Pin); + + HAL_GPIO_DeInit(ADF1_D_GPIO_Port, ADF1_D_Pin); + + /* ADF1 DMA DeInit */ + HAL_DMA_DeInit(hmdf->hdma); + + /* ADF1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(ADF1_FLT0_IRQn); + /* USER CODE BEGIN ADF1_MspDeInit 1 */ + + /* USER CODE END ADF1_MspDeInit 1 */ + } + +} + +/** + * @brief CRC MSP Initialization + * This function configures the hardware resources used in this example + * @param hcrc: CRC handle pointer + * @retval None + */ +void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc) +{ + if(hcrc->Instance==CRC) + { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + + } + +} + +/** + * @brief CRC MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hcrc: CRC handle pointer + * @retval None + */ +void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc) +{ + if(hcrc->Instance==CRC) + { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } + +} + +/** + * @brief DMA2D MSP Initialization + * This function configures the hardware resources used in this example + * @param hdma2d: DMA2D handle pointer + * @retval None + */ +void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d) +{ + if(hdma2d->Instance==DMA2D) + { + /* USER CODE BEGIN DMA2D_MspInit 0 */ + + /* USER CODE END DMA2D_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_DMA2D_CLK_ENABLE(); + /* DMA2D interrupt Init */ + HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 0); + /* USER CODE BEGIN DMA2D_MspInit 1 */ + + /* USER CODE END DMA2D_MspInit 1 */ + + } + +} + +/** + * @brief DMA2D MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hdma2d: DMA2D handle pointer + * @retval None + */ +void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef* hdma2d) +{ + if(hdma2d->Instance==DMA2D) + { + /* USER CODE BEGIN DMA2D_MspDeInit 0 */ + + /* USER CODE END DMA2D_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_DMA2D_CLK_DISABLE(); + + /* DMA2D interrupt DeInit */ + HAL_NVIC_DisableIRQ(DMA2D_IRQn); + /* USER CODE BEGIN DMA2D_MspDeInit 1 */ + + /* USER CODE END DMA2D_MspDeInit 1 */ + } + +} + +/** + * @brief GPU2D MSP Initialization + * This function configures the hardware resources used in this example + * @param hgpu2d: GPU2D handle pointer + * @retval None + */ +void HAL_GPU2D_MspInit(GPU2D_HandleTypeDef* hgpu2d) +{ + if(hgpu2d->Instance==GPU2D) + { + /* USER CODE BEGIN GPU2D_MspInit 0 */ + + /* USER CODE END GPU2D_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_GPU2D_CLK_ENABLE(); + /* GPU2D interrupt Init */ + HAL_NVIC_SetPriority(GPU2D_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(GPU2D_IRQn); + HAL_NVIC_SetPriority(GPU2D_ER_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(GPU2D_ER_IRQn); + /* USER CODE BEGIN GPU2D_MspInit 1 */ + + /* USER CODE END GPU2D_MspInit 1 */ + + } + +} + +/** + * @brief GPU2D MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hgpu2d: GPU2D handle pointer + * @retval None + */ +void HAL_GPU2D_MspDeInit(GPU2D_HandleTypeDef* hgpu2d) +{ + if(hgpu2d->Instance==GPU2D) + { + /* USER CODE BEGIN GPU2D_MspDeInit 0 */ + + /* USER CODE END GPU2D_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_GPU2D_CLK_DISABLE(); + + /* GPU2D interrupt DeInit */ + HAL_NVIC_DisableIRQ(GPU2D_IRQn); + HAL_NVIC_DisableIRQ(GPU2D_ER_IRQn); + /* USER CODE BEGIN GPU2D_MspDeInit 1 */ + + /* USER CODE END GPU2D_MspDeInit 1 */ + } + +} + +/** + * @brief I2C MSP Initialization + * This function configures the hardware resources used in this example + * @param hi2c: I2C handle pointer + * @retval None + */ +void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1_I3C1; + PeriphClkInit.I2c1_I3c1ClockSelection = RCC_I2C1_I3C1CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB9 ------> I2C1_SDA + PB6 ------> I2C1_SCL + */ + GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + + } + +} + +/** + * @brief I2C MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hi2c: I2C handle pointer + * @retval None + */ +void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) +{ + if(hi2c->Instance==I2C1) + { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB9 ------> I2C1_SDA + PB6 ------> I2C1_SCL + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } + +} + +/** + * @brief JPEG MSP Initialization + * This function configures the hardware resources used in this example + * @param hjpeg: JPEG handle pointer + * @retval None + */ +void HAL_JPEG_MspInit(JPEG_HandleTypeDef* hjpeg) +{ + DMA_DataHandlingConfTypeDef DataHandlingConfig; + if(hjpeg->Instance==JPEG) + { + /* USER CODE BEGIN JPEG_MspInit 0 */ + + /* USER CODE END JPEG_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_JPEG_CLK_ENABLE(); + + /* JPEG DMA Init */ + /* HPDMA1_REQUEST_JPEG_TX Init */ + handle_HPDMA1_Channel1.Instance = HPDMA1_Channel1; + handle_HPDMA1_Channel1.Init.Request = HPDMA1_REQUEST_JPEG_TX; + handle_HPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + handle_HPDMA1_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY; + handle_HPDMA1_Channel1.Init.SrcInc = DMA_SINC_FIXED; + handle_HPDMA1_Channel1.Init.DestInc = DMA_DINC_INCREMENTED; + handle_HPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + handle_HPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + handle_HPDMA1_Channel1.Init.Priority = DMA_HIGH_PRIORITY; + handle_HPDMA1_Channel1.Init.SrcBurstLength = 8; + handle_HPDMA1_Channel1.Init.DestBurstLength = 8; + handle_HPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1|DMA_DEST_ALLOCATED_PORT0; + handle_HPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + handle_HPDMA1_Channel1.Init.Mode = DMA_NORMAL; + if (HAL_DMA_Init(&handle_HPDMA1_Channel1) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hjpeg, hdmaout, handle_HPDMA1_Channel1); + + if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK) + { + Error_Handler(); + } + + /* HPDMA1_REQUEST_JPEG_RX Init */ + handle_HPDMA1_Channel0.Instance = HPDMA1_Channel0; + handle_HPDMA1_Channel0.Init.Request = HPDMA1_REQUEST_JPEG_RX; + handle_HPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + handle_HPDMA1_Channel0.Init.Direction = DMA_MEMORY_TO_PERIPH; + handle_HPDMA1_Channel0.Init.SrcInc = DMA_SINC_INCREMENTED; + handle_HPDMA1_Channel0.Init.DestInc = DMA_DINC_FIXED; + handle_HPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE; + handle_HPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + handle_HPDMA1_Channel0.Init.Priority = DMA_HIGH_PRIORITY; + handle_HPDMA1_Channel0.Init.SrcBurstLength = 8; + handle_HPDMA1_Channel0.Init.DestBurstLength = 8; + handle_HPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1; + handle_HPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + handle_HPDMA1_Channel0.Init.Mode = DMA_NORMAL; + if (HAL_DMA_Init(&handle_HPDMA1_Channel0) != HAL_OK) + { + Error_Handler(); + } + + DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + DataHandlingConfig.DataAlignment = DMA_DATA_PACK; + if (HAL_DMAEx_ConfigDataHandling(&handle_HPDMA1_Channel0, &DataHandlingConfig) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(hjpeg, hdmain, handle_HPDMA1_Channel0); + + if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK) + { + Error_Handler(); + } + + /* JPEG interrupt Init */ + HAL_NVIC_SetPriority(JPEG_IRQn, 8, 0); + HAL_NVIC_EnableIRQ(JPEG_IRQn); + /* USER CODE BEGIN JPEG_MspInit 1 */ + + /* USER CODE END JPEG_MspInit 1 */ + + } + +} + +/** + * @brief JPEG MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hjpeg: JPEG handle pointer + * @retval None + */ +void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef* hjpeg) +{ + if(hjpeg->Instance==JPEG) + { + /* USER CODE BEGIN JPEG_MspDeInit 0 */ + + /* USER CODE END JPEG_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_JPEG_CLK_DISABLE(); + + /* JPEG DMA DeInit */ + HAL_DMA_DeInit(hjpeg->hdmaout); + HAL_DMA_DeInit(hjpeg->hdmain); + + /* JPEG interrupt DeInit */ + HAL_NVIC_DisableIRQ(JPEG_IRQn); + /* USER CODE BEGIN JPEG_MspDeInit 1 */ + + /* USER CODE END JPEG_MspDeInit 1 */ + } + +} + +/** + * @brief LTDC MSP Initialization + * This function configures the hardware resources used in this example + * @param hltdc: LTDC handle pointer + * @retval None + */ +void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(hltdc->Instance==LTDC) + { + /* USER CODE BEGIN LTDC_MspInit 0 */ + + /* USER CODE END LTDC_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC; + PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_LTDC_CLK_ENABLE(); + + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**LTDC GPIO Configuration + PF0 ------> LTDC_R2 + PG0 ------> LTDC_R7 + PB3(JTDO/TRACESWO) ------> LTDC_R4 + PG2 ------> LTDC_HSYNC + PE11 ------> LTDC_VSYNC + PA12 ------> LTDC_B2 + PA11 ------> LTDC_B3 + PB4(NJTRST) ------> LTDC_R3 + PA9 ------> LTDC_B5 + PG1 ------> LTDC_R6 + PA10 ------> LTDC_B4 + PG14 ------> LTDC_B1 + PA8 ------> LTDC_B6 + PG13 ------> LTDC_CLK + PA15(JTDI) ------> LTDC_R5 + PF7 ------> LTDC_G0 + PF9 ------> LTDC_R0 + PF10 ------> LTDC_R1 + PB12 ------> LTDC_G5 + PA0 ------> LTDC_G3 + PA1 ------> LTDC_G2 + PF11 ------> LTDC_B0 + PB14 ------> LTDC_DE + PB15 ------> LTDC_G7 + PF15 ------> LTDC_G1 + PB11 ------> LTDC_G6 + PB13 ------> LTDC_G4 + PA6 ------> LTDC_B7 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF11_LTDC; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_14 + |GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14 + |GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF11_LTDC; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_8|GPIO_PIN_15 + |GPIO_PIN_0|GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF14_LTDC; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_LTDC; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF12_LTDC; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* LTDC interrupt Init */ + HAL_NVIC_SetPriority(LTDC_IRQn, 5, 0); + /* USER CODE BEGIN LTDC_MspInit 1 */ + + /* USER CODE END LTDC_MspInit 1 */ + + } + +} + +/** + * @brief LTDC MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hltdc: LTDC handle pointer + * @retval None + */ +void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc) +{ + if(hltdc->Instance==LTDC) + { + /* USER CODE BEGIN LTDC_MspDeInit 0 */ + + /* USER CODE END LTDC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_LTDC_CLK_DISABLE(); + + /**LTDC GPIO Configuration + PF0 ------> LTDC_R2 + PG0 ------> LTDC_R7 + PB3(JTDO/TRACESWO) ------> LTDC_R4 + PG2 ------> LTDC_HSYNC + PE11 ------> LTDC_VSYNC + PA12 ------> LTDC_B2 + PA11 ------> LTDC_B3 + PB4(NJTRST) ------> LTDC_R3 + PA9 ------> LTDC_B5 + PG1 ------> LTDC_R6 + PA10 ------> LTDC_B4 + PG14 ------> LTDC_B1 + PA8 ------> LTDC_B6 + PG13 ------> LTDC_CLK + PA15(JTDI) ------> LTDC_R5 + PF7 ------> LTDC_G0 + PF9 ------> LTDC_R0 + PF10 ------> LTDC_R1 + PB12 ------> LTDC_G5 + PA0 ------> LTDC_G3 + PA1 ------> LTDC_G2 + PF11 ------> LTDC_B0 + PB14 ------> LTDC_DE + PB15 ------> LTDC_G7 + PF15 ------> LTDC_G1 + PB11 ------> LTDC_G6 + PB13 ------> LTDC_G4 + PA6 ------> LTDC_B7 + */ + HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_15); + + HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_14 + |GPIO_PIN_13); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14 + |GPIO_PIN_15|GPIO_PIN_11|GPIO_PIN_13); + + HAL_GPIO_DeInit(GPIOE, GPIO_PIN_11); + + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_8|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1 + |GPIO_PIN_6); + + /* LTDC interrupt DeInit */ + HAL_NVIC_DisableIRQ(LTDC_IRQn); + /* USER CODE BEGIN LTDC_MspDeInit 1 */ + + /* USER CODE END LTDC_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c b/Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c new file mode 100644 index 0000000..d9054b5 --- /dev/null +++ b/Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c @@ -0,0 +1,192 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_timebase_tim.c + * @author MCD Application Team + * @brief Template for HAL time base based on the peripheral hardware TIM6. + * + * This file override the native HAL time base functions (defined as weak) + * the TIM time base: + * + Initializes the TIM6 peripheral to generate a Period elapsed Event each 1ms + * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL_TimeBase + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define TIM_CNT_FREQ 1000000U /* Timer counter frequency : 1 MHz */ +#define TIM_FREQ 1000U /* Timer frequency : 1 kHz => to have 1 ms interrupt */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +TIM_HandleTypeDef htim6; + +/* Private function prototypes -----------------------------------------------*/ +#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_APB1_DIV1) + { + uwTimclock = HAL_RCC_GetPCLK1Freq(); + } + else if (uwAPB1Prescaler == RCC_APB1_DIV2) + { + uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq(); + } + else + { + if (__HAL_RCC_GET_TIMCLKPRESCALER() == RCC_TIMPRES_DISABLE) + { + uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq(); + } + else + { + uwTimclock = 4UL * HAL_RCC_GetPCLK1Freq(); + } + } + + /* Compute the prescaler value to have TIM6 counter clock equal to TIM_CNT_FREQ */ + uwPrescalerValue = (uint32_t)((uwTimclock / TIM_CNT_FREQ) - 1U); + + /* Initialize TIM6 */ + htim6.Instance = TIM6; + + /* Initialize TIMx peripheral as follow: + + Period = [uwTickFreq * (TIM_CNT_FREQ/TIM_FREQ) - 1]. to have a (uwTickFreq/TIM_FREQ) s time base. + + Prescaler = (uwTimclock/TIM_CNT_FREQ - 1) to have a TIM_CNT_FREQ counter clock. + + ClockDivision = 0 + + Counter direction = Up + */ + htim6.Init.Period = ((uint32_t)uwTickFreq * (TIM_CNT_FREQ / TIM_FREQ)) - 1U; + htim6.Init.Prescaler = uwPrescalerValue; + htim6.Init.ClockDivision = 0; + htim6.Init.CounterMode = TIM_COUNTERMODE_UP; + htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + Status = HAL_TIM_Base_Init(&htim6); + if (Status == HAL_OK) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U) + HAL_TIM_RegisterCallback(&htim6, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + /* Start the TIM time Base generation in interrupt mode */ + Status = HAL_TIM_Base_Start_IT(&htim6); + if (Status == HAL_OK) + { + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + /* Configure the TIM6 global Interrupt priority */ + HAL_NVIC_SetPriority(TIM6_IRQn, TickPriority, 0); + + /* Enable the TIM6 global Interrupt */ + HAL_NVIC_EnableIRQ(TIM6_IRQn); + + uwTickPrio = TickPriority; + } + else + { + Status = HAL_ERROR; + } + } + } + + /* Return function status */ + return Status; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling TIM6 update interrupt. + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable TIM6 update interrupt */ + __HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by enabling TIM6 update interrupt. + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Enable TIM6 update interrupt */ + __HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE); +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM6 interrupt took place, inside + * HAL_TIM6_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) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + HAL_IncTick(); + +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ diff --git a/Appli/Core/Src/stm32h7rsxx_it.c b/Appli/Core/Src/stm32h7rsxx_it.c new file mode 100644 index 0000000..b6371f6 --- /dev/null +++ b/Appli/Core/Src/stm32h7rsxx_it.c @@ -0,0 +1,337 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 "stm32h7rsxx_it.h" + +#include "stm32h7s78_discovery_audio.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 --------------------------------------------------------*/ +extern DMA_NodeTypeDef Node_GPDMA1_Channel0; +extern DMA_QListTypeDef List_GPDMA1_Channel0; +extern DMA_HandleTypeDef handle_GPDMA1_Channel0; +extern MDF_HandleTypeDef AdfHandle0; +extern DMA2D_HandleTypeDef hdma2d; +extern GPU2D_HandleTypeDef hgpu2d; +extern DMA_HandleTypeDef handle_HPDMA1_Channel1; +extern DMA_HandleTypeDef handle_HPDMA1_Channel0; +extern JPEG_HandleTypeDef hjpeg; +extern LTDC_HandleTypeDef hltdc; +extern TIM_HandleTypeDef htim6; + +extern DMA_HandleTypeDef hDmaI2sTx; + +/* 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 Pre-fetch 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 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 */ +} + +/******************************************************************************/ +/* STM32H7RSxx 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_stm32h7rsxx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles EXTI line3 interrupt. + */ +void EXTI3_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI3_IRQn 0 */ + + /* USER CODE END EXTI3_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(TP_IRQ_Pin); + /* USER CODE BEGIN EXTI3_IRQn 1 */ + + /* USER CODE END EXTI3_IRQn 1 */ +} + +/** + * @brief This function handles GPDMA1 Channel 0 global interrupt. + */ +void GPDMA1_Channel0_IRQHandler(void) +{ + /* USER CODE BEGIN GPDMA1_Channel0_IRQn 0 */ + + /* USER CODE END GPDMA1_Channel0_IRQn 0 */ + HAL_DMA_IRQHandler(&handle_GPDMA1_Channel0); + /* USER CODE BEGIN GPDMA1_Channel0_IRQn 1 */ + + /* USER CODE END GPDMA1_Channel0_IRQn 1 */ +} + +void GPDMA1_Channel2_IRQHandler(void) +{ + BSP_AUDIO_OUT_IRQHandler(0, AUDIO_OUT_HEADPHONE); +} + +/** + * @brief This function handles TIM6 global interrupt. + */ +void TIM6_IRQHandler(void) +{ + /* USER CODE BEGIN TIM6_IRQn 0 */ + + /* USER CODE END TIM6_IRQn 0 */ + HAL_TIM_IRQHandler(&htim6); + /* USER CODE BEGIN TIM6_IRQn 1 */ + + /* USER CODE END TIM6_IRQn 1 */ +} + +/** + * @brief This function handles HPDMA1 Channel 0 global interrupt. + */ +void HPDMA1_Channel0_IRQHandler(void) +{ + /* USER CODE BEGIN HPDMA1_Channel0_IRQn 0 */ + + /* USER CODE END HPDMA1_Channel0_IRQn 0 */ + HAL_DMA_IRQHandler(&handle_HPDMA1_Channel0); + /* USER CODE BEGIN HPDMA1_Channel0_IRQn 1 */ + + /* USER CODE END HPDMA1_Channel0_IRQn 1 */ +} + +/** + * @brief This function handles HPDMA1 Channel 1 global interrupt. + */ +void HPDMA1_Channel1_IRQHandler(void) +{ + /* USER CODE BEGIN HPDMA1_Channel1_IRQn 0 */ + + /* USER CODE END HPDMA1_Channel1_IRQn 0 */ + HAL_DMA_IRQHandler(&handle_HPDMA1_Channel1); + /* USER CODE BEGIN HPDMA1_Channel1_IRQn 1 */ + + /* USER CODE END HPDMA1_Channel1_IRQn 1 */ +} + +/** + * @brief This function handles LTDC global interrupt. + */ +void LTDC_IRQHandler(void) +{ + /* USER CODE BEGIN LTDC_IRQn 0 */ + + /* USER CODE END LTDC_IRQn 0 */ + HAL_LTDC_IRQHandler(&hltdc); + /* USER CODE BEGIN LTDC_IRQn 1 */ + + /* USER CODE END LTDC_IRQn 1 */ +} + +/** + * @brief This function handles DMA2D global interrupt. + */ +void DMA2D_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2D_IRQn 0 */ + + /* USER CODE END DMA2D_IRQn 0 */ + HAL_DMA2D_IRQHandler(&hdma2d); + /* USER CODE BEGIN DMA2D_IRQn 1 */ + + /* USER CODE END DMA2D_IRQn 1 */ +} + +/** + * @brief This function handles JPEG global interrupt. + */ +void JPEG_IRQHandler(void) +{ + /* USER CODE BEGIN JPEG_IRQn 0 */ + + /* USER CODE END JPEG_IRQn 0 */ + HAL_JPEG_IRQHandler(&hjpeg); + /* USER CODE BEGIN JPEG_IRQn 1 */ + + /* USER CODE END JPEG_IRQn 1 */ +} + +/** + * @brief This function handles ADF1 Filter 0 global Interrupt. + */ +void ADF1_FLT0_IRQHandler(void) +{ + /* USER CODE BEGIN ADF1_FLT0_IRQn 0 */ + + /* USER CODE END ADF1_FLT0_IRQn 0 */ + HAL_MDF_IRQHandler(&AdfHandle0); + /* USER CODE BEGIN ADF1_FLT0_IRQn 1 */ + + /* USER CODE END ADF1_FLT0_IRQn 1 */ +} + +/** + * @brief This function handles GPU2D global interrupt. + */ +void GPU2D_IRQHandler(void) +{ + /* USER CODE BEGIN GPU2D_IRQn 0 */ + + /* USER CODE END GPU2D_IRQn 0 */ + HAL_GPU2D_IRQHandler(&hgpu2d); + /* USER CODE BEGIN GPU2D_IRQn 1 */ + + /* USER CODE END GPU2D_IRQn 1 */ +} + +/** + * @brief This function handles GPU2D Error interrupt. + */ +void GPU2D_ER_IRQHandler(void) +{ + /* USER CODE BEGIN GPU2D_ER_IRQn 0 */ + + /* USER CODE END GPU2D_ER_IRQn 0 */ + HAL_GPU2D_ER_IRQHandler(&hgpu2d); + /* USER CODE BEGIN GPU2D_ER_IRQn 1 */ + + /* USER CODE END GPU2D_ER_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Appli/Core/Src/system_stm32h7rsxx.c b/Appli/Core/Src/system_stm32h7rsxx.c new file mode 100644 index 0000000..bc2429f --- /dev/null +++ b/Appli/Core/Src/system_stm32h7rsxx.c @@ -0,0 +1,304 @@ +/** + ****************************************************************************** + * @file system_stm32h7rsxx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M7 Device Peripheral Access Layer System Source 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. + * + ****************************************************************************** + * + * 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_stm32h7rsxx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (sys_cpu_ck), 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_stm32h7rsxx.s" file, to + * optionally configure the system clock before to branch to main program. + * + *============================================================================= + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32H7RSxx_System + * @{ + */ + +/** @addtogroup STM32H7RSxx_System_Private_Includes + * @{ + */ + +#include "stm32h7rsxx.h" +#include + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 24000000UL /*!< Value of the High-Speed External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE 64000000UL /*!< Value of the High-Speed Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE 4000000UL /*!< Value of the Low-power Internal oscillator in Hz */ +#endif /* CSI_VALUE */ + +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line or define USER_VECT_TAB_ADDRESS at compiler level if you need + to relocate the vector table anywhere in Flash or Sram, else the vector table is kept at + the automatic remap of the selected boot address */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line or define VECT_TAB_SRAM at compiler level if you need + to relocate your vector Table in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ + +#if defined(VECT_TAB_SRAM) +#if !defined(VECT_TAB_BASE_ADDRESS) +#define VECT_TAB_BASE_ADDRESS ITCM_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x400. */ +#endif +#if !defined(VECT_TAB_OFFSET) +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x400. */ +#endif +#else +#if !defined(VECT_TAB_BASE_ADDRESS) +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x400. */ +#endif +#if !defined(VECT_TAB_OFFSET) +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x400. */ +#endif +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ + +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in two ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) 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 first function listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = HSI_VALUE; + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @retval None + */ + +void SystemInit(void) +{ + /* Configure the Vector Table location -------------------------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; +#endif + + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to RCC registers values. + * The SystemCoreClock variable contains the core clock (sys_cpu_ck), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock 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 HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSI_VALUE(*) + * or CSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) CSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal.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. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc; + float_t pllfracn, pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* HSI used as system clock source (default after reset) */ + sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + break; + + case 0x08: /* CSI used as system clock source */ + sysclk = CSI_VALUE; + break; + + case 0x10: /* HSE used as system clock source */ + sysclk = HSE_VALUE; + break; + + case 0x18: /* PLL1 used as system clock source */ + /* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL1_VCO / PLL1R + */ + pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC); + pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ; + if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U) + { + pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)>> RCC_PLL1FRACR_FRACN_Pos)); + } + else + { + pllfracn = (float_t)0U; + } + + if (pllm != 0U) + { + switch (pllsource) + { + case 0x02: /* HSE used as PLL1 clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x01: /* CSI used as PLL1 clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x00: /* HSI used as PLL1 clock source */ + default: + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 ); + break; + } + pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U ) ; + sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp); + } + else + { + sysclk = 0U; + } + break; + + default: /* Unexpected, default to HSI used as system clock source (default after reset) */ + sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + break; + } + + /* system clock frequency : CM7 CPU frequency */ + core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE); + if (core_presc >= 8U) + { + SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U)); + } + else + { + SystemCoreClock = sysclk; + } +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Appli/Middlewares/.DS_Store b/Appli/Middlewares/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b47eadf98dd0ca4fc14d84eb188cc762844ed202 GIT binary patch literal 6148 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 YR_Tt=P6 z!@wLs-sQ-D`A=f1`UCQ+kg@7Hz?@vs2O#?u)VmTMS1k~8^`+olG1n9U>Mm&umW%o8 z*~6LXt@<3IsGj@w=UjAu1+-Tn~xTFjap zFa;p*9pvAMF7Jf@o!G{mpNqLG3?_mr!FDlgcZj+BOELEb0pqxr`M9@6%>C&9{*%EI z;GmcX+Jho7>(I$M###-p_2-G%&<5NoX5(ajwoCfK#elvZV$2UCLk<1aOcS%Y0+9d6 z7BP>~&!g9gd8{e;Ud$8mfN?yzTFjQEVxFSkr|SX6{S3UfwiWXn{XSO>(C_oqc^+Ob z)QZ{WfUm{81h1Fq^Q9R8y}m?0ujB&yeuchXVH~gQ6|7h>GR+Y@QavVnde`Jfq7sxp#NX@i>VER zQ$Yn-3E*4%otQ`}7z|1QdWxXu$k$@=3vr8IK3jagv$)S_$rf%voee6$O0l?$VL4Ze zDu-(IA^_T=oK_yrsRxf1eh3&kt>=SDwWg}Ywc#V7+>=J9#HnGO^5o_!;vCb#}6#%|xz;`^l znZS6?+yZupb#`a5CZW505vve6rhX~bw8>)4px#X4vl@e3Fak^hjA<5f&DssV2FO>! z*h@wN+Le@nn*s8cARpU6t27ye0ezLis}x?P^jQk8(iLDUfY-U`@!bAk23Q8RfX~G$ zYX}%m8S<4a1&p=qQ?bh7Th2U{Gsg0(K@C8!6(Mjum;~sf0(mQtcXkjkuGtd-`kq}4 z-W6+(19AX!G3R1%A3)c01+)jF!2+-rybcbEH7^S=j(Ln@-WsqS{3O==*5EWSN38Q2 zg9%^<_(iP0v;o7wJg^$P4EBq4ei)nzD!@wc0{Bj>3sS*gPzqLnt>A017BmI@!3?kr zpr-}ji*;dJz}PC`e-UzB49`m#*Cp`1eyoUG^bg_i`f2HnUr-`*R89XG`wUfoVj=byW=lU|S zmZ7(09|GjM!4H}O@^0u2?h$J_>E-BUIdzs(=SJ$>NIy5y|Bbx>I=m4XZe;8?UM$v% z&H%Y?suJtwtbVtF2q9vx;%9x(<9P)@>ufTCrAJ zpa4{hbvtt3j?A~C$2G*cPFrgp0B?(R2Xfuf0l@!`C4f42rhrQDmRNW72g}4-8xKZ+ z8c-|N-4g(H?q;la?-1)A0a@TQumHgSUh?jxuX`U8>%P`t4)|EC`>A*TrQijz9%u-L z0ml6R^S_QZ>y87oTSvd^o&)>Ds%{K&!7Q*Gz-K+WT#pXduK?S@L9sS;29p4J8{oI$ zJFzx41%1FYfNnN2?oC0^1C)X_;B~PcL}w3n1(U&2K;I9gf)St^(C5Rw0c{>e@9ZzE z&G2|+oLG;B0b_WS{vNLp>q+F=QYO|@=ZW?7Cb6C&e`^8QCDyaFf3{Yv=g5D)NURq| ziuEF6dGS-Rw%sGvOYOm9V)31V^~x%-wl5XlW5RckZ3D)bd;NaD&j;}b0{VC82-zm@@V8WkhtgiOk)J|;USAt#}u z-=CS4nU!O5LdS%TF+EMDF*)6Hx~H@u%b4sHwJY3oYJO_IN$H%>F)O82tA-}4tFq>3 zrhm<#|J6Z*t{ly@VYb_{i!mw6sY{B>5s45^MG760GK$j`qEEy3aXdM;XX{nnnDS;mCgMHa2m^ZKoHp)(lLt};#I6mxOI_cBdlC^e^#NuHgP zmXecdR$M>yn4~_}CuFsIubpX?(yq;WO&c|Ru1lLXZQ3YQUkjl|_P*R7Olitw)UxTE-Cs4UGx&1%jLYJ<{UH z%nq@(WXBnkp*XUJrm|ab{5D%9`Iko>=Em#kFs<9OG3_{%Rd#m$`idA^H6%S$C{M7K z7+1?!aWt&Ut3!tjYU&w193&5;7Ndh`;TdGC?Ehd`|G!-((Y~?f-#@+eahUcA^y#S! z;_%6{Y|%5ddun&qSM*%ARnN>Ut*<5CDIB_T0-QOjk2(iMw%Bfl&$f9w&+y)$FB7)N zPr(T92MR`N^*4Z#UnO4Rp$U=z4M_-^D2dQ|E=`hp#FHfnS|55)Qlvh#fuukiN&{#k z=mBXg4WUh>5wt1v7ilI$3^plziMw4G!@+q*Pdj*0A-4$>Cd(WN=ko_Ht8hVqsbXcy=Y z!n*^Y$4VzCzlDr^&#xPm9xq*>{PGdX?pmU+0@U-c4=zN(8Jx^vq|Kif~rG)qeQVLxl=SDu}IaH;UQVzXHDxeq3 zY@Xk~MCL#jx^$7ujeIDV$~@?0G9S8F&Vybqe~Ek`RdPP`3b}xsE1@6ol=l}n)4%EHL|a-B=Bmqo;v$z@QU&!u!Z^nIQPyd1hhsv^7PCbIq`etM(BNV6ZC$UJ|H&}UnjRft7Rp0J@j4KAh$v{$|~q4Ssi(YryXyPyv-Aj zN*|Ur&>Fb|x>@doKH}0xWi9c?GQGy`hskXyutIyo1oj|LFh~J5cFkv82XCTK)1_g=<>A&(G$ zO&){3E{{k4#g(C96up|G)3kzx^NX)4%wSefnpA z;M4V|Wk>q-y?@}-|M452{^@_<(?34s)60(V=^y=pPyfjE=^y>Zr+?`B^bhO!^bcL1 z{-NvBKdj@^KlqJL-{bo9J)%B+&;LN5{?7kLKK+e9efpn1{m*^+|I7RI|G7T>kM`+* z`t;xK)Bp78x=(-MfBrtbUxp;vP2?L80k)(;JAvWg9B>V|75LqHno|NU1W$r}z%RLW zlMPFc&8;E0!VNY~o6*%x=6T79XSvCZXN>p4p{IM{z*D?xy}W8&j`Ol}`g`Fq9lS6l zvuh>HH^wJ+-O{hI-B@-2OG=@}+A2wWk(4H@>_$=zEE`eXoLoC)W1Fn5w?1h*Jl18| zhA$7&B3o>;A+dhfe(_es`i8HL(yXtoue=iLtBv*QcfGaWsn&qE{DtPkWu zYY$J9B|-awTfvjyRqze)TYEU)=iF`Wrq+AX3G@Z$fLpFWOs^2(lVowCM}|ol*V0atk*aE+%B!g z`eoduKq>GOdyCjxQVEuTRiGO9Y4a9s-lEMm@G^Ky zI)hv=0tBrc8|bFSdUZoq|FnLMt?kzHeB+j8y<)xKhA&&sx#3IJvu^kzVJphFS;J2Q%T5l*wOM%Iw zvMtE7+13X6%nk39)j`RfmX@0}02>P{$?A0?G03gqTeGa(tYtTnRFZY|QesN77G6nA zN!EE65mS;iV-7JTSq0OGDao2}4lyNJ!$%W?)L1JYZgWgp_u<`ag9rppq)Tpa1OW-d;|QhINumzXj;EU<_2lyV0EUaWSLCD z9#Zb6yGd$L^N*8M?xLodt{YOv(ky91R)@4lOg(M&P}%EHRBlq*$gBxzC&O=G>g2TCa(F(J);IO+wBBB=ZrbLdw9bf-?M2%oY`avq z(~MRw!!g}!Oi^x!z_P%&!0^EFfv$lLf%HIHpk<&%pkXj2m>jGZ3>)LQ$jIvM*+Z%WBhDPR-k7V$lUr>qt}!xtT#bon z)}j{GDFeoB=2_nQi>_*+VcSJljUO*f8_((6v~NnE`aK5^{2emM&73qa`|#29a5TGV zcFXEzLq?6OzNh8*>aH4zv>ZRA`r1+9iQ_i&d-;8X25#o3^919^ZMOTE?*@(3e7n!U z@#BZon6Yj>37c=Jhs6+3FW5@LT2I2kR$jdoUcF4(Q?HE%)QgLgOt)TUT%23aF!gcFx%cM>wggT8YWt&@PTjNTtQ{Bg9lbTAERuHO~=921G zNj1&gDz4<~-71};RW3hN<#M+t+mptvqXagIdt!AG_fV&fBL8)?uzz;8*?7YE{E34K zGX_n{7*q%*RbMfusA+ZO{&+12SKC>WCi9j!!o0%j@fn2!tMfAkhS#6qwmYhL zq86W!F>t+195i~|`iZ%P12>$Id%~cMyn*94o;2dP?nm@>`Juj!8}U1RjZkLCX0kOm_W@ z{*qlWyL`4Z9aKEf`zz-lt75iJg-5eB?{^QX464q}8(3b!kAyV zkGHE^4H<3W3Pw*r4HGAfdxY(hUL?xLGr)50?w7~7={T~*O9?|RkD+3AG#1rEMKpA) zYLoJqI%2G{(GspIw_m^9zI{&YeL}CEJ-T;0?%1wfI(N$H*de=pySB$=g!s5%!0&Tx%SeYo8G|QXcv`h@ra83PLA zJ9d!u@d-o|h*dYqC|z%w^f7M4YBH$TdP{Er6OZIP}V z#*c>wZLQ3~ld1;O^_9%j5OtE()}ry_s?8$0WW{H?qw>b*xueWU)56tp8T~Vgs-{h1 zYMNJ7%gFiZ8=5!I-OLxV%?E|6Mvu!#ukPC-V|?Dg)b$OeYUKQl&2q!djx6ceVSRFa zPqFLkB}F5l#JZ6}lY=2thg9YFU;;SC z8(LKtFeAm)aRVk*CHK;NhG?pNnaLU9svmgw%%qI3zC1D~FPh`eO#VT%Q0?T9sa2c2 zSiCwrySjaQHIcvo<`fzGxan>kJItxEGBQe&+1RKzml5bTZ+x##s6RbjC-{n*T$xOw zy7KgKUOFt3TWpZrPB=Yll9p_Vl{6ZoC6%#~L(L~;V97kh%nEK)9n3oPmz3PN!JwjE z)u!>kC@%EMhm6V?g3k&Ms+ttF+99KlNO|R|Q1nJwG*;bUz&N{wMV`j27PedJxvp3h z{MfiqwUf!8-!7M8y`-M&miuIy-h4jL)p98k`XxTs5gGuO?DCIU}5$QMK86+IqUG zbP(RoGn|^pBUiMj9(?6^G*)DKb@V+V%|LVCUDC|S;;9bd&b@F~pRl$#vRBJBv_8i) zYNFsrlXAZ)<}UP;^0e7Ut99H--o*WZCOi*uGw+YOjypDfo=bRvJMbepedJ$fnngD8 zw8m|Gp1F-Xz)j=~?gl*~jZIUYD7cV!WBrX*i+DDrHP2a$;JJdU%xRI?JkjvJbBT24 z$%$D~YAPe+B3DP2M%Hl8e6#%m&#WZy{7F9NE0M2#Z*v#DBQ37y&iwmkY21U7OD~nw zyoIL{R`5O^6Pe1BDK<}{%tZ!=Cox_zTdZuj7s@|OQ**vO04}#js(Gf~=4qC*coJd- zZ-eS)PO{Q{6C*>p@7tI@=E3zw?zBI|S;PJEcTLE*FR~`Gk7r^!$SI6xlWaFz?Al*1 zs_l#3_I6)p5onFO-b&hqD^`U(o?{RuPkjJRc z<_V9hc;etk9s%rOPB&+oBHnOx8Sgu~kvC@TFng_j)@W-w@0%*J&$So@2wqIyS4VU+8-lbBbV|_%lSOF@mJ<#B_rF+{r-12-vH-_mu!Zy*%4)dY;j86HIFO?wGW%d%z2kj4>=DbrXf}Xqjmicb=t@YjOds^Rj7`T{^U@srM{nz%t z?yi;E#kI?7H`H$8S&&A|A)9-?1nZ6Td7RUj?`2rrI{6#V^EG7#+M7P+G&FOLnP$#4 z^U&l%-iLOFEBgbyq3jj&ck>N0C-M$2l{v@iX7#s*bDnJ#TIcdvd8xI@ddvF74)8{; zB)gH_-ag4b%PzDl?D_UGyV`!4H*$Sw@3#+fMx1yj&1ubh>9Tnh=Q+GnY9;Tz`iF0# z?a2p^Etdabf|@;T5HW>>jJaMYU7*dKfyY|43mAhw(EGW;!wL8Dd7s zG^>lp(BIJEv1sY-JR@H@k1@9GaGvK6nFZE2{*Y|oBWzC*^Q_(3$+lmTckTC0z`0F! zI`O=-?JMgpdjwYSxYNfsPSWk0^iI?5>eMtYR^?*Ip+2`aQFG#$VD>WH_mz8 z@L$x-Sjlws{_**CS0|nDLcGdEeA+{-?nm$g{p_LSG{tgG!!E|)Ay#lM$4@v|P%&%# z47}KO+2kK>)yPy|J%iT~abBt&$#YnD@`Mlnzbmqor`X=$S)=pexRz&Au93B7QSD!( zlyCapVQru08*IJm8yx9qRax&?qpW2|&M(@|G);MG<#Ty}XVUuk9+fKR@4VWzZ{$jz z%xT24b*+(XGT$eB%qYL6hm-9sa%}A|Ykg#}&3`!Xz0b2`cSX_+{|_KCgD2D;lRE-F z$qQur-93Wp@er!5zsuQ9xikW&1X{{m-&h%EE|Up7E`PqlZYjCWeNsl7dr0>qd_>z* ze++mZ^af)=bD()cK_0-T$QbHw*0%5{RX%Q5E)#-jQsNsM`IY{b`JR_4U?uU@&PTG= z-&1CiUPHSl`H%eQ7pJ%DaznSuU@>UX#BYhk3iL~n+jmHJ9;<`9i;((w0cJR3Z z=(vxupOWL9^2i5_Wjs7j1((vt2*SZ&2z43|_6L`l=Vh^ZKC+r}Lb-(gFVlQ5FdCi= zpGB1SrCl5HE+O6=IrO`rB#;i;TK7p$tD!tb*opC<;ff-5<$~zE8wf z@a3`UX*W30DUe~L4LTp?+axPA4TicXkNoP~%uNTL%%to*|1!o=fWGlE7SDKEUrI-R zrd)`94TS$iU?n{Fy7o{Yqv=0~`o}t-xHfbt=_~2$o0y(-zDZxiypCk<4ie|*8!`%< z#Jp638MGfp|D9ClI`3v|ZBOccOr41e@|(E8&e7FoZKLhsl^M0e)rUh_O`WUI>mEV} zG*TI2aP3U(4p86gEJ8$wckb5Ja`NX{FyVqLa z#(xu1u5}KFrUVP@gk{V2h3L^Q;B($M`{=SQE9WG(tb?Z+jFU6DszD zAF!j_u}ST#yZUGNFC)GfsPDjDBfr4Qv(Fdh4)U&u*=H8jv&R58l=%JZ?8S9aJ zFi~~l&V@)*y)F=MZeNej(`(XIa*4f@{ereVR_eRgi@tIOvcKr&mBWWJKY6}0WVQbb z{vq`keC-w~K!%CP@}$ZG&+ft5k{E1+pLkQcus^)b*GS^2x60K)uG~faWp3N)e1t<6 zfqV&Iv%{#P{BCpG~@bov5k+hHVeId8{_>{*Qx-C#CxB17g z<{HUbU#{FiyD=&Y?Q|b>s&l=Z$@*H1Z(5Ac(f!g8--O5k`(DN~55ErVO6>Jse)my{ z4yRL3_2c>2%NXAX`yR<6O!r^UHDC7=*RvPQmO=jMaus>J)mz%q?-k@NWc_w#?OslM zT|2r*5cPY{A1;H>mEA+yVYyxX6GU)cE(Cqy9?h})R&IV zYpm6um{rd^VZSZ4zFKA%o2)Ktsj-aAf7ntr-E56ZNo`Te(P^Qv^#aYd0^cZ{+5 zAmkqUzlF}B*3&SoA#3qey*~f9GX3w?XMQgPXDJ`&YiSgC<~v2KKgAu66Sd%^!KZMgv>nD>gat@Vt8YN2iaT*MFC`Hp(4!5wn9>=wB)e z6%OBaD2`4CUzCLk|Fe{Vqtnh^wEI_>AnolHt}Tjdb4R89!?|Vxs|`BfEnD!qQgJB# zDr*^NTep3pT;%|F?XrHYO;W5lRNf8$4PyG%HK=+;2Dg1|eq!?y3uE=23GCapg9%(K zwo7NiQH1?sVa$eN{vwvvQ2j++J9m8vzU7EIhu6g6wZU3(+edv+-TME3inDgMf#<<< z|F_4bcW=~3@brlIcd-xY%Rcf=_9Jg)Gy?LZ>&`s7U| zyhY@|55&vJf73(6a$3l$=)STUc@IU~(w)n1l-K^i3%pm3mHi7ZIMDV7_-63HG~(Za z3y8l*_!QxC>VFQOg@jLg<-eXodJcGu^cUpM0ON=+A#6n00W<(9v|pys{YY%z{C_Vz z^0Tb(sL!_lF3p}LA34(qA0a$H_SxaT4rBBAZ$kEtM|>uZ&Huj(8Hf8>&y=KYx^FK5Og3858-HJ!MGu(Ylw_{j;rm*k}l!HQqj!etDTJ-@mvaa>bEO z(!Dc#)j@=}5ia)o-0uv=AlD?WkpnUPrtH)^Bs30+ZCj4tA0MzB$MM^aZM&~=aETXB z2=aagzdsnTd;utrWswX7;{(9}|2@g)r!@!E;@@`!y*NzbH51lB9$BEO=0^|y*M}90 z6KZ>hD!~K)C)~ZXD}jpUb90?gf?rQ$qH=)Y z(eZzA1QPT>(u5EXy18%e2nKz~9Z#?Pxm;a|(7SsE{BiC8b&x(Qz?(N1L9|Habfwmu z_;>~v^d}J5@$NwyJ!w>R5{!%U#l`bn9YaP_2(IGmkcrYzU(liN+;9U8dHn_j!p%c~xIhraph6nC96aqR3!pu_F^U;Ye4N{hFCj55I%l!K zb{y=8SCH6tAYk*N6DTI=9dR15eQ{dDhY)dbny;08UfpQTI8FKaz{U>3aeVr3X57Q$ z;!?Fy+Y^mBR2y;+Z%%Dn6E1J`=J*v1{HVia$$P?%Is$65e|Rt%0Uz?%K4`$tLZmO2 zl%rHpM@DQN={aYMwvb<)x|+Yw^f}^0{W^P%$2FfO)&df zg@MH*j1vdHSltkuLJ0wCAs0@|a;<@0odjL1YGt;r83a|s@{WMbn)cZ+^{E#n6Q6

L%Yj0kwC)JKzW*Z{;59WN z#uEr7CSdM*CBcQ^D-%3li9`seA|d9XQwOMrpM{NNhYDOdV=4TY4~?lmvlHU6i)C$g}_zp*UT^i6O3&7@R6SLA9du3m46d3nnC} zw^YU8z!`^faJ7U_V~jAP8g{Fbt_GB##>rnOF&LXPH&o+sR2J9$;qml^P>e(wB9rUC zJYPwPu2DEfE4y`dV%>TeOTb;Fu=RW;PU*;tH3L+qv0JUh&`cq#?Q~IdqN~mn{ z2*i)@mD+PuB|#mZZs_pCo|0(pMvzh$^dVn~SHM@gIjAivy!%vdP<^g1DKVfYx^b_h z|E;eKCh9@c#Cjoh-LPa01lh9rf*7>hr6(XW?4Fv^0qWsL_~@9lP~{AI!=Msc(!r@e zvlHX=B<--#<6!g-|47XjpAheP09*vll&RHgAyZ(-;f2*U)h!X=r!*-m)ZllbUv z9Ea~3lWSA1N8(dN$cOj{q(w&@F4NyGe9ZY@99*}9u0ZO`V%K`z0IHT1F#$Eyxl>=M zA4e4R>Lny7T>H~21+VE-#K(KQ_?+VEmlf)T_)+hg0^g{A(YnZILEMO^8ZZ7YbZyE3vs=wvTp%jO6I7-=?EWHMSo9I8^by)e@uLWTK_OV?K3`N2o;e{t6tBMph>uHRk)Rz` zwmV(!2M3m?Ca~6^?mMvr=AD)_aw~a6$5bb&n*tx}Eg=a(l0x3>>ykn+HXD3o#3AuV zhoPi;L2A*QaoFlsaDTS19^&Y9v+zRr9)?0w?+Du3v(4&7c=m2SpE{`o%}(H?XO?;p zE$T%Fx9kLc8VdyzeE5_ge#q~ZP&3G0jm1xH&{sbxsAn*VSQ(2g zDv1jv^7$>nMqxCub!wR%b#;t^6{^=J3`KRpk|N|UA*Ayaibrv1Igp%`h)KWzmr;*a zB$S1QXrf+HC^4RHQLF0K<>1Xei`?CJ;$S`1(}``@3u!k2e^PS1H)T=k$9Q~L6`we` zNHg2&t+6Ngs#v($)SdBYi7qp~vk!;VS7M6w5)S!FPxne)Um2I2kig=?L)!S1 z#Doy1`UZ6qOo3;VMDd*V|DxV2E;p6==Cp6Tux^+>H5$r@Xh zWGq{@Y{|x0HXyTDmVsbQY=g0lG1w&7ECFnG3>Xq`2-^uxLLfl=vN*|~KmtjAh2-&` z2=Dz4A;B8`->I6GMQ{e_Sd`2jPY^TZLV zlXv0?WzaU!uVj1?!O7xk&M29$fR%tjf?IM#ha|+13v>ar0)Q2ODCn2GF7lcRl%mgH z!pfKjlL1ogi3D^fFasJQE>n}@3h_7LKTSRXR3k(fnv4-vg5QCal=hmINQ=ZnK(??f z;=NiCBR1*5G(@Ri#UGW5Bnmblps7f>3pmt3kBK*N)2*h77XJ-z+X%z9#%$ttOOyThDwaaA-$65 zAE#mEU_px&AWF11|hX6k~P|J8RBGe4E3I-|djnrsL2zw!p!FsCm9-2(9 zXLAhaU*a&l$b+Q)7$`=@6B<08r>EgR4Hi-iYKUPa zBrv-H2*{{((uE+=$74VuA1i@-Yp@cR33|w~Mh>@mSV`x2DIb)Onnd=UwOC2N(p_r` zp^=PdfSK`;@R*b$CIg{BNnm9PLM@0O$<3of5@X0kSP4GI%!!<#VA#h>dMx@1Tr*y8 z!bIv}WfX!nHMJ*;@EBi7LPTl;EG*CuYq8S55c3vqe5|Cx(QuH+0F$^5auq2?J|>YE z3&9L6^sBhIL=HDfGKmI+RFHOo1OhFId00sx=y|{2>6|JE7o<87Rw4^|P()a{nwh!< z2??@aP)d+T8qJGp^JtGSVI|;f6)PbKq`VHo?f4}G)W(E?YLX!5ffAhpE78!YgaE8W z*U6IL&kaZlU^rM$e5}N?QgJ~@0YH7MgaAfQfxJl$!Y!B;iX*z1NwSCnCvV5dv#9G|7`fL*@ZUkA#{eg=1=k-U9Ov!8?-F_-Ibb9KtB3ys(84?Ic3u zKe!VgV4#!5hTt+t6&kw`8b3q?(R`8$dNCrjM~b90N|W3jjq+k7Mj_$NJam2RAT&@$ zDrK$1aQ-C@!#nQj)}&!4yp=a9FXYLFbVj9)12qX@C7~k)Md5i0H2lb+l3+L(Us569 zBn6u2NN@L#WMze54;291vx=3eR3HHQ0-)ThrdNxgfAN>leWsr@-45*LL@`0}{H<4rz= zoBSU2c#OK;XEwSB>?R9h5?znWia@=Os_`P$gd>8KNMf4xL?6&0C~`ufk%bWi(Fplr zeG5kX5lN4QW{d8k_0Uz92&Ur6SeW<|pnyBV5a`f$;Z&T5#}$&y`6O&`_&rDnNf(3! zALem}1svF%=n=qGf%Ihvd}vHfiIa~jxCBS-@hdn!L0|t@aHFD1818r?unhYEB2t*l zQ7Dp#Ba+bKo+lz!tAxdJ(t%Mi-uua;6Kv;ubW03BDH7_app(2bnveupdO%7LB7!J* z2mp1Qx&~c~zD%N*!?1wBbVmk>1lkx7hn@g!B3%ZdIbx67fgrG414x2VP=+5o>_T%A-O#8p`e0inVVUyb&bY^=7~oJwp_Ra$v`S*M zg+UWkFX{uhpcf;;h=dD;C`Je2nSvaNQ%IuHr#kPMr!#&6V0LB~4#WOHcan}wvrrIa z6HED}g8PUSRs*#RY8)eVgo37tA_W?Lh5X-$&G6-ey2zl0FoGyNkSUrZ zqsB`Dl7FtHcmePz^5F!Zlz5TH_e;PP8UPgcMw3``g=hkH#AFr}Nx}erLPrOGK@-a@5HHALyS6@URAJj3z=UB{5czKulCrJo6eDIhoX8pwZMMa*^_q z;DcC5rh-EeP)Ljp2S7k~VJaQFWRQn89~Qu$L;^0$vYZqXKu>B+TmjD$ucJzs$_X1u zR2P##6r3ULiS9JDBt>Xcu~d`?pcq<$d_se9j%o<%e-)R~$N^n7UBPh26BD8kO9dl} zw_pUCh&UpN2d(f#J^?+sP$CG%riuyPKp;9(sE_Y8AbKd3)D$rp)&%lMqZd$Z`bR;L zlqf|-NerUF&}bOk0Bf{a3dkUfVBQ!|DG8Va#GrE^uz_6(D`7X_<%ED%PUxDPM3sRc znBP$IB%XmspeZmmcv+Pc9>t;)(X%uic{)0d@q`4JfsqZ=~KiiA9LP9qgsfErCuNMR_P>b!@Z&iEM4zr;l% zFlK-rQpwO|z{(Jn7miX)fl3_*Y7@XFG!h6l2!@dY#Qvq(N%mA#URx-fG9}S^jaq5U;HI>pXn!1c&48MT3zPl(}c)`jIFKz zokP>Sy!ZLzrI_~mjIq%_QklLd<`|#Da^W!x1{L!A=M)nmiKqe|NXBURVoLNpJqw#G z+cJa3gz}+@Wc%aEod1%5M5}Fl$`nKi-*-}^FlGitQba`(c}XxJouGBF`T~i9PtjzE zT{J487VwjY@&|4RM}f1FC@HJTh$nv$!$a1DqiG1(jeboDvTVW{WBNG($`CVPmC*zt zN_io-n1Y~~Mhdwg>%+Pk#ApDBVzt!u~|f(M2Hd&#hrLWPO4XjE0z zl)~e(1dozQCW0tLQx3$eNGd9U^_3Jpj|gidAK_z^7VwaiB18Iw!4x8mZ6?VlP5eYP z6g;K+Y$I7P$$`HuOP6Ip4F1yhMG>`)#sNLW~Nf3`I1eZLy zk?0g6l!3efQlT(QWN1P z5QK;PtA5}DjJmqvU))~3WaGF3Wce>NQ`0%RO&cT zyAUQ~^rk4-wyIJf79xjALUT$%Hz(3d?0@i`_i zU&u&N{xRc7-WW;6bm9T%*@Vvo8e&QYn=y>jQyJ6{HYQWX?3NJ8l>Cx_M5}G0;K;J7 z%95sFObK8FNmFHThb!T8tLQ&)Ho*mie{@h-r@LcVtxhQbP?)4d+$}5MT+bmR<@1zf z|B3(!3U>&SsycuP$Il5+)&?R{SbX6}|r*hZ|kj!f=-%m8mM$w&G@tRIE5C z0&zr=3{uDw5tw;ApF*8@A*=|h_Y=`6MJWSaae?SzS#V5E3cCt0V){ut24+9BIncxs z6-C4|G+9zb3GFCZmS)O|qheIVMM1_BlA_o9m{E0XWYBfUojiUPpz~rRm^uVgA(e2_ z3ek7c!ITUeA%+JphM}uL{+Bi;hAy;oSq>Y zrwNg~VXSYm)6*EuXXlAKd~O-XRHpBVImYLZ#(ilM9OZMC&pcGL5VybsVv>e02EONs z%@`&c$+wm%80#ifB?88+x4mw0Vy&c)kI7+5RY*c0-b1x z5yC?aB|ni@?sbV#3aQWk|oHZ71BTn#e@FdWqX zDo#$51KMP=j;=#w7X)2P$)UI%ljCt2G6;Z^rZOGA#MqYuT8G;@hwTWVw3EkAei|9WM2lOWXWF!q-g#eBfX~=^jCO=HB zI2Q%YAmz$XEKws4&ZaF14F-@@6$dq!@Blml577}hj$tcW8nUI30I1N$7QiSRsRoeX z4U?1w9TzZ3qDr<&yI=TZI;*bsnSb!?nHW_`L5e`@jNo>}aZjEFO)8lJBS{Nn;&$Ru zDg&9LNeMG`N{VCHc=@2|ig?=+D+yTng@EM&0(9JyE+*)DlqPwdT-b{dDF}o-l&0yL z=S?ReP*5bgw$^zM^}g3m1)X$adTpll=dqZM^(>eg$hM$Jv>lYni+XtHVIE4Qk||K5 zpvF9@BNTEu%c3yWWyrEY!7zwxDZmT{u>@RA?Tn{F>Lj%gAmgo<$mLeWqN&^t`25c%SrChnk#v;pI{o&1dI509fT0pKGX0-xG6;&n;zD?gV0i zeNK8RTueCN0SS6G%_csE>Ubu@GBR?(=m-W5$z)-YvEq(j;OMdV=hGxV z!Em$cWI&24L=Et#20Xx3h;*_g#Rv}#2)zl&$&#TObbuxnlM^)kSdx)2fRai~Nm5#c z#3oxdWHdFUVdBB3QOS#011$uUQAun&d#B{c;l_L+ZJH3-MbR{|wv}+>AQA8^5phJ4 zCRyaY*^w#;hgL>U$`PMVq7+q(jVH~Vp$QR9%0Xa_ST_LNK#H)d%1T(Uc1^0qVq~7&VkRmQrGr7lT^z@(4Q7t9YM*EM1UZ71}6D<;9W|Q=n4Eff|Ko1KXC+gpyP&It~SI{2_uWN$OSRZ~?0qPzdrF za1>>mvW4-JU$h7-VJu7Qz)Fm=m%++{uA8Q=+Gb4BWyiF2+tf8vFT8}6G=Af>bl_nn zAs=BS=0n0t+^w574aKn|hNmHbfk2M1GAUzZ=7E)Y+cWVfqUm^8nI^1+z6Y$#>$;uK z%E;woWf)kAM-Wze(-}S1wrzCRDOjmPs)>>;qx)Ftx~^=?F&!o~69go538$(_2f##J zPMESO+me}p{3U5IElFurR7DwF?qj8tEafHgQqIKSQvn=jkCVu0s(Esdg$l)tWy!iK zNtP+7;bc0Y!X%aSi6fG9$p*DHNHArpAY4R>=ptzK=_E=~#Tcc?7YG}5DWA60SivCg zVWo;{yTot0?WSzU@}wozgdhNI9UZCyIvr~jDQWCA*=`2iS|ImRp4F(s(L zR}6RLi=YagL<3=flu-{5)?#G>c7qrRXqag&E8@k7Gz1gYaY~aFToj#bN}`}CbZxEk zo@wD5Ag4Mxzc$nQ^F+c@X@vlm)kqX3E}T($u_VP5sMK+wb|I|9OfOR?m0Xv?7%OFH z0TgVTBplL)Jvn?0R?=!5N&moL)%U0@)i#7ELe=zY5%DjsC-yATpzut&g84;Pck%6} zQ=R0xr(Sru6h`yedBRFtTI;Dy-xF($&t1&3p~sx-%)qHOV2#A(qr}x859c*zF8z|mu&*+PE8raCf%lhdLklf@j( zkStBtaV4A0LPLyMvZFYlJ87ww>YzS2Xb~)KCu#agYfcjKmu$ohp3*e=sOb#!O+zrD z{!Nq>@=6IRG@NY!q|e?tdYK$U^o!OvyMp} zY8Y0=jgfdAMSo&D3M3OvlF$>XVyAIUO;tg6=rFiBW-0HcS_N zT_~pWrc-us2d}FZo*?RIT0B&eGJqKv*&J1YzM%1nj4gnL4Aga)i^~%>(Rb3(a%3{D zsRCA1V4;iQcEl+>NR@~tnp0y!2EZUmSmm&73?s^%5OioFl8!+QNI*VV1yxU?!Gf4T z?{X46!7_N#B^B3=6X?)<;zqp~k%>UaLum~I7Z#JEpinS%y0+GltsFP5XLYT-Hq-j^ zWYRV8?iX3TfQ^`iqERX@&QnZ*N*xDk7m_S88C9iFt7Wqkyzz$!yANP?SA;ZdRJu-q zmj`kfm3p#DXbu$^)&S#REYZNniH;+`ttvfCaZpDCs7GhP3 zkW-77=uTe6L(+gatSDKy+s))*g(m08U)1e>(u*a;f?;Q~b)Glseoj-%6b)GCb7kA+ ziIHu?sJm{yK4Bmi7HBlhjTo3GH6t10K_MJH7SdWKlkwCIGVb7kF;}&;}L~JqTlcphQR$R2K zI1HqS1#ml*eM9qR-?&@`nTn#5`41+gGtL&D4Nkle6m zdyFwSru1AcNxF$=8Hsr@A_pOpiN`5z;#W;8R3)8)154ql4x2AyxN$wB8}(DOotjFe za<)Xab%1`{v9Nl9k8Qi;M?>opWzqL7E)Wtt@6(L_h9 zpESqNQ^}Nt84cyYV&eH+E*b?%5l|kZYEmU|;$1wI)U!%q<>^fMLiLMEZt1kS1T|UT zWT&Swn$OPTjgq*}E#sKV^gXf0_#D!>=6Qqij~OT9Ei)NH)g?(2c!fcUT#!q1;6H|G z?JHsg@i2navRKZR9on1ol6;g(K}fTwve|q->z49KBWsuQrECeQe72R%xM&^C7Hkr$ zFd3o~;uX4EFj6+24{k^Z4(`t8OL_mPp8Q1&|572)Fl}43+(MxRm}r$qZLu9AU$L+q zrC4)a-mz>8%-qUmORa{DT=6*IGlQ){0C^i5$MMUm)Kn^!0GG61a@E=KELu8|w=*E# zad5R#sn{hune`yZwuG#mwSoV1u;X^h7V>r;8S+A2z^y4)qBM1uRVq8S=E@luUpp;> zywS`%t^*8DlTLlsuHd%F0d1z*^n?Ax}h5yTPHA zv#596r;{ipIw?iIg~=wKwOh54n{4IDBQ4l2s$HQr$(E{esZxwni@AA7+2wqOI@HZ% zD}`jn(d@Wo8xYh0kC+u~Ter-73D>MrcEZX-HZ`VORVSU#X0jIMHy8ihD}zyiPIlA9 zY$023lxi6i3u}nv*jYS5b#l1f#^9?Mwpp$~?lg)PjBWtrWV~LsRm0Mi)^u*Q&-?@S z(_q=ghRp27WfzEt>CuggwrN8_u#6mpd@Z4rK_=O;;V_ISb4qbilox~A^76%@P2-!c zSmP8##oJ&HQ1Yyht2iT=#bT<61kESKxECWzBM|aXnk+lIUT(-Hg)}UMr#f1B!Hw$~ z-EN(l?bMVY6kUb(gsW;ik%l!no}ltl9^TOzl{yZje*-%8O2srObi36m1+qhvqumD- zN~L7daY(|W{gohov<8WJ4+f00C3dxeX$sefutxXk5e_hTEzW}r;>VBDfHW! z@`YRbs+sC(LL_RkzR6BcV>F+gC#>|jWgMf-RZpx@&5pf~k6D}Yj~OTLjS)+#XC2j1 z^BAwTku|br)+~bm7^ZWe!a$sqU3W5%U9L(RyO4O2IDE(Rn6BM!J`V)SR!h8S-vNMPuG3u@9Uwg7wq)E&PSBl_#k*F~#MG9QfFh-QsR}G7hm6PyN5@r1rZm~f zmdhPUayr!#I^IoNrJ5ruGX6(%R!jqrAjY7;YG=wtE-cVkRzB*Ig~`QUDEtCPkF8d# zfJ>+wu=IG&P2{btl`Oe=5T8!t8U#AG>hgK31P@w)lP=*u4sOyFT#2Tis#}su5^hap z6-omZEVnw5cJ-`^WfQsAvB+D~rF15p$rQ6^8YC}!y_D%p!$B17&bBHQ$aS_=DeIY- zJSk?NX33xk#1Tn(kV2k_pbEkztvKcr7j+^!iBizXQ;K}2n75L7w=-GICObv)c`G47 z(1W8E$ye)2wO+yhFGT;9_QasIyEzf5oPAJ3~3@66z+KWQn0Y3i3I^08U!ptgaowRlTNfN6`m$}nolYTFGiF@ zAmpJmrfPszZA!H%kBb|1i$WUJL`DwR&BQlzIt4hL7$K1_P5p+a&_Q#nq?_mxUK z4x*x{a-6E^)gs|vTu+3I_p2lcCJ5RgPeQp`YRHpBV zHOA+SJivgwOZmr)<4e7c+yW1zb>J1|6XXGwR={Ko(|cVFv#o@o*e*d6&~miN@Fi`M zb|&O9{Za`Cl&@C>r<7?{>!mtU)lv_$E@l!l0~3mq$p{&AkdtZxIWn>%q@Akmz-lk& zaCfO%uli3#Mr4JfY?%yoaz@9AlFm;|^Z*k*KWEmdPG+zZq}I;or5rLBGMQefRPS{& z$d!cr;}m0n701a4NqH9dSSrzD0SJIgEPs+|hg>FEa`HA`%@jd=E{7}4W)m8sP;#p9 zptY1KWeERq$fPpBs%pBLu4k$;wT|Ad!Hw$~ zJ=0s8Y5ln*)$%&t4uL@`ku2n}X+KHj2_D|j8I?K?)Gny8Jvo_9Q`oSf)uKT90lBmZ zvl>F9!Sh)NF*$4wp`8!lYRKdCR1+4bLXOG-V0s>vrP{_2C8(NIiA2)BxSrUvNCVB! zlq=GEU8~qCt#2Q<*<63=^fX5E*?HQp?sLmHMwzRgSff=M`=Ud>l%f1%#;JPqXecyjrHGlt%wYpeI)@!J=!8san(kK8VlG{SD1jBF0`9KXo2!N!WXyT079Cfe zfuou&HX8GalACYV=yE^!?yJ~ z;3E(c4uAl-#A@rN3TQsn1r6(?2A z&CfK8!hDT9(n_v~YPYFTs?BM=*`7>MixulawK`R=P=}T(<#t1;6l^pC7SYib=`z-Y2=B7R-$4RY=WF~K zr|GfCtI+jx4rrPvW1i*B7B*!A)FZRKM`c0uWE@eFs!5edrY60MNdBr0-FBv1BJ($P zDxK=7t-~;xc6p49 zSC~(LqtM|e!G8?1bVrAQW!x;6hfTZ@U{@8a$a-tEUIfmnR?AzO&33z4n`tYBX1U*< zY0ecqrUed0b==P-oekf7vLxiWyiaViDUf9CQUOuUmEqh#w z#VQxO?CHHh-m^lk8c4Kar=xU`=#b;R7*PYE-4;bkSBhi^?`^aT6dF~!w${ZOgzr0@R0>2TKsisI)oZPKeS4=fzkORB zxghJ8%hM?=Bv&eR?A8W_aP-*u`T1V2r(r+Ks;f(#N~^5)>eJ;;eR2|4H*MNfpRa43 zN)NtXvpV%oz1Ql|p)S?+y49=qkfCSwtWKq=HC;-#%B^y3e%PqPKsOCZ?ZWL9@|AOY zlfaDT>=fzLXYKmU?dQP(t#<6%Iv7k$H!GDvKi}k?MYHKRO$QW#I3lS7Qpgh#R6#hj zGR$Cg$)}SjMHMwlk>5T$U6wla?Mw45ZTl>Fq^)`r)!syH(%G;nJ-=}vQH!;D7~BiJ zX>@3-IX%5;piMXOb*a{<5puQT1Lbvs*| zz24+BMg=;#*`Ay3ceb9hVR5>5ey`q`a3<@WLcN}!oWbq&N};^5)Tj6V=ByUzhGvy&-_Cg8#XMhUdvRPO1e3zRA3}%Dt2R{UMrSr6>ms65T3 zm;#kL4%8?lT5Q}nF+t(N3pZ_|FqY(Mg=&Vvh7GDZIjO3!G-WCk5jzMn8NyCj4q$_7 zPf|Ixrtb#>K>$%nP%ct6sS={(UtCY@S)^f2JyWjO_6J7OqtoV+%BD@!F~8hlG@qTP zed9j2jAN9!>WMW*ow1)TlkWgKe9rP&hsdZoTRW5a$$SsvwN5fAWYGcmk70Iyb|Zt0 zb?H{?yguGd&b6`J3n_l=3!N;tIP7;f4~=@iwRO0;zj@f78TNM%dR@$Ql@=Ct z>#dgAYRO7N-bVMjb)!|=fL?Z0w~f2|!_7ngnaBw6gY%PKoJX8)b{7_QyKZauX4qg_ zt#)n0mX?vtjLz$Jtu`)nTCLsv{^s2~TgWBLty;CmVTMB4u^)f zH;yzGwQ(!#b{ki=Zr$42+%o$0Av|d9xB9JNcSwhpjB2>U)({zn?$GVm zXUv%_rMnZ|iPq-DcB|aY_geMLWxMO->#rELJMB(q!_0;A zUw+Ox6u_aLYnCS=C{5-!Z`Sp8Th}{S@FejCn>6x-odz~MluEPHR8F(w`;8kV2}JRr zT%u}HC1l0FxSrUvNW+?Xrd;vepWW8mcA5~`*t&InlbxQ%Xg)hno1lGe8OJDd)e~!M z8;reg$nOI?e9rP&hl*}yb`093b_sY@Z`J$texu*m2>xT3eMh!3sA0a_y>LN>D$}El zGu@NUwjrc-_b)6gE-nm~7wy(Ucl+Yy0)4Hg>WFoUS3{?a%*N?&k%*Et1h$# zO=GdU&|K*DdbqM<$BypujJ?oWgzt8<3*Ck8BI<)fSM568>|%GZyWCyOE@l^6bM{=3 z(u3xp*z3L;%D*Br$ma)nPz2(Lqy^9l4-yu;*e*j}ZD|Wrt**M*T>_m%DXM5w2J)A0UTCTd z-F+7>56sIqlSew+?W5W|s8JS{cNDkn*s4;C4HoT%h3$(&>d?7`jXSp53$wMZ+L>+D z&=#%MY_ry#ne4O|m(@{>AR>bfMSXSnqZxdYii4PPbKWp5L5ppLhQJVtZ;U`m`|B!h*x@?cIrH zw^`YD^(Lb4q$_6CY}TIXl&AVevEMVM>J7|?x!LI%C+V~dY5jRRy>+gF9nadtgraTe!Q!A%d3KRv z3RLPiP`i-b&CZ<^z@eV&)Y>Hq=bmesy`E)~o<23DV1=txBJ8wbRG*mG z(4%rXecz+9R9gX&Le->7D4Kt9J+Wtzh5`9Zxsv;i>>BPmZ7!MGv14s>z5F>w^VxY@ zwN+w>mpsZ`^~4&xHjX{OfIP6n=PaLfsQ6Cd;*GtD-URTf)om@b7TOE#t#~5C9Qfny z4CbrSV6b;d!IqqP+Box)9PPT8t_RmHEiErEE$m!&J4=Jz%R85LE-!6dUb-3pihCP_ z{9w=-4AOm=!#es!xVxY4xP$3!*cF52<9Xb@w7hfKe=0H#2DBZ_PkJ$#(u%!>^UgZ} zYs`V2+aT}^=BKw^*iV>MoTm-9=Vjp>aQN-s<=O!s$QFh78SZgam=di{Y8`Od4B=ZEvd;kHfNeie7_ z@W9n@kbtj!?Y`~XXBRhgJKN8l94f`VxnZ$5EP^5sMKL&urUipbK^`?ddI}l{*Koxp;oGytKH~+p@H8 zxV${Sh*5z~-Z(mc@w}ydSM1umxO~m>U~aZFKUiuF29xt!`7bZtYL@)qaj`d&V>*Xqv`A7F*Brm3b%FA<4r3?{kR?c3e$ zxUij^=EaCc2-~)qCZz}Xb$a?0`>S0FqYZRzt;2>+4L4FLYu(_$+Dz-ubGhvsYxK2* zMnf}38%!)zQ+aNMVhU91IM4zPYCL`6g|o91-tdNtFQz~eHMw4Mwn|~wF2|mqckJPi z_FuwAhQ-y{S$b--+Gvb6P&vJ!@3(JPRS+eDa*e71mASv-7lXd?#4#& zag+-@!%Z_W_QPz8F&pB~hR26H#TSMYOCO9+`~>fv1p*usi4NmJ?A90;J96ULk(Lr>Vn1L5!6Cr?tIAj1ZzROy;rfg1g;%-27;^}~DrZQp4 zOl8B86OZFvQznM5i^Wo=S;i|^c(qC6%4#6Mh>@}sKEggZ8qf#I@R|wZ(AOmxyojhu z;zk}H+X-+R8S?`v;{&NOKa%El@elGG|E7HW15WG%crF_63283Ju*?ze6OZK{ehm$z z{f%Qs#iJ*WFHn17U?E;@LBAcv<7i50ZVK_8p;qJV;y3PWnRM_r2ds(E#QXOjGL+(M zSIN)jm2QASS1ShcT0T%z@&WA1%D?)Ohre~+%D=HwmppI@yWx@#Uh>Fyx3l`npIq|5 zo|SK2@+NkE`^q0#>=*85ue+apWMwyn`&aJ2e`OE*g_S+rCiXgT%(*9;K_$GIsWa2e zfc?u+`Q{88Y)|%jQ|II_&R;OKzjrWj_0&y)x8x5`y{&g={?@7Y^~C8TCw}nN#2k!= zrJ2biC;nkHnJdm5j1KC0vY*rI?RpsPOnsK;C9y7AfH;%BgqqwT+w;F~TV(LfO{-bQXgR76%o@Z0;Q|tg)KlJGA z;R=o4xIEXcj4HQQ0+l1&g(IP^(^`2h2cf5f#eyU3Z;o^ZoeF_{I)QH-x0w-hEAwYy z=_6cn6brQuzfrtJuuH@^VhIqLoGKPt(_+?{-@aVP(FuZySK=F(e7=jHoJrBp6r z+Qqb!h+osa7hpGcY}YdFeu=Qo%c1MuyW= zd>{({@I+Jb?bcpzcBWEgSMGfHZSg0x+4B#+@y0#-@4Ec4gCE=XX7efWnoIARyy)QE zPk#5{Yv20nw;g=#yRUlx^N&lH{J}ki_iuS+f?Lowx4-bZXWw#xyl0QF<5gdD4<3?_ z|0kBp5B|o*Pybi!$?$}D*ZzGsmyheIj~;&2Tc!xS-*VzR;Rk^e3B~|cRGBUt8O86j z?z6eqMDhB~5$+=+0q-N5re!*sVA<0R`5Ep(Ao(>+l6!EJ2-ubtV8P1e3A&!e^%nQw zqveGA4EGVHff-_&`^aO3FU^K2tsyPokul=pH_cpfna9HDM)7A}UmiPtjGENrS)88) zzB@gZ^*ixGwp+_IvJA`#S+-fh*;ENEt$czcSN?A+4c%NDmF1PZ_L;y<$g{P7Rshdc4ZJYC$n_p;z+AN#vM`ubDf{wDiJ zH~!Xp58wEa_Z|MP!{OL}{s;TMkAI(j_!j$(8-MGb8|eq2#ib{H5UQe|vdkpYV;4q$ ze3N#AeuHsS>!ztY^v_QHJrjK({VAP$_tZOk+&kUd^W5V)`%2@gJf~|T{U8(gLgsrq zci26g=H6uA;BaqZ-llVR8}D?uhqW*3+&eRO=eWD$?{vBE=Du0wp40!p;hwU;sdBIF zJ*9K6HLmG$*G#c{y8C+EIo->$+zx%w;oA0Gma90W9LHdNquIiLqQy)5X$>zi=5kNP zoA~luvr-e;nObH(kZ|ru7q57wa=r495|~m(3a9*C`d*VYk8qcbTx( z9!jyPho-N{McBx}{vk}>0QX}r>?brh`ogjOINPq#0;=GM2qekJp!tygY4_o`x%-LdlIZ(RGncf8_}N3Op5 zLpOi;uJ7-@;eCs@|KX9_{`>>#Ko0*Z?Mu?f z?(rUc{Aa|Bm^?Q@AY=El6;2}9>e4r(!kWmkKfM2c?6~Zi+umATD1u*BUhxe3bC&0f}0RIe2|i5e`<4;#!!TtmLkI#JVfx9pJi(ef7-cMHk?@AP< zj{;Y7e}&qc%pIfi5^N&wunzuZ3qApbbk36{ebY4DjC2LHLtknstsaLB~d6&c^? zN+lC&FcOHear|Qh`md5ItA0HkViKQ$_;UX!75WS_l9U<7vaUyqk=VB5h2t2H!{hsh z5HK+D;19^<9qBOLX7($X1yF@>A>@A%O>n`e;z`(SoERC!f3E zlFl5s>$yYksqC<>x*X+hW{+?Oxz_{tCP&uw-1Px&2fKsg*doK(q3e;s3SR$Ss@c)~ z;*XfA9mmkdhXC2Ld2KUSV~;%X1hvvri0%aS0j4}MIU;uGllT=T_z-@7DCkl7GXM$* z^oe@vIg;}+O`Z4`ZVn?T!0i4S6FBjMN7XqFvezi5&V4Yza)Ac}UkPx5H#01RUGOFH z#RLD!aQ}*N{V)m-K6Vr851Hhc=<^auo%?}Q#8c32X%2b#zLiU@(Et7~Jb_~_hP*C? zo&~?AnI|3(=Pc1Za^k0ta=FCso%jbvN01Q&NPMpfhVSI=O57!Uo5#OwPng_R<$Uct zYstAt*{AKZE_AMoT$i|7d7XBh^-AZh+*`tLPTVBi8U9e@0rA`B_qe|f|8?T~cmp^S z45^t^$~YVw<%=`z7|Y-v4{@>kveIFav`6^F(o7Db8^_$2A*sw0u@N0=P-9VZvHK4( z`x(z-#UjSnl?h388BFTot0K~jDPfaQArij$y5}Ey^P@K|9(?{2fBDw;f9>I$Z+`gU zU%&ah{oM0xkX`uFm5;5Q_}{gizTd+;Z(y@UGVhiIT*pl#yJ z;ZZI?I@5K*Tey3<4@ZMv3bHXK9OCfrQ`scPekbnHE>n#dHivudWM~A13ksTFrFMwT zg+?JRWF?+rhwQtcjnXJO)SwC;@-#5$hQz?6ZS80FH}XaLEc`4+YM1-P zbz|^t8*k2jdE0lcB>INv?+ED2F#j^@Z3t}$KOOpd`02>EqThBS=O*_iFXFFD9^h}1 zZ&KbZKO_IM{m;%%?c~=JUsX5N^)0&1}UM}aMQ8lzToVE*LZ3r84TP--AuhaU?A7t zP}cI5K3ZfvQ4%Bj!V)G4{I9*pi+#>0f9fOu_W2LL?HwOwzoz{B&!7L<^5_2GllwA{ zJhFLs^|QbJjeoxOy5Ich-O8W-?T;V1^b5~?`mU>{(UN;k{3xiSB^%81qlpl{*RwTs zM=H2gxv2f-lIOA|M8c9?K{_9 zd*B`St^Dg>|NaT~o#uz{{Oxz#{0a5r+^@a;>UZ3Jd+v#Ez53AuSAMjW`Q7(DyYlZp z0{h}k*q{h`BF?0k7e+n#(&THBA4xu({B|;Qe&GDn2Z8|^V~a_K0}=est3U+bVo9aG z69__S4+c^Um&AV&3Ovm{%|v1Fd1w^J|5!#A<~#A=5$@Wr;{Rlg(%G3fl*UmiGAa~j zBDdyeBlihF%V$UUZwWIDCvrJ1z&*hqVej!;?tkwGvo#v9cZffNVh(GY5U^}T3WjiVk zQDrV!aB*zTQHI7|7?ft&t^^%k3P>#X!13F;kNxI1zxnveEPLf=0#Ckp-e*=m0oJ(x z_;naGgv0sJXTi%q9;LV2Z%yBwen9!0@`uU4PJZ8s#uSsU+ksd+)J{AFb`47w~RL8AA)4V3nPuit2Z*(^s7RUeV)c9n0HhR;(H9zl_IIb z_u{_&FDF04&N2dfKSuH3QT~aS8;{vj$Ky*Qk|te@!%fF9BKO1e zv7fA8cSc){5E_^9xY}cA_7F)YYe%C(rVj8kwD<^+ymImHY9D^xJ05@Jo=fhTc=&zX z-yZ+!uG`=LEE~P?y)XRnarRd6?)QA-lOK6>*Cw6&KVMpT^S+gz{rR`v|L8x^thNKK zsezxuqo7{Ir?{NP*`j@&C0Yg7t z#b*0Fakey(8Ko{raTrPt`}~#Ec3|RIDC2|*88wCZb^tN?iSl95Ydgr8*fzz9_f5u$ zc{A+XD89+K(s-kBixD)AaHYo@tFzg$G4HOjuE(-d`)OkHz>Zip0>P7JFUW0Z4;c)K z_FyEjkCe`05BQj!!+~EsW=@`a-JZ=Czlz)Z%&Q+i{+2(x{U2A3e(c@<`pDlO@9%ow z&Ko}c$+z9~h2U=fV0%Y<<4^wX>Q}D($6wri?AO`t?9J@MzyJ9^c=7M|e_`*DkALVZ zU!ghWDsZhH`W$%n`Vs$)6dS}JhySh%jwHBmb8Ha*mi92ri&X7h9>51UTZkTx{V!%0 zdnJ1%7ubZu8`)bh!CK%w54A`ZJT%<#!m*v=&uF$I>4dOydlzUy)aSape1tus>$M^-;3@?nWp#lRYcpG`CK?R zk=eyxNmzw_iE4;_{sN!P9w&s#KE=*432>RT4xJ{6_Z}zKlTJ3RG?F;!zA=lvG(i%N zodlyXi!u92X7{jXBR4x!CFa5r_BMPj*%KlwEX|dxwwLQ4(Qm$L_uDV%vAw5X|Ky8o z%d)rO_=aXOh9{1hP-1uvcK78}rKf&%6Z+gS|xBSiZNpsJ2Z1it_$ci6X`G27m z{>#c^U;cVv=C_{w#z*fV4&xXY@7X(o6^!2qw5VJ##NglbaN%JvFl56)=n7NJCWgzQ zB|Z^d)n*P6w?LxzrYX-JuaN4E@HMCnfxXW?_u}WEK5)L?3VKe?HW@( zR=!Z*>zRKFZV3J%6J{_;A3`Nqoc zKSq6X1N#Z+wn|7btzJKS-Ms{ArFX4zT#3vPIEHo(4kBJf@A zww0?MV>hwG$5yVTT3-gtPeSL+Fa_rJ(G>XC;cm8XcDPsB*ErmD$*XwoGAI*VkKe*` zjunjr8L=u!Osb}`8B7ab85Q$|{4g8O4)F%+5MQBVuE@M0euZ(cBwmq&%5bnawzzus zR?^5}GY4x9LANI;9F?edumrLn(;tjKp2?b+li1Lg@`EI%@?3<5J^MFoMxQP{J^1un z4u8b_n)M&w{eNJ+Fx``VIxaL4?H#%EqN|Jn!d`>_7p_kR4@SAO!wo#(ys zbt@nA_~eZ%uZa9r=&zV<%q7f!j4lc0#hjkcmuFL5ek*^jxg~#2>6~-7?YW4*smAN& z8e56g)0Nt+-J4q~?=knLFVF9(?KyYvo@>l&%GcK3Y~Pf=q4X~EcKe?6d-8WyEMB~T zX9Bxv!i)>mcH)8rmx$<3bIZ&Uvz>eT@um4dJWFEPJezA=-{2Zgu{)S5_wLT^L>!6s_vw^ zs_s4atnWEz6s@&P)$g|a)9_E@KTSHpAQ%M`k1n5RlnK*M(x4e4jwQ5Ph4Ut;H8}7A z<@umsaNsX=X=uilhQ{&-=^RDJNroR4N+>-{^boUp#byX{lePS?TH%E7t-!AXhdoG$ zqOUa^)qZQ>*BOX`y+_Z*6I!}N+pMM9hs~!yRb5<79;j6Kabt459?SXjoV&Wpi^*13 z*ZKbrH>#2Y>}ZAM_;J(m<157E9!qZEZvF6qyVHh_9kW+3^OE*3JOPLNQc9j(10M(p;%1L~8@W8AS~I zsc9IcKw6rWliU%_h;YQ<%}q@Us%*YK)^)t<7J~W+zK4h%BoK2W;02Qdj0NscD~nqb z)d|XMV7MEvvvW-}gM^BbPJ~DXm~&CNO20UMlt#9{KX1w{%hrx=etmV~VbbmHiU9-r z-1BteOEUAuNYAmABi64@>=X~z9h!XOw&LiK=3DkO6!OEYt|^22&(6NQS!<}6-e=gN zLdM;vwErM31Yb?%4k`^3>9kZx^&;a$aQ*qI&D_$|b=>3Pi~MuOL;POj+s2dJ+0=ig zqU%GdH8qvb(PUY3{J}t9<0!{y=P1uqaeC@v+bY}R{6^E`{_W&hy50JT$<8@AFRH$K z1?D7d$%+%E5k<4&7Bfc#pFPdM`_crRC1M`HMS_4PAm=y|l!)X>n}|VFJ+w?%vbZNx zm8#Dt`EV?TU^JM-T#}-$d@y1gKtciwAA%t>#=uMvVeheSi8sDGpZN5NU8Lu+uSjm! z*NTrlyyMT~XMVqY>z^ns{Q2_hWY!+8llA!Sb z$x6{J*MJ_;;A%*kwYzwYk535^n+Y4YTongK^RYyUtS!0SKa)1LvDZY!(|Bs+8%tau=n7{W(?Vx_&_}DOdWJ{;>7Xi6Nw!+ z740l5?ET}m@Bht;HW2O^tc7!UPCYkHacaag)@_301xDerE=|u#use?`ev7R{JAxk& zl!Hc!>Vkr<qx_CDBTY`rVS#_v0r+UcwjF5TdX+C!46Mm_9cxR&e zrG#-OyA!A!!ZO^6jvJ`tsCTj!!shDD;6|Pd!tYC|SKoPcnTLmV1rh49A?dr*sa>0&rU z{Cd!c!-`FsE)?Q2d2G~BEog;>iBgz1+JI`1sz%W zL3HNY#L3N{B{uDCCAD8}BIKdSuF%cT;Yp7xcp%315p*yX9iL{-WJMR#=@w3xp z-riddK2k8JdGOGsH7hqAPyDC(rgDPjQ-pgKYbRZ$sj19Mg(YuymI!>BPTnk^l&LII zsz=9MDToMDeKP`^RG%a#MryzWmvHrlppgXO;Ak+;F$!Jl+_Cy5IL8R!n=T1tZAI&qf>T7Ya_iwMtd zPRK`WpcbzA3!G>R;=^^g+%v*yJOG#iJaR3~kgWA}O>+?!yE;+K)yD|6*!tQrCarL< zRUnvQk`3_1Z+b?$XYg*ne8qvAWmqdHqAO*}eUa zp7ZYF|8d20@V#l@u-SyP6o;|dB+HaSKD|6H=_;dgsisWsE05-v^PlqCh4Sb8=Q5uq zt`_bWUl4whL|GuE!fAnFyUr*&Td0H&vJJ#Qt09hXXZx8}yq7xm0^6sCO0YlLYICvA zzfrn*a3v%(N+=rN4b+Niypk;Pf)EsCG(N;T5Re86jRqlhkqU%r^%5t^Jk`TCIY=uN zGr}61#ogjj@eE)z10?pDzCcTYP*rwoc_^~W;UW(P@sRa~uG>|;1@?FobX34>u#^xO ztj31DuzH!!!oupApDV>zn;99J=Bf_Mm!OTuOJu1;r6(556yqLub-UoBWnKw!BHx+5gdEJC$Q3IFLa_=(PGYw5LHfL6 z(oztw`uv*f#Mk%rNe-SQ%8(OR`2z^^pF1&78#qp5#`jss0%ZwD&60!qBw?Xpx#1lH zuQT*F^f&X_LfDvV8pDqh78-9etuRV@DoSxfrtgn&(&u!bGDE1jPoiS>yqg+}>(syv4&p zvh`JNFc(!<#j&^Z&DnZruAl%$4_E)gW>+=X6?dwDIqa~wuBoc8a)$QH2wI(nE`M6p zR0r-hfJCxX5;3;_XOBr{`fG<5|J43a+>{$qJ^A~~AMvKJD<<$LgT#V)j)v zfVfi1%1H>kj${z)29im}6}UWb+Y|AX#Hd|~G2-FN|9G%p?GyZ!U;7B}UoI8STn;i? zfLl@wVD5C>PkU^7#%xQ$Y$aw7XeBHp3Fa#==>$r3T1nu8@VwLq^&|)ju|Ypa->et) z5(K{*Of=w3m2hM>f?#ejl{YsrxLJ}ptL7YZdI5MdHb5kX=iMtQed1sPNB8%MOG;7l zuqdv@5@9;xeh&_dl85ZmjAVFOpApxZ9C+E;`-}VSI803*rsB}a4*#>KbIo+DK2<2z zVYv_{7>M=Bw|RQ_?JEfk&)vcj3{CUpW@vg7p#yv^p5jbEdM!~Jyk>$vrngKy+79_>FjcYE*lSW0?-+56ZnR~jb%K3t$^`c)?`Yqul#SHlN#l82 znqKFOFtm=h83-P8gpHNQf4y1@1p!Wx>w?BmYV8(gzA_b0mDuGLc>RF%pipbMiDV@y zd!O`qac^S(YbO$ix4%PDKmC&U7XA3(?-QTW_sC50)Um{KUwxa{yzd<{_IHVYCr*$O z;%g=PhZEm1PYQHep$+qI1OjBVQaaf>-9ZOh20F%B#yJGNAq`8AOK~&RkCSW>$s6<% z{CM5Q4j$pT#v_JUn(ATPbZT2kG2CIxsQ5jK%7jo^Rp=hmP-*rz?$k617c`30-SFtLkGBQXUl+r&^FOJL@6PYb8=5H5Q^Q*=6+~fSS+>87t z+$XN@xbITFb9?<_jLQ+bibB2kko(cdClMj+%88V?;*tLD{{G&9-WdZUqogs`k5;{eHU2e`FWp~7Jn)*IYVpOf5>6@Id~wRVvUqJ)#O;E+6vn7m zr0fkRqGqC*r&4B`R_Be_2T*S?r#Xk_gd$j0dQbL$lLO)pj2u)er$a?diF4Ls%e$(- z5>^j9mS6!*bHfae71dm))G?C5r)3?qVr7I=9*GM7S}`~N^ix~kd^>Su*KX4LT}D5% z+P>dD^F@%&=ZQZN-&a$|kDL5deQZU1@wlU8{1=~-NrzugJom-E#J3OR*FQ<(K)pVk z_%wk(PW(RF)q~mD0zLvG6I7H=1}SEn-b8F={;`26(#(KhJJ|lGR-3m3`wOk<(GqyU z|J0fqEwOa$%^iFE{jid-eC&v)?Q8a1b^P@DB(M*N^wl^v~7ZW?E!kCa*L< zX53*uXg+89fpxhy1g&U7g37;UgU;roA+Jl;z(;O0h;H=fO!0b9DxM3as}#)|iJGLe zi0Mg9eK2!QW^*Q=neOhO>N{0Mjf_W(=PZ%*J;P6j?TId&4-MUOq$6@!)4}@j9%g1`D25lGDe1H=%*Q{o2ED> zyBFziH{Nc()3P9QUU)fwzy3bs{pJTO%QEi`KV*E={HQZ6oM|%ZMHFLB^GRBbz*7wg zXQtybn0dauwcs)5U0j}p1W7GvAaj7}(?HAJt%Ok^!o`bec{*RjJ3trVvPrhLC={`g z2m+;yqZW3WT+EC3U%mncH^A#61DnBb0E?@`<)Q{y06R#dswxaOrd4b19#>ObJUy%HzJ&`; z%$xrso&mY+!eOi?Ems2=9ZkdVz}VG@0wQ?xT2)nzkOP_^q4_LoN60>+s%-4H(*BJ} zXA`r50rIZ@o~bBFuB;}GAZQ67n>~>#+@J7?#+^HV{U?WOZh_2W7Mg==Qsjtvj4(!e zR}x%IB|s)-Nr})^>LU!07Miz-=ge9IN3G0T?APcV5n3N~k)W&AMH^gmT+J@tWmK(S zcCHTR%JojB5nwUJ>X{h~6C^3-RNy352|x!O;!U+e)M&9)XgD@0arxBm6Ti+m)_3Qf zr}vA8uk86cab@coV*HV>xzh65zMGG!s4{3ToY)8VE_44<`sIrxhs)x_a=xL!&|tVv zx=**xaMWOp+l~0)i;27FdedqA*R^N z&0;#>A70OScs+mP>rCp24(Ng{Xjgu){qHS08ysVQZ-FX(u>Eh)7xAwSRz((6#xhl9 z1lUHkD(ayG)`#HoR5ie2LVL8m^9OQgmq2mI|6wvMrlc3U<`8_bj!pnz+%7%Le)&2&aI z>oqt~4FTwUu zqp6qGfMUt$yJbPwMV&!%J4G}4z;aY{8bscWzO1Yp6`+iiHI0K`6+MN#mL57XltULJ zY@K*12r~`c9}L1#=KIaum4=Nmwy>bZ2jusaf9qBT{Yh>uq!89sGfyTJCIfE4fuq zBSN+|OP^zk*vf=TsZ!6rv7axF~T0oz-`yV9q^XVT}U)3zUkbJ97}_qJS6olZx<_jn#%8trD}LlM?cowXdr zvr(g-H=xY~(O9TmC!@Y=GNp(AHY zKqW6`9W%;GZdZu^MM?}pgnwo;qn;{BC8DdlBr&O41K42FwvREZ=n$u8egIFLFy+AQ zi$gj32KuEvxr1Be+HZ4II zwQ4%}xPg@Hhf9eUy5iw}Xtkv<_sQ+5QpDBHCAfO(2i4DXk z<;eLaVJexbnX3OrBQWyOpzEGSqto!ZAexfMvK|pG9Xz%KoS$e6dJTbyCHjNZqv()w z2a@3=(?RN1bOzlpMQ(!delUi;650+5hubd#G`-p5~@qi47MTbwW+Yuu5IuCm4s@0-*6-G|EcW&oyiYQ^tt1X zdF#loE3Iu0v++jtZDBXKgMs^gj}5E-s8R{ca6i&l>ZjvnNw1?X3K$py2$d{I=n?>j zT$W6JfoD5N1h95N&eHo!2-{$WK5NAuH};ugXP@E}F-@zXdN~biPkx2$!zBfbqL0%S zND4&i07Es59mpqina$H-I{XbHgJThzz_@K;R$<6Ev^c_rgzz&@%Z$OI^)Di}4G zvC5FiTyRo2!?1P~9Ze6#i95vB#y9)mN5FuwQK~C0Me+)u4NjsBIkV}{wf(OAUhrOd zw~pVwmw$26fSo(9Xm4RYtyPIe>c+@0#7jWnV}x2nO^nmpKp9%i%YqnI6|R@0r=}*g zEu;!`y zh%v3k!qXT>Y#LD{^ksn$Yq^(nPq5@NHQC`ePe4MY@RF2<$lk=f&p#&*BpTOiqU-Sl zWweD~1&cw$-2`wD$i|6hfUhz_v!TdSEFY0*s-Uk=R#GVNIUImONLrODgs=D+^efV+ zm5z`iE<|1NmZrW-Z^ZEjD-bALWWZhDYR-1l!>I&|e* zIuaw<{>MZkl-R#un7r_00)*rhk?_#72cx16fJ>L4Ab zSfUC8eFq~2kzElnQW#g|O&WlN@uP9NIZom!C?lJn`I_d0h6Xg%8mcL*fD;g|a~5=n zvD~z(w(q`U{tRGklK^o1wh7Xa2}p#rl6WU9Vy-EP^S4}!JZP$^$^ZJ!e|Kb)>+{Y7=l5$ESJUlQ%;0j&AoG{9?32^VOGGr7GsRM|wC8Zs2@yz!gu~D$T}#y}^dKo>n&xs%NaHBB zmK7Hv9l0zg9~4JZo$Hr5NG(;+M2cR z%}e~8IQFQ7&o(bH^Jb(jyrA@F z3DdP)1KHcCC60`j_}T<`ndy#XAD%;b;9hc^K&nrpR4*~5$gdm+yeJO{aH3tO!EQM0B!*I zVv~5Jt3CoYSbWu<)SqAeBJuCJKi;?VtH3VLlCdjacy{TuHDp=JffFQ^$S)Ck_pU9z z=`-H=`1G-RKv{h-O5cLA7y{+A@}f)yW7t??>}3>79i{%!bc8(2G2DL(og_}yO>{K) zj|NVOpV+_ld}sg8@pH;wJm0AlgeJ=|FC)8wUPglm>t-6exGHI>aUkt&?BnR~A1#kE z-eUYt^MmVGa?xZVPTr&k_`-(~v!ccTR=vBJaAB)CY_XiQ5(|K;4c2C>V4ZKvd=03c zZ?)}OfsI`a!eySclG+Z!0+b7YX;`^!RfxEsM=TbvYox^%b*L2Mbq&A;GE<>g9i+uq zOg_HklLgaG-P`bJersFsr3DM0+rId=Ez6%?eR=C9!rwo%2Q?vdYy056*Wdc$gX0*p zfmn@cpe!fG>>FiLfb%=)NWNaI*NxOq=BJCZb(8gy1%W9GjoLmJe|22)Y71?ZoAS|u~5QtLqDR> zg5#@Ch>2V|C$}t{xVr5NI@C}x>b^U6kWndH_mTj3fq`TtzDfLI3GO;Pm8@UhbLuuG z73~mD&5-CRT&se%=fv#E_Y`=LQs{ZY@T75vQSutIjJrKYJ%WclU6wack}4T_gV`?= zCyhDm08i;7K*>5>YpdIHgdFBV+$AEb(jUT- zsmLk{^*l@|rZTfEE5K1zJcPr7Ah%W{L8MsV)a9%ivyT7=qZSYVVa;V)N-;xVf^ET9 z$6R$zmc`PtX_MW1@4`XjeHBH+dYw4IKfbzYdP$$rwx{Gi4L7g8G6ghrLt-fZ6KIGb z#4jifdcEk#)rTE}^t~M#9XieD>LZTajJUqcF+ktPF-ki|KUM#${4b}eOGa+Adq(%@ zpy;~X&AHk#6kn~*?W6A#>YY6zG$OlEJ25mdyCJtZ_lxMc(BCqCj#^V(8s|Z}XK$9@ zu2nghB?wm^<6q6(Q51e))ODxQL-hO2a_@9B(sMbB!^Lvg?LL`8EGbG#LrODpGv=E~ zm`e|2zGgmQ{?^=X76RsKa}Bs6`V-F&u>}b$wZ4gIB#g~7C*UPG0M9e2%hFuVCKHwc zmugC3@F7)pvd{s8gRl{V)|W&AT#wYBvP)mobN-zx-6pbd_m>xDee}SQ+qX^ra`W$g z+PLk`JGSq<{kH96yhFo9lg5_sUPY?D-ayFe4b4}k{pZAOFY-Ab9ewSCH{N;!v%dm~ z5DZ=9;PxCsx+YSeoGB$?p_K2w=5Uacy?(cD1_%7j=Y_(MTu$_yVp6Z_!D}27w#m?2Dmc8c9c7 zGKN87Ihu@9fl)E@OeHsy#-t6KGzK3rN+2}UW?reJnG`12;48MZTspale>T7iCbena% zbw_pI>MrQCoGzf7gQ_>1IzBq1YuCvE6NDks)h7g&M0NRgq`ou#igA(-bUPUD%DsE{3V%6q;<8hST>b)! zzx^3xh*zrjXyZ02gJI!_U4>$CxhSScqNo*s^cL+LG3qHCE6BjrYuSD2HCn&bybkLg zeih`yg=Kl2o&@yO`Wij2_t+gfL+qYZf>g0jLoCc4*Thv1R>N8h^OS^oGDlo-@d}Fs z#UB_blVmYRBn$GT*W1s;5{Bs$IS}F*Us`P+qpTxW{Atg&#lq z=$FMCP5mDd#$VoieDEa3-7xUgv9pW-DAKa#&yrZ!E`t~wGf zwA!M~v2bB8_BNn0@IgrZKv{}UGyrdk znhIUDvBp>@)M>_O>vVSti^Pq(w={ncPHWC;e$@V3^NZxP$v~~}0%Z^uAXsD(p3ZO* zxB@UsI0O1AyxT}GXrmLt)a9ZZ7f_O&U3WhXGB2*D9YJ~{QfKh-R%h_VJS#2L?E&W0e01SrGZZ>q=xcaTx|DEi$z7YV5hz_sJlJ- zGA)9F8h=gKJ%CakG>Ey2qFNbD*V|Kcq>8y};`p9fn?wV*Cs>~Ry&!{fmAY3S;zS4~RIE`!T_vT-eL-PzpR7@J zR0)GCnE{R1Bz`LjHP~Db`G7bFD3Nv%RjXJ&f0EI#Z(?Fj@j?P^;>b~`p|BG>xsK4e zCL!h2RmoOj(_H3{P#Ma-u+UZCJUF8!0!fs?y>$q=&7Ubf^hR*Tv%*>3A5*>yil2y= zf;2@6X6W3$Al#Z6X?~5fVG|z+^H6^I#Un0NGrJ zRx}|R5OEl+K4LREud+*~wXmmiGLa0=Ha1C~sS4-ox#yOmZPOM$7P#xZr(bBz7~g%) zBYVe88gzH15LrKD!p&n2@7muMrBBV6P`Uouw#R78ZMW4v{$ShZm{BH2zQ<^}xDOP& z$ZPC$yXBze&-@Se3;ZR!25zVeN+AYtk%erqoOGXYx4VU)SL$tAwBqfn=_ifS z)JeB!8YQX3QfaGnmAZRd2HFO?db`Jq<8{L<^|pG~F!xMxrf!mDrfsHclKWQT)M-TH zIDUjULLO(B!A}+^%QMiQ+b?LXAUQ{-iUCH6s1ktZIITq+gf&q3Eh99Hpob~HI5uT+ z3jTx<8s!STB~W}ZRI&3=dI5F8fofY}JuvHlEq~o`ak%bg@n)TXHEvh4N0D2rYQER& zBE6oy@69iXYw=%JeVaIcsAa|Smeyq}TBw~w*DOr@vF*dZ+(Xic@q_n2_~^~|-@~O> zz)uvyxY(fOolu@LSn@30ECVe)!?8UU$7UsDBX|4xgt`ik}@Edy_nhK*R zwa|bH`{0`FR~H$=(yW{Ws%0Umk_kvvL0R!^!@5?^&%FMBT^jCtQg`$S(uT65Yd%_p|+H9s1Da$B-#x*-NA zR;i&s?PC~A8|mkUFWrB3{pk7LcZHgftLyN>?lfr}FsC?Eim8}mR;QU*%!;|e+-w%i z^R55G>P$`hFFiM@}(v2yn+UGwe4 zB9IKBMCd6D7p4gF1&z)s=_H-eZq*q%RL9Y)WWdR~taZp^NDtbHou*s=f3;Lw-wuBS zqy@YU7w0nkI-7KsoTsWv$W>(3+L#++E<^t%nQYST0f5`O?3wP3)#GkNS=O#MI?{y5 zmZpA{&qw=KH_UB2#qPfvo`yZR{{r&4vRFuWq*v+&=z3+2N}rs5hi;8-Y34Tji@C>m zqYf?YQwj#=o=y>cbR?ygA|kuTOXGFpkFQhcNn%tpUrBGycuz&LMu>gY4NdAG;ELs zZ!qE%^j%WD%)&;e?P^brXM$&!=Y&UNM%(S#o^L%uz_ZpvJ+Hv|>%<(qpja#n32GrH zp(UvvS}>nhhpR+QDoHb;WF+Y_K6OSaP4zpqg1?JC09;9?N3pw0Jn(6@Xftzg#sPo) zWDd#k7BSWpfi>SybhL<87d02rB9w6=nOrc_oc?X6a#hIq7()g%0iIkMWG^7V~|J@3^fr{P0^FYkE}VJUIN$SI1g+8|F3MG0o-5 z_bq+xu~Ch0-Ff13(#=18?&MzGGTh;!{&x@QyC^FV>$mt8_ptH9$}{|_b~&@S#~tIx zZW{d(qqNNSf6yFpBfJXDhd3E?lM!Lc^iib;4w^l%a12J7@SMw{iH7M3OSlWQidRFAMp~VVt6lj=^XE7?{06qSMb8VRe!^@3sz$& zs5_}UgF>W3JXaM+$juJz0-S+8C9)k%)c%W1yT)H(5)XFy~I26}Gy(*E|2FR74TCvAsRQLFc&lFu+ zsD#VH2Jg-(I%wOR3md%qLfMzqrGyJ&V>V=SS;%CFbER@WuCF`_NsV>V7~K>yg*Hl! zy4yIw4(KB3Hr=iA3Pfd=^Y>|2O84uY;x_0WlwabWkzeHwX!pqPa&O9CaG%J3<^C*R z<}S*)ND7eMoJ-E)SZa9<2g^oOY_1YffubnG$O`LZhfXKMc?Ek)#jc3RBw%?3EKICL zV3;FfK9U^MB}Gw^m1>D^p8~T0xg*4f{8p-vbp20%U}Op8cpD%BUibO4^~?mv4|Kw$ z@nuyluWLXPaB~LezlI%zb)W)!R9pxEA>`%6jNhFNBjoefLy1{Jq;2UfvqvnXE1C74 zjGQ09jM(TNBwsp6j*uPPB$)`_+@)p+SNHJ3hSE{X)x|(|NeKm@9uryHL)7;lOz&6f2%r+f$ zNp7(%(%i0{FCEexHt)CnOLJM5rMG5rS;nX-%N(`kJ1V$x+pW@aX#@Y5;d!#1Zr8)J z&+XS7HoXI@_;cMk;hgyg+eOWgvI{pNJWQQQnRf~P_}`+(_2K+ zpxT4T8X(W_BbV%#z>6RjJcChq(G8shKa2qC-TxbX)IkxD>Y$7N2k?;==n?i}(Qft{ zxH~X>%w7Opg7gSVR1myO?I-tg1?C{IB425-_7MA`{bsc4H6V?m{bY-_fPG^NS3y}Z3|y)6%hhjV=cTCU zSpgW5gF=v1!Kwq}g-*}D?9_f+oXf=veuF)BX2jPeEnqc&Aq4P~3VO1qsK_Ti%9DYK zR}Sx}7K(Qq+Em(Y|E|Q|S9WB73Zj4Fto1!Qt8K&kAJQq8zo2*QyK(~5Zw5d5JE-46 zZarYO5i`R5%u}HtcVMjfQQ=VuDX8Y7;!({}?fYh(S#ia^yj|xsdM%}-QhzsDqnGk+ zqlG$coqmkzF|tA4pg%wl8s5>rXZpbM1^fRfOZjbW0^ zW}~GOkYtfHsH!4c-s0ZUQAu$XhZg(y--fvxP zTW!D3u|eLhKVo^sdf4%k{Db3P#x~0@j&^?oB2$AP}PHratUW&;>TST8$J zof&{f17JeD-(%+d7C+7Rzvid@gS2{|*{;|W$3Z$m(O26P8=YW#4T(qx$qoC>B%SN+ z1M?W6*vvt_q6C3RtugSmhISQyc0+4E;*@+{w6O$v%qq)|cUvx=^{|qA z=e>YMs7J^ywRa5m3bSf{5j z&nB``F`~@ZyArjLq9nZQ_s9uMDIwjV8-V8=QwHE5n`Y_qEr1rt{Yf9%N9wPuv5Y4p z=m=@7uGTVxOr#TGf-ENUrNz2cWEqgYzmSWp;75dHOEFzsdQSS3Xc_e$usBO7I1r@Y zDJ2S3oL1^&3fF6xP~ey-VU-c+O$;KVk#90`#+XS4zRSE9LPA6>gmFqPr%g9*22{zU zm>NvYrVA#~G@q02B4igwYEaO#ow?G?miZyJM6Wu$lMxs=)7Yf7L20Y9d@Eo*a0>?Y>d=DBu#ZHEQ~StZ(7VM z+$p&`cL2aZ$>rqtYOhp=?h2rO7Z2KXl3N(oSX^BhNWC%Y)%J;3iQr?VD>Wj zToR0g41d^C=aWt}HaMsb*qz!?|De1KO)6NZ4|P3~^`)3H%RYj|Ls2z6KKLd;yLE;A zDk7sQ0#keGZKLaFO%$Xa69N@C=PDySGZfmndzC$9Nx9`|GWGsih5+J@AVR`A1@K%EDxH$M6qKJ6w@`Yu!YLPovA9KG^@f;r z$if|f1EGTgtGWs|jrGV=sN!2vRbyV8InrLO#%S5Quyv)^-W)O2@?h`2b z%I@LXh%y=k5vm@yeGo0_tjzq zM$a-e`E9it$~Wbk6- zJtVSUuTh$4-iNnkl%(2*bUjs7=ATy1wYMiLu4w*9BU~mXU(2l_-BCLzqyRzZP+;si z43qlBfDLmUrXkGEq-AP|sS0iR#6q+o3UUm$S(VuS=F_2l}d()RXb#RhFI&IO0X zl^!4?$TTiXL5)8%IcdINruk+RnnbC|1izP^Z9c?qnq9p<`3-6wsOB=hp-}yXPs#Iu z*Ox0^a>m#0qqBXxe6+@wd^5qf&PRR1!Nl$AcX_TK0DN6j6B~nM4y8JN=%1>N-`f~J zzhdI)t{@5W$8OHECU}U44ZO!X3y(mlzw=Z!gg944 z*NMmQ484-0!2KN~=u=EIziV|@+SQMNqonI0nx1_0Ru)vwscfzk)>Uq<++BI5@=idgL0)z5c+$CupKc$zduujU?s9<+x)NwGaTPfU(@ zZDKYWF{Ey@9xXo{|ELSH7QG{N!hUJKGodm-u-b!b#4t{%9PxY=Nd#DP)vEsSS0Wv2*0?E?@*G_Lz zpZd4wpJw%wxhN`N2bHd+K_#!K#2nldq+BpVmN9FYonL_9-F5fPW-WQ&Yt(N@(s(*a zmy zfis`D?mK$E$EoXGRPYU=g0oqV}O*TUOP*ji{GBrQ(Xt3 z1~nq3QiG4oK~O4ry6@WQNox4*`KP%vxGGj4^|PhB$xk?cfYX8wf}N+%z3zV5=p^rV zjd~`=2P|FyuL7&TM!M>nOWNOUPBhyR}05zM% zD|8*QGP)b)Krv92AJtNVKAGIJfUK&ASE)6(m=y)J`?~7>ka&GNuL4lty9f#-Ulg(t9O9@uBr5Y4>?9Kj2SM|jEo z)FRb64b&A2bYcrN@Vb5|<=2JjnzzoK|IF5TbGOc%*r)fziM{(w6n;1FnP=wB+xpD> zJ`*SQ!3%dWJ#mX5i-!R&$RU%IbxxndPs>QXFvc>~Jk>olbenmee?jVf**iktlXK>C zzW)S&3H>L-+Rrl}wSRD`XKL!y9L)gTz+j_!dT^0>8~2=bNA`}K?@e;=v?=1`G(J^= zL&J@x!r2~=3B*qb4;P#d#fZGdoKV2$HXGoXjv}c82RT|kkjC*LjnAFo@fz`Sklv`E z@s-15@}Me*&FF~&Y-5s*UXKffRbEgc8jZp2;X=h3ewWs*HRyT2tT&l7nObjdG&5kU zhTZImeSeq~z_ssRrfSiHSq86KRRI3(Y9J(G=H_3Er!e1{H7>EV8dy@y23B)>RcEV; zQ2@e)L0OJ7PzyT}lO7M&6zG*H_7ol{bY$E!osyLyOrht#3Hhf!W^E1qdwXHo!a4KiJ+$D*MVU&|tT_{> zId^$?2W`XF_Eoy_cePR7nr6qLQ>Mg%AX!sR$m=cb%@Vmcn7A|c;7s3~Mt~+<6Wrrq^)%Kck|g<(M%ydC(iM_Sb>@ynVI1<)Mn?R zP~6kH6h$W#&Mu^d2?aG5v%3(~A5SllnF<9D)B4tY7Obbpc5_(LtS_3<9C}oE9J@bF zUvwjY`v=Kdw9K*=z}@NXO6YUxH!^`TxZ=jwa!%y@oWtkL4Mf7xwC=kgUppg?dy0OH78)4{?Wc4rfqEU?w6kNrJu~_wact+U_VimIgu=Vg?jg2K!02mUYo*+wE zt@F-C81$Q}-svE#N!P?#`|t@hJ%&$xsoQ{s zmE$KD<-~j+rse1N+uE~t!*c8K$3wQq@7TTXFTPgu`l+)Y=CdEk%^iJgvdfcQ@m$m` ziPajZD7Lfo%{ASsADMGY;mHN{Z}0WpcK_PRv#|&6_#uEhDdjMvnH?C7gpZIC%zU)ADpi^8|%h5Wmf$9RC(W?{d4Bj)=WAw z^R+XyctHP>(wFY*Ikb0|E?buO@!r!owNG(u;0xn!Sv{!X$w04pJ(`cS?6BY7FtMs6 zx7UV-ysGAbO|@O}yREJr^VIOy$l1u`f_QcHv=L=p##dCw;}dGw8k$K?(y9FW;N1ac zw+~lLI?V?Rc}uwkhS68M1m*vRJI`D{wQ>FW#;NP+?;9U^q!GvLy9kgZ!@+^gsQ7EF zk!$odrW!K}r4aLB@)Ji$qY~2UOc|1vGa52v{ah>gC0S+LY>~WH!DC_VPSoTi&_AXF zM!8xW2aDi5i}7OunmA%jjyKC6WBTgf)%nuFPa@&W4A%R{h6?@8SZ-by14@TVQV!*d3pE9rd@e6H8jkpVsVJ(U zmy4ld7x_h~`)++1C+GX6XPr5j5CnOO)9HH`N|WDTnx4ry8=P~T%}xR0vYTSyN>Q0Q z9K@|ZRDKXKTm}mQYfza%Jw^ew<(Vn3mdS*_vjcC&>NRw>3cA{Kqr>@`jEW@No|P1o zxI!pf6bYuJBa-g%`?yrU*H%|^ zHy*Ew*6tpY-hIN-udakR0GQz>63=0t&0K&h;}mkQQues*5!WN$$J4&FopPP>ewik{ zmU}3VMxxny*#)t}=lSjW9mf5!w_>Mb@?@!?Fn?11{Ct`ZJFqp9SCW5_-mC<=>*oI$^PWES|Q`(kq|}$p2Uq^MVts zAhm&ERd>`A33rRw!lnp?RCGn;uqNUSchBgWOHd*v#03ayYNqIL_$t7 zr1ID}_3jYo6R}Y}t&BGQ>mMT!CZ?_{&BRKMrd%yTT$E{JMTwzaGPpSFR{{b`$zbHd zs<)`@m3i0brQeZh@4cPac>H)`<2&z@X}{Z)`1pnAN$%FIBzN16#2*p>4XkY*w4^cS zE$lmSbH9-#nY{;ZnmatJZ^L@=<2MrP-+Uvn;qAA{)HmKF)8DvrYvQA4woC0Ni3CjAU_;i_RjubpdUu+Gn$OP@Y*jj)N1Fz5qG@+>gZCGkDk!&?Pb4ljU znL_3xQW0iW(Q`0k+GBj|5$?a~gArd#myhv%H@AjX3Z;xNqI6OxVN`VxM%Vv?Fs{)A zV;XoNb4#u3g2XInbt8()!#N~?Vh6vO`Qn_?09PKy=6_9pNmfySltn7g5b=M|KyvE; zPZ|Ib{NE_Rt|~59OUZOj4&Iu!pl06s2j+}j`TsEO zZI;YC*PnfF=^GQ5%uF3n^X$frPfcZZ%pd70&A%bPwD8kBsRZivByKIW4Y2mH33{u| zY(k?q#@GcU^iT(I=8Y{n02?rove6*x1kPx(nAnmwlddh+mu!bgSI)tfy@bj%VvG13 z^!%F@6Zaeq@&$YY+U0qipC2O0R>tr~w_RkFIxk&fB`BFWrY8D81H^*HDo(Hi!L?-##<2*}iFXaU9qnZNsxUHo}cs~X&P5#by-_}T5^A1DO($$zu#uV1lj-^4jK z+TDapbe8xA?m)}+Q!)T6(N+Q9fc^<0GCP2qtr9lzYO6I?7IZTwA^|9~RhrYGO%HCn z)TXM)$-x5fnkfh@1)>TNiZ)_^?n0`m9(53ay|SRg)YNrxr6-upO3A4Bk?_%bbBJ5 zMvpIlgLo59E+Su(Es37w)$PQ&ofY`rp7_glHV*_#PN1kG7R;P4SF-G8KB;3oH`($_oEKiWHMm~MP%SY$+(M$^4qGZw+U{8HaC|0}*L z+^-Rr-mi`5qkN^%tzZBdAoNe|9qbn!m^Y3a$JhBs2J1rOqQkPs=1nJ!^!9>PbXj;+ z^cmen;ud(l-GMURf)Lc_0mGOl*!XA`=!$aw2*`-!WJSV4sy|vFq~~8d&J7^HvH;Lr z`~_<>(Bk29*-o!R4FTjh)4cqM)*CD$MOIdb-a-l$eR?E_YA&eu)maw24Y~uXK$z4R z+L(%%jEi@07Piw`OpNJt>_A;ALM00kaYx*bDhzN?ezVVpLz@~Rtz&*RmhD@f!UTA- z2qR>;Hmb(QSc!3$YIkxBN{1Gx_#?GEqwuHg6L*hF%i5nfaOnOyqvqk=%{S~Nz29E` zu5jZ66TVFR$z>_#tJ*w+dyJg;1@Vg|M@GEW+;G>Ee@txN8%-N|WW<~6KYrv-^wo)9S^u9H}c+~Z`am?k)YNn~-G-zzs{dcxjtq-$2!!a-Ss z3MYCeMizJ%M3#D&MvT2Ak2WtFbeQ!ST&fTSj6n$Isk?%loRkWoAjevfnxj8RjwsfQ z96=Mz(Rz#XavYwbr{Tte9ogxLQF}H(3MbP*SUtk4=vD@DRfTX-EI%#X=0Zi@NX(TN zK$YrXfaKe7lqTaS*O?O_Ax%brbg>r%xPX)zNUB*$2@CC;3Dz>zu1~`MnN11B8{U`V zA|T?D<|%wHFh4uYetbmtG#@U zd3(ku;YCTe8uMAy;HaQKe2s9f+;J@Y-X z+8|tYK05%Q8+JE71LvH zsC2eaajjt;XJDNH8>>M+nSn}L02p7TF9G@XKl;yjJNnN|fb+BxEocfLagZyf?}(!! zU=5cIc=UfYWx0f#R@oHfb26+-ST`CiZg_Aun>ldR3VL;F*P#Ru3K)4q*FQOC=>mZ}RgsyGjgF^BR>mj2H@>;nPEo1<*OIP%0 zPK~ek8j?57GTN$e*X*9#+}`sZucc#$HaeC|UM6F%zx$5PGCb~HaCdf>Nj^Zb#Z1?| zi78j!c^>)$ivSBVAvL_*7fN}igaQKQm~D}?&~~4+%qGn@E;UlHG}JoNi7=9pO$0t? zG--_WThO|O9O2+*ldz|NSadh|FzOV5I^j{6$E(`*@V}~#I$!vdZ90+E3utU zOvn34WuGk;`rIN7k-NyuviE&B!156*wOcw?UblC1ix~Tpk0j2gbl-)==5u*XoTXTI>OM)7#){_R-zG zqdt1lcLrf+Gk~7PGbVD>bkamQQ_!><|I-j(Hp(AwYo0vQJK$8du^pQnvVAT-{e;pjsq@yMZI^&QRR`fZ3I`0aUrXrNB4!~&WnG3cuKE?UZ73}+nF!6(XosSbzfm|$E0IOnr08{=J`d#>i8Kl|*^2i-o&(X(A~ksM z`im;>tooj5P}nf_uoL#i4pe9(lwuGpVTuzvN39Y*xspjIwB0ILE?ek~w&%o;pS|+S zmG`#1!aI0@J;fG0#Xs>BTCTg2&eosSB!HizX|iw_F^|J^h7RkV(;U_=l$i9xov_Ll zR}1H3k->CfJlxJoZsWB@9QN9kF0YFp|K~2vsb5sjJwju`Bq55C>Y=1*v{WBMa1}Ka zp-A(>L&R$Y1C(_SAy@a(A^K=X5h3OcWDbxHuOL$z*^H}|q|^&pGlWUcyqXwwWRnnm z`pT{ReeA{b+xARapzVvE_s=PgVkr{^0*q!|N^XwJAs8|(*=R!c|FQSp0a8?Hzi^#X zRbAcF(`mYUI!sT;2}~X)G6ANPAUQ{20D&PRNf60d1eGk92(GSKau9Vv%pmH%BD%UR zu8VP()xFEAgs!>2bE+qZ`rh~6@81umtE;=~7*b$H#b+&=?bn z(<2Vu8QE?80Y?gz)3QV$Y*IsZAg6>lWM_%c#-CLJvvfEQF#~smpkRI~%bZT^?u>l7 zK#j}vA!18$yKqEm-stsRKAXPfFy*9;Dk$kuo*m2aI2;~Rrrp@TqHo!arP*z&U5->! zrg)G#?{B!_hK_BDsxn;ZvD^vT_{NU$AGJSC?AWQipaPPs+}=2>QlW@`OW(oR$G|bI z!%;P8&dSI&XQdQGBDCNbT?kY0&|#lDyDpW$wC5J9Q*ETU?IvbvLI4I(6taHAN8zO<6FyxNAFyIVsg@=u#ZJp*A|~_Vyia z|Gxd|k~SpYnu;|vE2p}5m5Xsb1@r=aiO+J6(D6W#kEFbWjxh)Z5)zWpAAZ5$5{NrT zob;U!dfcUO%ChB{CV3MJ7FzrR)~h;*wC#|pGZ~3K&WwNaFdSWdWV6VejYp2I-+1)M z#(rZP`t%*wAiw|S-aT)=y651Vt7a`*JZH{|`M0t8x&*j@ugK?NcX(ONtg==4JB!_I z-ThrM5$?({iHvtFB=h~ZWv=zD%(B%`Qpm(qUDX_un3r0UN-twjs-4v-dD%7D^sem7 z*)+R4w^|TVf-ZMXn>KDEw71p!-KjWyS0Bl4QU94wo*AECFThHK3YT1dGZOLFnE_{K2 zCG5gNf@98v(_@C@XeJI?5Kl&o8TSdHq`-ZE5eVN$(vxxF(}hW%zzxr=&xGVqkJl3R zqyjD%oG*e)msjvePz()TF*sZ)9<~C0KecMe$epCU!`AoHSsuU^oSz!E&J%TCZ=_(e10+ckP+er|RaMkyZ0$rHxt~Ez9gFceLJ^*{SPr zX|Q#$Z9wKEWrDTAHZFF%{kE(-?I|e%p}oC5ZQtJ0r6RBa0ZM6MVM%pht0xey4rFJC zl`a8ONkD+xDaBYUQoW*RGFN1#l(x?-tW?hzl2Bn?;rc?c@F;mzwdIv(2&MMC;yg8P zX`YmKlw43f$!VE^Xvd860GUdzW2V;0z8)>!dTb|+*Z0De8CAnBfR7GvJP~Y;t?$sl zFs)4Ds`Ezxu44j!er38}W)iJ?)+WHnaO~p?8P+Z(!ttXKh=HF;FhZ@StKs#M@Aoe` z-fQ9q3!XVXcHhbS#*;}ahRmyS?g>nKb;aZ3Yuc!f%zotT7#b(E<=0GZnEf;&5p;h1@aXa5NAFuQcw29uE8S;b+>qOAkbBNuy-U*7F5Mp1 zv_;O`4aIE4t;VkZ;NK zbrA;o#`%nHA88YTPpeCYnY$y9;*NF^yIFeLdpbI&_sF{0Ki)kqI6k`8zcl);-3qRA!ngGAqBPVr!Z9*yZB$w% zthKDQuT7J_A>aD12v?|dD)O=LvH16>bV@iyFH7Q1#{-e4#HStNuUHFKtq<!7ka-{OH`+ z7W>wyG|n{5JuNsfx-KfGh;Xa4f`9a@Z6kIY>>+K7tQ2+&G!pYir8Xg20O_3AMzQ7F zEmkq)5&|AerrBo2w1YTs_`yKHqW~UsxSEm)Z}>KV6FaYbr+kli?*0NMVN7wCv3E6w zkU$#>b`^YIAPNQHf~5tY6-Wi4jF9WR>pK_nB`#n7F;Yr5>ia(f?cv^}K+EHZPzAhouLhZbgXuPy zj00AiT#CtV*}s|G8$X!ii~3_x@f#b7i5dQIRQyu-f?g2+CS8brS76`@5N3gnSikj6 z5)vL{F`LOppci9cRgjN>BgN(p;YdQMEN&Y+dPqrU|Fxds z<5nFkqc*Ls_n38ul8xe5OS`Nc+-2M``&reJ)JsDTT2RvC3jz!w@=;IK)#JX zU-$OgJ*#rDVC>KaNPTeT5QV6)My7kb4$>*1g+V&nJ|#%&gY_ZWBiP?gd#3bA zr`0K)>@<{aPL?EBw%aW^a=f-EJFlq`IEB@U2G>aU)Nls8e`{$}8W~+<9T|qj#N5~p z*mpC{1C|l2@O-Dk>i)~HpsXK>J67(*-iL*t8K$sVAHZzb>8EF2)+2*fK6?AC2fasq zKc4!iaoCDs6+S9uojIdzi#l#)p+O%VQ$2adhVAatfByFOx9qyD4?=^oo%(BSDtUvq z+9dSZ7vS}eq4tVsFrOBxrFOEZomdUC7uitDLXVtIGB1n#=|5oaeyB&S;}30syvTl5Gu6!+E3aGq_b$mzC4RO!K2U0 zLeXI+&lWR*P?HX(iV`3d`4!P;Xo@z=PGT_AW_%A9et?^05oVvd_BjL{Pmsfq(-L7| z<9=zJ(hGd~oobC_Z~^fU&=M5B{@caX~ub?PBbr@d-csa5{ zq2fPE#;Xun8w^I`H_1MuX6cj7G7bf`^2z1F++;WJ8ZGZ)l4#=zDz?LYn z{KK6|$<8E_zq|IPW`8{j^4qHP`l&&T4_CKcdyCb&5cVML5t$?+98^b6Fc4xg2}%-h zS$u(XuRx-KG#|tr24jjd=7;jr2-mX|yW5+do@p=x+rpggH5(+qA>9b*J(D|NCusr2 z2xlM$02Bz@SiBW~jK@HX9wj^X!L<}p=6XBx`2vU%SD^r#g((MghEfkkkvJRib%U=Q z@H2!8oeP<{_>)~2a|Ty&%*#q=tg@7CZWXY%;Zs&oN|hKy6R~Jvtf91`+P?2C?_1tf zPiS_1-#cRyO53$_I^XuaecV5P#z<|-gQ@LCODT7+npe=FOV<6~%1IOMzWU;pnT$qD z$vmk<%7vwW0dcEiGt4n-UTQ`(nweKnRHPtaloimwQCp^i2CROY1Lg?9Xdu&{1;bxo zIjxY(eHDSuw2R!?*CjBR4)!(B2H#wHZeX>%IuJ@rN=r%0aTQ4BBy);6M=Fpq!m*=t z*OBb-jPTMh1t)l5KRgK7SMX=77QJC0o$fl47oOo?>Zd>(IB>v4;B7#69fXI0A^Qb_ zD7F};4hJ$~F+2MNfez_#(2_i9^P=TJ2ls18n^LKDW}jR6Ibd}BIH#VHr{GQ&W~nf5g}S7tjO`yPD$HZym?!~^ z7{_BO!b@0`d!nsLz`=rVJH#`}x8x^6?;yb6Hz@y#JPC;fX4yZRY0CsY>VC?0R4TAY5BrXQ$CZtM>p1tV`bzcm6ykFu|^7sh=TR-Y=oPmlV9OsA#T!M zCUsjD6XSO64N|q8+O>A%P4cGJPJd^#e>d9jMWPK$Rrn85Q>vH(cpHVa!7H1Snj67t zY+z8tsC}ZM>|Ko|8gUto_!^C1&j}o|_&J*xf{yYT%fru;)!-l)dHtgL7wxG34}7Mh z@@RsnUp?B@Eu>C+dGiwOr){KKdwm;#G@9$q+Q2jnuoG8OgfqBPFbcIQkfSM3ziXNA zv?Pg1Nwttr`u0PuiMJzSt#CS-?Jo8opt}443Q`b1{$KQzK(7UzB><)Q>$@}LFK5W7 z?=bDVwlLX$+IF>P;^T!(+QFO!~7tfC z;2#^L#lGSo4g11DdWS+}3;D{7KrXMFDWb<)=@f~~u#!3E*%rE3TnH6$s>hn*at2{R z;-)q)g5x?;f_57fJV8Q@p`dJv7T9Po#Z&C*>!D%bLsCy>mV2P1doe`mv@ftFX&CU5 znB_~dNLGLcsP$zsDck)`wt-A%hDAtMS=RIDnL2)}uCv6xlF(!}W4SWM1}tI|!^lpd zhDbOYSSCUw>;c*~WXeo@%);*4Q%Xx>bEpUz~8CXX9rw;eglGM^zO;&YoX+ejQk}{a=wE@^vrlq{JD6qk`%SBx-F)xr* z8i2%J$pk`nKuEJg1kH}7u3%6!7pZMjmtRdQJ?|oQ;N@{FJyfi|2XO(Lzo1#?QMyF6 zM>5VENS&b%;7ffKtxluyyqN%oU{ZrPpDC>lqWUqkX+v)%^yRqN&5*-vvxWsWmt5-x zvIuVO(b;UqbsJ>;Br5(_&)4VwRl7LnyG?7)l&Wtn{4)@7uYE5bSUq-q_+Z}O53D|W z?dnYrTVag!{_kI&KHdM=fl1`m zW4A0m`^M{M#+-0$d+1S2+Qw_-lr)_V$M^(Q8^OHr%VF#hJ`P*2vn=q_gYbhPvP;rz za%$s7#y<(d#CVw~+#dlt-L&ld{Q4mn+Mi zbcQm+NgIp}E;_(CAkkAcSndn1r=6^Ck}c>mD>{o9pT?fnS1l&!KnlcvVzt#Kqrb8( zo(^!@WZh+%0|vfUK$m5M!y;rd?=3Fv=RUuzt8^D&=(4!TJr46v#!#XK}nmH5w zrsIOLQxMyMsmcGJlcvL4{dtOMK%^5RVd zO@tXuBr`{lCYNA%$cKkl8<7nXW5EaGXVqkG*r+Dx zwx#!lCL(22>TK1?3xBO|**e{u)Iobb0e6ghn0m-q%baG8(kE4u3Vq9E2$bPl|D;+f z)b1su7{K*_um6nDz6kgR#FkrWt#GSBy4753GMH{v5ol|JybED_XC}12Fl~o=o!PNN z$ydar7V#fu#%KO8lL?(sKg6$y@b}Ya$YQ4CjUPHAK7cdq7f)zjm`!1R6rq}L$oGQB zGzr_(dX!@{tYS7n28<%4cP3?(B)cTUKE<)vWH7E`M@^%G=>r@P{3hZzM6Z*XX%~Jr z63J+g6vQkNktG#jWd)mXvotA*tC7Cshc+mWa1!IPoI8yPb(S%~5aWwPV3?+xw#6n2 zw$o!`U^b6vBd2S3kUOiiXTX3?knfFG#%t(n^sQUs+Y$120=&97mIn9LW5(f%aIbI} zhm@TCP-`%5(wSEbo9$5O`;Zv2!J`z;SJ7rKFF1yAuPp=Q?OnJRZmpgN=}Uq_8uR#b zn01doS8E=M`)p}djch4m;|18a4?w;}!XFNdr_iGVWCmes;1&1T z0h5D8i{$SRxV^2WS_5STd4+{SmM4r`k1sVf=u)8a8gS6KK9gkPW`D>Q#G6`Z4MDIM z%oANfpUGl386<0ZI3rs!XN96H?x`6puDPJF(9<>(I-+RN#j~~cbG6VER~40Fe=fz! z&0Hohl-#`qUo$B`r2o2oG7N~AZqi$X8;~OeZS{nit6(u#B1|5JH*UxR=k!=u%*w|3 zo2hW|mXfI-!o}1lW_7A;mqedRi{C;BT^Wc!o4afF>K7(0+NRa+414YmOcKe8z-=9f zy!+&_C2i)*1^tSL4)4F(?d)Y+{l)0cW8SGI^LkEQo!i#sUQN2(JG9@i2CN+;gswE7 zpGtbN_$~hgMla4p|5TG;Acc+Mafn#h@g$X!%XE$)e}Gd*Ei>rcfRoZ>!%@;>9}5|S z(*_hB(DbnVnPIHy=OY}COk1_rNX=GA@~X%i!v? z)QLNBn3=51+^^^TB{FZyTR*vw2JOeKq*!}zD_}!j*Ho<-wC2GKo&)ND2_B*V>{SP+ z8qJ6!Ve~Eb3YLHoV2gQTAO(gRIIbA{?j%oYYFe6KP51hIfxyo6B<%&x zQ=60&=L-&(%dIAy3O8ZH@&y;_rUls2bwdljaO3tuJ(RToSjT^M$Yt-`!jW(AY}aSr z3w)2~8Xv3G205T&PZMkg3rDbDwk!c%-z;^}f$Q0-C4$tB?Ao z1GQUxaNUF*Pk6SQy3gyp?pi}D5N{j{&=<24eX&pP350R-dOd>EHfRK~nUqw?=z1-o7C2LV3>gkc4KhGyd$nA{+wAZQ?r6%R;1WQ|imP;tBC zRs@iP6Cx~FQ=Et&2NTwWJ1I1521->BJrz5+ntV$6&?cyW4Y)q)iEr8X7jYj`-08pQ zE~ib;VV-cSFKkR`R`W^e6YW;!bV@cIB%8Hq?4|vl%-T&q*iCNN?%EyC+pXQpIF#q< z6vQ5C2dek0R=9f6+AzM|#UV!^l7^%LGm-7g&!3@FxLxp6?O!n5_#<}TTh%uIHj<6T zT}C>~xDpY*jpV-+a***11C?>$XmlO{Obut_ykKomf>B(?c^SeAYRw^lL4Zt)3AY$S z%egbgA21$LONdGx))mC|B@|j>6(^1a7~$wr<70lo@x_Vgo-Mm zvoMe>R?XYVHjy3xJiG|Q^aoU%ZpTbXNgkF&yYof5Q?Ni=pGJ48X0R*O3K4-2(C;YS zxxamTxZ&&+qWHOu&<$U7>{y8J54JH6p496_`T$&u4hvoA1N*Bdm#~kS_?U-}p{XAB zF$o{-^nnA?q(Os^l8Xl-OzWTb1FS-uUeG5bn0D4lAdxyu82rwSuh_N;lV>hrXP!ED z%L4~w_Q~pz*)Fpzt2i?~)0gGW>|fg@B=qgjD@3|>!d>?paaS413kl^hxM>vR;I1ee zcL9SvB>0V<5J|D(&XtV2fi?X?q<0-IH+Ak75_;Z%OI5fcL`pMo$sE*9Utw`==YD>h~>ISf=twYu7t+H^rz@4CJ?el7IUrqS9e2;!kL| zJiKh_uDdra-L<994K?As{Ag{5NCCa^;iXG=w|rX=tzq9<*|Y05|NPksgX!{*(y})W z9X|Q$8^>PTKDnUw!R>WLg>~0v@$X)L{Z305NG?1@;UF?21_RRUosWEYwZzA ztg1J_Vw;{&UFqR6D-)saLi97b3pRvsVmL~yhd4j%Y+W7TZ7@WO>s!^4EJKYL!p=_1 z9t)jrS%T2Ouxdk_uJSfnT4lnK8ty@DG~Om=9tMn_#y!a4|A_n11k*Wg~H4GP!ecqG#BR#%{= z&$TM8W8HMvEPB_GX06BW{|=hZE=#iR7FP zev$edc^#>NQ$mGcL=-`QIJ-1e_*Y8nNM6xP1J?8j)oxBM>zn=^5JdFSfFRObSvJNT zdx+N+qHi`rWDQd1scFQkCR@w;cuB}x%G(qfDH7pwvK8BbK$5O zZikDZY5;m9Q7%K(xc>Q$WEDz{sVft-2|^8gV0TN$p)Oz>;TZX zQy3@V_*!ddk0aIz)nQ65lg0_-#3iJb`V^+(!P)JSw^!Wv141n4;mYi2fNud+Bsc&i z<}5|f#-TIc`RK%7-hjUKd!|u@RKxWu=8E1 zaBdRanKa8Krj`h9bcsv!ln5rPxdd^loFycc;F4r9f*kcFp6yS#<1PozEaq~+1*ny! zO!JuyDXL=dD5Sb-ScfS!v2avbE>0U*H=$!F>P{unD-%0(s6eoTS+m+@c)buNAfT>v zn%*Oi0*@ABUS}s%8vqw{X(;-e^`3t4g(MW`LMOzU>2!v4ddn81EtC$?MeHz=;LH_yYEA1=Dz^YE#Ke(m%qA&kFeY2NCfSM-d*H7;&%Jxru3B zV9LY}W`s8-E4!4-i78!RyMM{j`)v!X1G@AZARk?{de!1i9dBTD{{pUSugYstcc90> zP9L%@h=@*0x=II!F~-yC9Of72rKdjo3^ewLw1g(f7rBJ7{Ge&2trtW(2UVBQ%e_)0 zhLtJ3#9qlOg{fXH0r?^ByL5@s3*Nmy;Kdl$>o>)Ofz=~Zx^61oltQipI|Uz{moq3b}nH5h8LhIuMWbuKWcFy6;1HeH$TTPgimMZ<6?#MQ85@Kz z?QA<8yPH&oDE%Tk%j3{i$0!n@aP=U5ZljsN%_}eaY+-i)4!wq#%`X@`&pWI~r-6mH zr$y&A3`QrnLA!VJHKZ%zuo#GqhMLw8G_^f1nk^wBmJn$P`oX6#^WtAFAw?}qNM)(W zLZ?o+_3gi&_~;$k`;_)I0;ocy1l}S~K8E=*Uv&$_C|N|wf^!;G;7~$fT&=u7tT;lT zNA?plP)@9BBpE_nNac)45)C87%RrlA{8WZCDyac6M#9*#kJ9}ItToK)JYN4LPBS2J zewr2Pd=T?MtOF4h=k_l$r$mseQV#rh2i#!T0dC{QjVDP@?I8W=+IU*N;PHj@)A*aj z_qg^|{J)-Ma|&!XIgUD;;jz;@#Nnk+Sl+WVS`4fKW>GT#tO0;TeTyWSlM;0nfPv3z zt4ik~O6)B_o%kLiYxPd%sPL$9eN&ZN*Owj1^x8r+uGhEHtvF(vny-aefUnt<4ADq zslj?0VG9O`rI~>=Zl0#RMYhP(@QBmA9Oh2I%5k9_jy#qE;m8ey*qcjXdop-9@hmT+ zK2gR|UIviLTnM3q=bgtW@ca_^i`WxsE1XV6=<||5>2rcY8X#+4tj0vav>UQoxEaav zPH7Jo*0}~nVN&|t@L~QS!oWLqQ9VRDn2Y>iuY-8TnS~T#=1_Q%VGlq2u>AhDZ^hKB zTd#d1dJsV^4yozQ7-^@FDQr~>IvQhQaRyW&;Ybi#bGIw#6pR@eS=nh>IGS1f*%4P* zrd2|H7V{jn|8N0R25}M$|8PVqV#`vK(U%m9QjL1!fy(gVQ&HNcP6idZuS zpWo~E_(elVNsExw6kGzy;Rx|t-LUiIX7{;>0KkP!KqP?8YAWni5i7tD%ZxCbUo5$> zIOmGn9lLjvD^K0Lc-U>T?|psQP3yINq-xWn#hrWiTDbjT?QOC}n@S&CNgs5l_Z*|W z`|4-fOPfNDXDf<3fBpC~?<_3VQdVLNx`Cb|=!<~RhREu27Qv%ZtPTzq>jMT!a0$6` zhPPgjOCX03iPxJ79hc81r=rgSDP3D!7{LoMSuMIc5zC6Z zF*1k|T`d?MvBuJcOau=SvXj!&Nz@)rCmGhP zbQZiIy@|iz=Gy?(A*HDvc#*>`z_G&lNmFRPEaj z8`swpda`=xjTseX+Qt0uZh?w<(Ft znk5sa-F)ql6Q@uA@#L%Tvf0h$`JA)W<@xuJUf?mk4C&2o@H3wDXJ!>hp=%LNVm;8c z2=@r!G=-4rAVQFA2!0l%L0gn93c=}d#Sn&CS zlK3&Ki;S);dr}y}*1`ZY&Mh5EU`A>XTZ=o%g(4NVy@O-%WF*iab)ZnWDaIK4LLdWB#>K@?%Ag{^5BW`C55 zP6U?>35lp_5f)RKZJcrJ+Z?ro?V$M24JBB``J@f_(v4PArX?%gn3hg_R$Kx}!F1wJ z_Hr8GQU>Pl3dmY)E0~M0nPr~Foc+8mnA5>-m0d^hXioD7+*HxERX8W5U;J7xUlakI z9@Va`i}-uAj_3qSO}a#?7PGM%AyPWc6a=n{X*SN(_3}(#CRKB9$R*q!b2kY~CTR`! zuExXJ63LLrLYRoEo}eSiV5YEXG>dQmL!bo!Aybq50=*riCeqsvz)af2J{e&Xe!J=w z40KB_A!LiO7&r&C4pEyajL3{PB+*S!ycuwXwhUKnmUNSvYBtGRq%GoJ^9eKEX(nvn zzLvb>dBTFlqsQUl=eu^T)@%Pq;ykNPmfk#YsTSf?+-SAqE+E0~3NSN(#OoHcYnzbrMnuB^-=F3E2&N zvDfF5YEm^%dy`bp*ItLV<9<@ZZ%Nf1+8g|5?KM#L6#6Oov-~z1*%z_`7-5TeDKKP^ zL=&7kLkElqq;i!0PPGAfff!BY1nf3~N)FKj%fo_@Ip8vGo|%a-3A#>LY*BX@lyau- zc90(9=Xcm%G?jizbNhuCxF)xc1H?e^;qw}l9T29eX~1pp(mCEQJYRUPi2xBKexFxV zEM8xV{}{bR2*BydVacwu62N;Lg=aG)M_QibzHFIShEFRx_)?pR~VCgGM8rE zl_{?KRdVz&7RZgcc4ahqN$4(2x(PJ1WAGVr>PR>(vrDHNZ*Xr*U%z_WJv9Zp2E@p6 z`e{|w;6Da)@`^hYb+k{PG1wnk4_uTZX0$tF_Fgtys!Xzr z@#~AIvW!;bkdT_3?#mwKpYEr1u$yIVNkvBP3nnG?=7=4720d^!GXk|X%?n;OJy zxzVEdCEg?!w28HhZNt|X@HlhNf|YEGVGXv;%GAUurMZC#AT)T3L^ip?c{Mi;?m8sd zZ8fI$>rq?NuFkVQXVJV3D{ksIY~YSfcW)7Q+iFvTy(>##JaQ|k&C4vyul7tHIHhmp zU}tJWr~0+iF&U;bzF`2`3+^nC{hn7nK(8vwFOAe?b&3p(Jk#dIHveeDc2Fh(j_4BL zHaP(A64R_OOQlkN9?aWiqZ06@DPQA+{k#2U3876ws>z&OO(BWs=e zLJl3Hnsak8+Jb1ZW~UvaV?i3}s?(hltp+UQqB*LInRR^_2T5Px1+rV1D0qoA0hEc(XZ_3|2be5|^}fIa z?|f`7@$tb2{M9i`0ybcm;%q?pio%A5b3ZKu^2-q^hi@6=NA4JOlj1e0_d{0?^wx(! zJfGB5_kdHOb)CY)xDB5N8bfmeb3xJ|nLrM=7wQtg7Wb1UC;&$-v zY+sw1>@F#-&U7G5k*RHUNpVUqhr??EDA7|e=|t?~Vz?l0G{GwGDb>SZr|SaZk^mVM zm>!_~64>Z{i4nPA!Zi=woDu?}EGaK5tAeLxQBBpjVt`TY+h15(!ly>Nc7>v_zR-*? zKgDXgyXJD+w#EN!S6yCOv9Yu;r(N&%m@EC@kjP*6n_(B~UBHrV1(zXaIxPIKUYKgzTXkB~!y1~ZkjDL~^ z9G63AIHClhUNte-@U}3(2quG%6js|E5_Jex%VPjW=mn$2$xa2apKSIp#E=e3<~nw! z?B*_(jG9?!c=nGkHf)&z*M$>1mK_dw0C`d+U_qO8t2m;&V^2KsgxC*t}O~v__o+u(k&isi`P!u(@$2!{lK0LX>z#;?aGWd@h-v%en zrNas}F-{y<->sy>BQ$9Ec~k)XT>fV=0N5X4HI;-)$%)eMODX)2OACCA6)$NS`HZF9i+@Rw(u}P7z9TdT+3ijvI^(oYk+f^r1GMSGnf*s~?tnnwjP==K9oPd)mNz$8WvTF11gbN;TRMBXq;<=@ z*>baMh;6^1d6>_7rJ0)tP);xe-~ z&a6@M7$cboB0CFEyI356DaO!7%W>*p;G-$*6yo`LtW?+}+X38UGl-4$!AxL zzON|${xfstKK8_ddAp@oR?eQi@@o6lJMO;vyPZT_+wTT#{M)Bqe*NROUxgU_uZEzs z*02+tOr~m~#W>@`cE>M6B7ThAMegO2P-YGWsW{e3-9$JfJ!uFoTLxLpzvv?R2eCU+ zN0<#-LN4tC3({vFMBi-9h3x}dQz4;2Q^>#0&_%8M3fRof(B~-WkC~16Mu{`oG%*`* z&D6?P0zIw+o70{2=Y{_y=JdO@q&6V3IbGX4r};Y27}rJ{lI3H~W&B0li8-2zb%59a zHjgrF#+;)G2^A|tn=W1AGgB|)FVML7gcSCCyKMe^JAE4BS)8Wjo4LFUEE$uR3I789 zd-fxE2;!o1XM~pNhV!>5+ysjLCn!3J$zFsP)#8fm0igleV?txH<#KNYTw5d6mTs1g zp3cE;ZEm(qwipX6F)uYF3CUSuUmz9I`;KZy*Z_zs%v*&tzmU~6RSB4r!dN} z>SfoR40P&byb6ptLR3o@hm! z2jbx->Xgaz&o?ZJcJd7Af2FY%iBjv8E;OZyO#gowUW*J5wD*WMSo)gNwXRA33!R6# z06Hbah2I=nU3E)6Z6i8}ZZuB^`C_qd(s`jtu|5 z)8S*!;id8!Y8NIRz{G<^Wk0ouhz(R|0B34R>WAD#+CWGOA_T%eGH5p&ZT=LCHJr?3 zAwCBamtoZd(h-vxL$%9p>KN1&fN}Xm6BvJqX{DQH>C0l%T*B;$xapf``VJ|ns-*FW zC+UAl7tfrTxh|`h@0Q_LoiL~SH*^Syd{i%&ZqD zA$)}pX-cV}hD0KEn_*vSr#tQE?X(ZhFqUKiONYgp35b9&jzGO_H|b$}!OEfPsJDG4 zgGh)rQ^^Uh+C0X z!m)c1Pli-F4L^j{I>hOztxg|g1n8*%G|UY|Aof3Q`ONY?;)|jNTXj2;))p+VVCSXZ ziG}=2PREQA7+ro2I?gyqm`sB;0xD&{jF`DRiunjVJ zAWQ2)f3?K(yhP471$@MeG%cmDGOoAl_>}BK8Hm#a-AXtdrr(E2SR9OLF49&Zp7f|e z*GF3URQM}e$D`(~#{wbc@nkJCRgapp8-4pM?^|qhtWSs!C1!w|$WoILG);B7%CfL2 z&f}XRV#*}AXq^LHh4Fly_vj#`M$8=-`V+kH9`|`Sb+Z^rZcxVp-krsRoLk*~&>`Ni>vg2A&X*@gJqL4;f@8sW?jD;RvhSA}kE-o*>+87{@|9alm;P zeuzwl&Q#!FOxcC4W=#1-AfEuoAh4eqH`}rzKura+iHJjF>jKyVI7v~bmM*Q;(oUUu zyreehl4Q%X&tCbrcI?cVgWY8$m#4AR7lGUT~GB z)ZkIHFxi);`n@oVhNCz9!w;(!Vq~K?&F}T8em}xVwu)6A>&C*B?bMU+wk?ox#rq(39gmFIUGA~+!VlcSLA6su5{WO`hk z1;8l!Vhrq07qu`4AfRhr;0GN>Gh7b?k036BWSz;RxO!*ehV>^iQfBJ7mOVxMtq5l0+H|h&`jv3;Y|X&Q8MZ>0yX|(V>q7)yLflj?85>Nx1L4b%wk0-GUU?a-sjkCk>k@c8zB^q-smvDgUAE)z!H%z* zZDn?>hr>9@wD4&VEU?nS;r&dje~<7aN)H|)EEKYGRGY+;rL@-U^K`sqERZq2`!O#q8>@fFR%D~!*%}cV5vFdtd1{!Hw%8MJ zohA_;#SCc&8kZ5_&j(~f@I127POzvEfSgES83$QI&GU(K>?Q6D0=BFkqAA9hL3_ZK ztJtIBmU!VwfHq%2cso%T4I23vxFN}c7iYCk)x}ed(~_pzCOgKu$9fEQt34&;3V9LZ zRx(Vsj!hZon&RC~?~@E6x7{<1jFHDGlg-nU6`;w88+YiWMTgI=>9v#s9A ze8UCiAs)@3l`h}{u@AARzzpCnaY%mek)YmlHG{dyiB%8v*5^R-8*7Phv9xc-_E;Hnv@-F$f{JpHmerzH3s2UaR z(PF&qjh=|gQ6^gh1(c;`g`t!4MVbZ(0V6R+Gg(kv2y>XYhjYwz*g3I>Vt>JZs4M}< zguha^B)IK@41dxLfrY1F23@c+@RTxxkE|Gd?<6|@CT)lI)k*EV_WS!t%KPv9?WgBY zp85JOAIe`Ia%zA0PP?R?N;-GWOzJNG4oDYCPZ-X;)6%K)O4vike50@`{~U~|2eg2M<+!)y6nDtmn{7KgHqO? zVRNu}hX_1JoW0EiN49ly5WS1&8aS{Ng+d%ZcZL#o0v2) zd0xoS+1EX-duWj1W|N%lZWF3>w+nT4%dZ2VBelv~6(|i358Ug#GjzZBM9R^WbMB9Q ze-4}reUW|4krlw3WOivn{JlZ}sb-H(YV03V?(=^I3DyeUBUwhxwQQn&aeS=1W z=oa%FQ<5j!WhWKV(Tj&<$9h{tqQ0&0gG2Ai5vBa_7A;}J- zRb}#fE4Y6Z(TGo|{*27BVj~fZc4OEm8rw!(YRFm#>-o0frqv_wVrh}1w5T52ZB_j& zT(Js521$N0zCYmj`oR5JEDTCQ8EfL!Z@8;(Yz9T+2v3_JlmwGS^w|2himKD>U`orQwJqK*M{UtW1*$M3x^qfsd z6CO~9RX8f#z|K$W?C9+7=INF;fDV-h8v8p2x<`5%=wul#SdMY-X&#r2(j+Mr@XaJ( zGuQ(b#h1}n8ZFI`mP(QxiaJ$l`nW;b3(JzDI};P(PDsnvG|6AV+k z)1r~}BWGb-1%%fH%nitG_?%#th3r^Et{l|9rf-W|u1yuUY}&+D5d{7EMykVDWC~BK zoz!d+lVhGX-gfC-(`P5o_pCMD?Kvp_NX`8%=L7qXX)gju;n^jJR(3CME7d&IS^MO{f5+&S z$+NrNc4fo7f1S#LN^&vjLWGMX^I9*@KVLrZXt#wJw#L84C*TP9cW?s04?0Xqod|0r zW42L1b0#Gfxi_mOCGH_#tsa`|Cu2?dYmb+*jfteXIYw@{TLG$A*!vkAD z2YQLAZ;F~E<**uaSLjA#=w02A(9wT+&IEP9tde_f=+ti*YH@$(oZPyGY1(A6acJie z6Se!$OQnrp8aJaA6~Ya|C{nIY86fo!j8AI_tg@~ha@Vjm!ymZ$q2Wn}KvGODN)7m8 z?xI*)eyq&j*>|JAdrkMce&Qf$oH*4vuBf4SOy9ZE0_PnA77Up`e3i7`y54zD>Z;IP zHB0;6jc^xFT8>&?wVaB*nwjlS?l&~z$~a1o9J(pcrgwEO7Szz$#uZ35Rx9m-Wo6}+ zK|yd-BLJmyf3h-)`4V(2%uA9DmR0zJ&w;UzkB|H^-H}U5`02`j458=3f;fG6K z0JQ3Y{R{h-9IcJ%%|OdvvXG-JB;Ca#uE>X8?F)21{`6y{lN-~PIy{aDh5&Z8*&O;6 z?)|9}kNX96S~e(;n|wNAm;nZa|B7MEO85-OiV=sxcRU0X$;MWwI~`VQqQVbp|+>p;C^BG*s`(DkqV-n4vg==kqj8px3DrJ zqi4T0JyyNbeZUH%v3LG>`o?YdMN;EW$+r0SCG$rNxT98E6Q3E%%9rJ$o)u*5^!A0d zg+QT6FPzuA7xTjCBRs6^6{iYzkUiW@VCaR7J%%R1LXG^RXH88nL(S#aCXVdA?AX{L zC&j6AM~!Zn`qqZ6#RZw$*-W`#8z4@UYgl?GvuQ(cRd-f4=oxw4zj0e;VbRtNZ%u6& zJ!-DFW7WyQV~;KCHFCn04)V#KwKXh#>+)GzB#Tv4Vm(C_49?~hmtQl~AcZ&;Sr!!Y zEN>Y(_vht%%8>!~;R?nqD`><0w~y2-TU402&EB)7wx@jZN{0y}d!a3ZPwJ)bK~`x$)NQ*qNSq)a;kh?;OmpS3%TZZw2uQv`sx437efQH_Hs-Uu`0Xb7$jBoo zbn%rh7kBEj{K!ar>eFel>|cy39Kr6gJ-#K8JKSHvdFmbiYx!eLf1?cT&-6^Z^uI0X zr-#QNdz{t}ghayB7i|tpgXNkn;JvuM8@lfVzIHntdu{2#K#($k7SRAqRLNkqS!@7$ zvPlL{syCGy(u|>@f-lKElmtcpP?BoHrNv%;StRDLS9TCfOM(}+|>E)-)?D_l0* zB=b%sxzpB97T*5huFhs@wIQi|`m-ZO9GqRKh;$l}J1=_Vp)vKl4&GUIHNKhN_P4rO zch2qEcf~^!E8b(L|5?IGV5eT-yOmj(tk#;7GL3a6oE=ZFpj$u+6i8+7H$AV0O12;o%pd3?|fTh>i#AW z0^Qn|S^Tn>)c*1KgHPa(@qiCAnTNCtJDf=npmZS)*t-+*FgZisxptUd)>ddM>3pih zFUME+gT3$5+8~VIOd!HmNd}B>!9g(-a=oMEc@<{YenpZqv7;sMV6g=2imRet8rSzb zxxvm%)Z=sV1ReQ=#!PBxG#(er8TD#jUI;r%^qpj8Gt@ zP|wNm)=wApoa{+mlNEOuIW>MmQ{|WGYZy0y^`!jrl{WH6G<6R?lD9C>^OUaqH>Rk1 zYfpT$>Cg{7@Ectm-wgf3Yn<|#FvuaFj8EA^U)ytakzB&^jc*q76Th<&iqS>!sba@H z$ok4VEIrCSiM-j&LEcc{E#5=7;>(h&i}vXC67v(kv-G86{MpGV6KqrX}*@PwH8+hgr6?@f$K!epy_>=M68N(Xu`Yd?e29 ziGQ#MjP?oi=igB};|BE}L)Ky~`&AzlJ}`-KL4Kfe?$G6C%>n#kr}z}Qm35B%{hl*> zuCZN)<;lme=~;{-T!BtVRLj|O2EUb{iqdUY@5cP$&$4Y^}r77`N$rBy#OJ zvTzSw#dFtIUaOIA<73EZAW;{ziv8DnmTuv+K!&0!S8$%>)bcH;h1G-w#?xzZoM<@` zVO7CcU3rK1FnSERe%o9VKK1z;5EE;zJtvX)2U;#&g-(%gK;9w<67@&Fpr0AN@wW1% z8aJ-YW!g_^`9&*)tg-?3II=qxl z7yDmrq2>y_hscmdLF$drvar)^$BqF)m9&1sYOiwJvrHao>{6SZdD!fPXb zd$p0ALv0dNhxx$ih(D><1T`+l_^>yzX3y0|vA?!*PkaF?V&6j+imzS08!gr6Fmh)j z%ARGkg334diawWkzkpzL8eo0M(9fDuAY2TmL-L`Plb}UT+WI;n>NJKlP)FhX%~OF} zL|L3VL2bNO{_UxL7hQGk5P1UqhFI#CWNR znVgvWO>2oho3Fjtw4(4S&6?J-@~{-Fp6Go(2U$JkkMwB>+HanRBCBVj6um!@NT+^m zf=I2GbyeflBnw%uQeNKGyY=qml#*D-67^)m!CJ}E@--^4@QANnt6__ePKVd6YWl1| z3f`S;Uhox=PYl$u)x2P%&N>o-Ae%~}x3aF>BMykq$CPR=j@3~wGSM>_4+QCCsrlN` zLZbTEV--oPscdO$B7r7){dpd(sNiS4oTz?tSF;AN7wdAiqDy*@qb6)-IRs!*=`)62#K zn1-2y5}SSl-G1Ek8>d!5#Nc_bRW`(xQo3nT*y9OUbINF;ALI3NcszV zU$~Hc#@9_xvnPJ}?Qi74(j{_Mx-Me>7Ph)BTFCzKFa8hT3w4d({y+D2Q(rF-mIy0^ zJB4)+Hf|QS2@k>|`gZ`kds^5d91xBOF9^qlSA;i&)55#L`@)C9C$P5soA8zJcc5VZ zTli79Dm3cjRf>{>8@V`tR6hsG0few|@Vv@Bb(1GOsI>eP;P(|H_Ne$FJ4T^DED? z^uP7|goO()t4T>-~aSE`CQXzUCC+g{)KE*`QO5Y zSEDVTIK?#6*yZLQu5C{|jzoB#%mpDba%{>4H(0k?ebVn+zLWn;Tf0zOyGXw-By$!a zkLGK0y%_Pf{A=~0sSP0JU;Q0x@Yo#jXP-qC_l(~5!3Wz$?->cv7unu;mtnKC68wY* zd_)oW2Sg(mBD(2BSP;utZ|LQc7AZ!m-0B`qVGttgQHBhgwRPH0_`jCSg?`#d=8Vu@ z{`_+oPt<+>IjM`+6h$M&#gS+c`KIYEzO_T2`|s~vSF-t*F`K9XY1ffCNNFN-kk^k$ zg&h9Mav%+Q+NP96+C3Q?He`$%HxAuJj-n+8TD9b7?T~df1s8k+_OD5qSwT2NQDruI zGTU(A`nq2`-&9oV>XvL8bIazEy59HS-{<=3u8I~lrQq+{d#KzfR1(x+Z;U8i41*GV zT1XTEUi-F`1P4Akx%1?m14*b# z`?5=WWBdq`YiE(o`=o%)pG#Ud*)0DJ7BJbM9Dc&#YDEY4>Pe`HT!P5wQWN!x0diU^ zuhGiL+Y|n?aotaMt+~8b`|HKIe_c$RCto4X#eXGdv|DSmZsbS}*|g&7-D|F_U3YoS zAGJSDm?fPQyT0G%^d3qk#=r80TUEg@&>kOeqn+dMHQ2c3@;X%DPoyMG6ty4A zXuaI!f{l5ZLCZhHloAsXe?U#=5%{-;jBmI-nO%} z%S}16cI=ooY)l*3`0#D>e%HPG8;b;KamFj-4q%Dra=R}fFt1O9x+I26N@S%oG-JUsq9l*P&T%z zUAJKY^`Q~dmTX_pd$c^j>Z;1UfBb~JPNRI`YcJh#XTJsGCas4mpTH(;sazs|$8*nY zog1_!a_i3?2#x}E+eS@W{=ob;?K{VxZO&f$@u#cLEL_}w(b#btt?Bga^VeRynU8+6jMw6D%(Beef@s&cH8()Z;L#gk^bN zJ-4P@qxBQLJbh1|z8Com($}b|A|35S?1hlC*g4&~!MV%%nbY8e*+IVQLI$93=KQ=w zT94e**63LxPng)VT2008=MWtr8(ii0$k)J8;8P%qCqnFd=Go$n!660_014tA93c0i z2C`5MfTXBDQbzd&7=V&QGQLtdWK3G6g+ zX>!>+<&%(K%76Z&{S);--tPWT6><*?;37m}>4_B<;hvYMHgrrMG78xLB1!Jj z(lwHBOXDfSA^Cl*W$CavEf?NUb0R{R6j_!EQkaD4YUk?I<@xs(-CMG}+!#ntuk)w5 z{Qk6bf4l6`7wI3sury#a{-CC2n*b%0WV41~s5BSUYR4$-0+#I`uuV0 zI&D|5I2W4fmsCe?Ztzwi{j&c#!J2ES7ILA+7^s?ExpkO!w39U%fePS;~WruZ`KzCkCIRrW7DqSp_y9L99fmEY@z7X1+K^E zZ-4&S_WAd_=R1bgjk}a$>*tE=ii)nVifva`c13qr$mGA@ z_e=_I`M&?Zu0N1zIdjf=+w(r0X#Z=EY}&W%mdh`{h5icPs!h$m z-rII?af5f{s5ST8yXLa9gDEvEdFJIqhjt!3^yVuYHf*@-_6=Z`<~e7_*WlN9k3+T} zcZ(jc%_pI7*lI;x`%o}q4Rav^{tz-K6!J-)f1+OQVm;qk;In5JN|MJ7R*l%TsT2TF z1zb=IHV3x^cLv*na&U9rGoX5-h!GZ-YNyHC2&~fz(uko|1-QmW72(vJJNm0J2*@C-&mXh9z~pq#}VYV^dVAd z95*U`2w&}?-Tq9s<>y@At<9dR!_qr#Alvw>g)K}gq~BygFe=KS6L)E_WX{aH@18mH z?z?6UzxtY*nrrX{`j-BVx~69M)mIO%L4AmhcI*X{GlpMh7f2ns#T2`3WXMj%_lFqYXBo1n+`~8YCtUx5JP%sd{(Jb>v1XZ^ z!*_n3#eJkZi(AWKS=<1bXR-?DHGZDOeT4f7QiEk9Woayn8{Dm#j1_vkasDvw$;c8v zit{&fKHZGGatdOndF7p_r_#|lKShKOV{JG}Wh6(L>*k`wrzf9&1uU(dIWbJ4J`Rcc zwR{NQ0iK-o8)X1y_hfSt{(NLZc3%Y7Fme%TKhA2Ab%3W)6qLXk_nNFf@VCOew zcb)$u#+yvr;E||U>`9DA+hClZW-1%!|A;${^RryXB$9%V>)4$wK#w=>pE3^^_kWc9 zU+$mwk#YW`onz4R{(Fpp!J&}A@vxTAKSvmc0=@r~gC!Z|cXtoHAA>z%KaQuNUL4Q8 z+1Wq6OPm4pPw%b~p#8(nFMrc@{-f;ttp8I57TW*aIbZa6b;893*qt$m^)6X2!WbXBvISf*JTkn-PVIczZ@&FU7w^P<^K*UuC{U5c(ic-;T=W2JVTK zD5`*!36d--qbtfGqiK0^=xJczFx0l5P+orFyCW{Is8`dYcep-Zv@SLOm!JIYZ=dX4 z{N$7`HXS+g;I>7}ezEC}<&Po;IltkK zpTuTpp!;wtbz$jCPeFH~e*Ne7a3SEI&-3`oibKQ&0W7*{AzF{!;xL;6epPfTC{t?z znTq!y|?=8XiUDogT%uo3GbhPR-#kJHgFbUmR)*@gdMZ)PqJta%-OY zpcW!ps4g@u)DRLW(jUl;6DZKf033{03AKY*p&3BZfab{XD6yRsdn)SD0E))2u|*!Z zo#D~zVs^mZmgB+OCswZ9&;PU^kL~h)yb?#=^D%zzIrAdl(tfcx^3Q)p=Kwf~zCznW z+Ux4wax0o$uK3YuL3WDmSwcIik%oM1?qr34wfU>os6a?IcH**Sd zfZFstkYn(_2MsGIk^uBGxk47?03y3N>C{Ur$~v5+4K$6T=_T|)Sw-2-$f*e55ZMyh z8R>|K5h<7yL-cQM9DFJS6p0o(96BBnL!-mcEgFl^5h|YO%ag_RlsXey2J5CGgGPt4 z3Q#qbE233upsZ&42HsF=i@9LttJDYK%2~Z^Su2^FzH{-xwI^Etxa5&mamT8aD_5o4 z?|LA8rhO{^7~vm#wf$x6qivWXmz%thFNWU#LC4zbfIRB>9gc61w&D2q z(ZMqJ!T)4-wCjNJyjbX3}P^Tg1ze}m&ENp!a{&i-N7 z*}IPJ-fOTHIDWKA={oyI9q)FY-HJl5IJ?rl6mWLzzWi{;bYq{0egUx&WM&^xD2AN{zVOWTP`pCr2pVD_FP(KJohd! zp7RTg=bWVRoE0;kaRz$4UW5wknzz}z!z;Ko&biUK#ktcd7CUuko%5LUloQJeA2vG$ z=i?qsmJ6p$e4zZk6`@Gz`+>>huIYidG9iE8VSMTic}u9}Auenz&#**brTt63eo^#$fG&c0OvQ$pji#`cP(o)){ZiddCH6d4uub^aR;_6r$eJ~O z=8PM&Ta9W$M&kx8o__uvj3^%Sr4oFu%~)tR(6I|$88sdWgBkWVrByb2{u zzHpIlLz!qdsxR4G7MP-t2Fs8hM7b0i876J$j3Hk(hKlQp8h=J`PvOASiec1h=wSl^ z?8&g*Q=e-^Il}eS5&LE1+aID+_ve!h* zuYVlmWJ#2*s1|H_R>nsP-U>*MZZf@w1Zm!yG)gg3xsDs=H105W z9EiiwHYV5G2Vo!r0~%?OIGECds!?uj9yO(@t%&DfkpnMGupUuZFwnnmNq>UG3Zxs( zYourkN|2UAOs-X}WZO4DzQ6Wq`mv>ADqTl*rf+J$ijOZ&PtJ^jSlELv;xA-ek5N#q z7zL$k6u|Z~nf#I+T}$OS`3uZQ>r3Q5hnW-3r`jRL^<#>)@uLx)>)ow z{Y!-T@;uXg|2kolV3PzX~G|k18nyM{{;LnF9~hPPEk?X&gOIkVv>L~ zR;R-ivzen=inADLhQ1Vs`i$dIS4YdLkAVe~(g}8Lsl`a{sD{;EiZp7PfJ2i!0AFBE zWz_gZWP*|ASGdd71a`%x)%Hm$qN8|>}LPJ8wgI|OsU-b8` z-?=|?i!0raIG=NFbHC!0WVaNZ=U(etBkT5x5bVqq-P6ooRKB{g2p$3sKB)eQYzt_wK z^MBF$`20UC-#LI^-#*~LPS1mmiMR2u+_UDsH``wkQ}^#^*h*)VQJwld?AZP29D&vT zF}V>L)4UdKh(Z#6yDJ*!OfZ_FU1FGJOdDJqR4*7~d=F>_Dl^P{mIn#0)a+-3Qk$i-lBz(2oW;Zw|jB8Pg)VS71>{_tUcrFoPH`h%T zO)a#?uu8VGRRWWWNx#f0;k7=<#L9;XpX^>GD^cg+AX_Du;%Kb9BnJ?JN4`87JB8Mvtu0LeuZAi9PjfP$M?`^5Cvsy7*6g^y%LGbF3ly_ zIh&1?SOjEI@=n=|3IkFMo^+>Tv6~$NCpxXR0noh$$PTljv3xPI%dCk~F|BzD8VqE_ zA-{?T|K|-YDx<-mJ4+V}2F>y@5`Ad03DN;6T?B}B@unCizyS7!PB#XqLTn1UEW>Gm z3F9R)!eGN7HR;{^`S~k&@AmEO->zs!^p&%LufZcd2#@#N zf*s(yAG#yvn0C-?Joklp` zU`(L;yTQ-!0rxHDj0SEWnq;q!9aqMMlI(k-F2{nw$HT59zutAF580KN-RWd@XO9cf zHE3Lku36(sAF?a4*%^vj0=P3=pX)-%5<*|D`2#of_x=h@C(1 z0@19yJ3eG22tC|uSZr9Sc(T5+6p30$ zs>D833Oye0Fm+(`arM&ARNq|QMYS~+Z)UG}5HQ2@BgxY`13b@+`51C zso+J07op(E;Ds}WH3mqS)Csj`UwCcL!8)J_(HyvyWBm*y&$?GYASRWX*{^U6=|r&nG=+gsx=n% zSWTLuD-B4o=7-wt2q$HO?M8hlhf<+9lex@l&LwTRBzH8sjE`E)d8hLDhP*9#JM%j7 z#Jq4a(6yZf2u(je95{~jL>!fu!oqo&NCIekG`x%tSg&kt-3Uq5#8#*)^IRk84@3uh%BZf$t# zUjDB3mURopO>17v4>)s_&ioL^nGC*B#BZ4o@!E`sCS(v5b(hX!dX@|i%`S=h5HB;1 zCl49B8}S$gv%0CAx{e>ltQasdF)QXeoF6ma4tkqo2K`6(qNjKC^EwDefD2^%Cy5wq z_h&0*EiC2n(9s;+ZTiewwOQSw?o``Ai*iae8842j9je5sag}nUZC0hYI#QS<%oG|_ z$r43!hs6Z?Bn@NVq=*VQ)5vBhDaUE(f$A$l8`WJPcRDp?XXj|nn+I`;OmVnBr~wO; zk7~id&A=mPN-^)o+KN@PYbS;)$}Sry-hac=5$;DUwG+-PL_3YBfHI1&06G#~mL#jDu)AIlsM9x&tly|QBT{N3!rIDp$DOd_jTEx6py>Rr-iVGuZ0QS7O+*i<_> zR&u zobe6#1Uj{-e{+rX>>6|*3@L0M#J1LX0oq?bzruQU1$w;4#Eyr9t@HHscqTpMKVtk0 z>9K*Ql^?^%%8o)5er6PR>~RgM2^!a+d$S=yHZTdoY9jjCMR*=X_d2iA`Hh}3+v`m4>gN*VLLiOVC=!q)u-Yq7*)tcQqj-3TDbNn>QTwY#EMqbWe z+pE52pZJf5dtFqx;kK=~V#gm*vF#UEhBZ=9^cU`LgozSS((omG9!bK6R!)O%z`zUr0iTG26c~cAK7VrgY^xmla znj)r{ceZMeIi9t~RBK?f-2HAKa^8G4Gwqq2I-|> z8aoZgT1H7VqSy%fSD$P|fP^aL@E@`7(Z$6m5g-72e!}c!xF={bglwWx+0S5lG&39# zZD3}g+M)_P9?HvdVJ3DV11KQPPo4)K(wB**i}eZDY#TE4rmDN9jA*`p*w*Hu`?Yu9 z6_Zcj8X)FQleH;oW=U^Y6Lr;{Bhz z_DZDj&ikfRt-NOzHZ1P4j!(s##Tv$(^n_mbl1PRIE)&N%CaahE#subwGfj#XsS-zu z!(AhMlA9alDGt4Z&_&4XlxIogIpJBe)ms&O&i|~_Bt5$k%-1{Q*W`EPV={icp56RD zlxuTqZeGPhiCb{@#UP^qJECCwcExSgKo0b!u6(2K@B**Uqd=H|5)>Ku#YPWfgQFW8 zv#*WLg9ZZpCB?CM@?5kVUF7_QFQnJkEIhvCWcm}5`tuP|V*RS=xgCpO7p-6PW6}0& zi2lRh$$9A$>90nRf<=qdA3}*>wI7-=pJ}Cy1V^h9oX{P`RZCn8e7Cz+`6OCo1Gdry zQ_75jc6kHKgleNwK`@wfI4XAYSLoJwvN&0t6q3oTB3e|%L!ba=Nv7wNEk@mqR;%qZ zp1e$M!F5XT1$)+K@X?vG3)H+m1=?;D+QI9?wtmH;FNUaNE&=Z0pc&U?< z!8N-Ia8z#Tb1i>z`7P_#t-Ir?r_v1P{WH?ndl!ABn}9pmz9+875l1v!crfZ>YMB1*@N#+Kwz$D z33d(UP@Klqj}4~7zFDm-NakHwP)-LlQarezD6giVI9$sHw05*w5YDy~lz{1!mX8RC zjy(HSlD9yGyNUO)LK35IHb7R0%gzHM8#pIuF$pSsdJeRD0$zd6vF@xN(N(yHvSs!d zb}FIH9eQqFrh)_;(;QP}zw$CBhbl@nuxhdipppOkjQB#l_~A3H=`DA~mt1(+!&Ux= z7tPGwSg`6U61#o-*4xuRh_@_Xd+QzR)<3`dYG|uv$R(D}x zrKZ&w6R5Jdvbs`0&5*%#btkd9J;gqs-KFMDb(aAA{IiTGpNy!x1B|h&Yeo#(`dB=E_lhnZNcx}b3U;xjnaG3oh~Cx{y$8n=J29X zQ^sB}Y}oo*WRl*VT|24q(LKv=+9clnzfYzQ+_T13S6!-y$f8A$mfwBt!uuN2rT^Ph zl7MgewQTGJHdtA`fb69^!GK%T1>SY)D(`>W2?Bv!yS?0)E4jtF)o{V*Mhoe1yGh#% zQ5zJwJ-cMnb7rM$z>DdCN7;ZU3Y>Yp3*vOZ3qpAXzPx?~q3{4U-~;-@!Dyx)kkvL? zeCfGj@J1?4PvlTqEY}Hn}%18d2tpF~moJDomfj9Qt3XHYgx4d(08(RT%&Cl9DB5fUW zp%GWt& z6*≪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 NC1tZOiJIot{vZ5_jpG0S literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_backgrounds_800x480_meteor_rain.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_backgrounds_800x480_meteor_rain.png new file mode 100644 index 0000000000000000000000000000000000000000..f9dea94f31efe1845fecc5c9b59ed716cae41c80 GIT binary patch literal 327784 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%0AP)MjI$wY@cEC9IK<8p+4Y;WB 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%0AUbBPb;f^a7Mp*s0C(#0 zpuH5%z{6~2da7^AijDtQb)Mwqo4nf6?krQ0-N1!_wGDV3#3sldN8q^rT8DI2C_KEc zzQa8-iY$y!>h>FOlE6drQADE)O82zMM;RHwo`5?$N=Y!+y}XsB0P6u<$wzlO0V5+$ zomZ()y4=ukiVwShMg+uYfHRvIiWht@2c}1eDF^ZF{~t%AgA_()J8;yiXOj3+_vE_i zRRPrVJG!2yI9G#LPxnp0PiM9^9atf&*;-d^4>blID8{*^uA1f9GT@)w?z>Dj&PkUH+IGNIZq=pX^ySi1!J9Wa?8fHl0C3Gbh4_j^ZD zo4N035t@z<*QMIYlw0YG$Yg!s;3;q^5FT_rdJ6Zlkvy9rTsy%AOWF>LL*^nYS=Mbw zC4opaao_yKorMSlOYb45>}x?Mb;R}SzC-tD2y2&?ENy10&>#Ua1fb6B^_yT7UHv~EG#nL#H@KHA60k$$9p=zBeacg8j^-&5Jz3WvbV z?DO-7U8npm8hh+*_qrb&wXb=F%wF2Jwow)*e_Kp2(MHVa*Nzby1X-_1`N^w0YQu z-)CL~O(W*Uv?`;ba(;%5LJuvTM+lTY%o3c4AY!gIoDmh_V0l8&d87fOF$q9D1#Z%C z36Rr}>7{66FjR9cyku#YQ+G9{x2V2(XnUq-gkH6sr89D*?5s`j)6Npt&&Q*)0zoCEqZ#h-V8xcSnHFe&a2(v=Of77HC!V#P>u~DW7k8f;?3tp3f`= zzuy~@bbXihMFGAl^WEO~y^a&u0#I*3o!21785bk71aMsslD>?{o;$`pi-RP)0>DNZ zcKx4w!o)w8hxQ5p#=Y~N3T9qc%UF+kUXkld;IMNJT13pZT%R4!kp8rt_L#0*<#p$U z5-ig-h3`gWtj(D58sRAL-iGf!_rj{V#*;VsV)rTO4n14^qy#CxYrwxNa>xrSpp9=q>5&V^B92|1<3{+#803%0DK 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⩔P0->t*JH*#d@TCg@0~ILxiytA z$>ycrygn$g!C{`74;{-I;LK};UG#lLo!5yHC-_Wz#F8a#pth~e?RI!@#9mwNhm!2g zk&PxwiOWV@m(ZN#JO73af7~nH=thH34C_9O>r)>K*xtOsL}nsZLQn(x=pFhVZBx@ zPh0K4xqt(!g4s7kvh<-kF%{VEvl1+^vJjG*0*gbs%%WSvI8K+^JQDjc)1-Ep1P?W! zz=&k+p7{@u001BWNkl8bEKEMP9KR-V)Uv9{z zF$lWN%rb5mNg6Q)2blV%BG)~+E-QdrW{uRoRpY$ZT_WTJ2~>=948-TWPIS!m$WkNr zX18$^v86&>I3q_d=^Bnhd_j5=#AJy~jc)0=ZeZ?W++=(|pAVG#i7KiS9D3)|0A_Gz zM#ka$>(_a<(>9I!Zz63tJL4@AMLl!hx0wP8Cwj3O$_CerJbEX4A9;Jbm?yLEXx@U%9;d{=8>Msvm z-KD|E-W6;D#mo=d*3b?YvldjWyv={fiY#rImwXNB@zK(Q!Qf{8X0nMBI zBxi&fRNBHKtH-uTPm!NH4;5ZLHrHY^^A39IUd#fGQ4i29fjSfY(y5J(M0efTY?h_f zeQrIIz)(Y4RzQ*@}=ygc)v%mL3;lAiorA3KR}+dH#T8c*P5>C~y9xA-*2df#`^s~wYm zzhA6T)gyF9R@~nTA3Yo$L*Ve($2>Up>=Q+0$~ZRNZ8w9X8O*+eACtCv?)A5S{PRx% zg?Wsa9*~jhy6}t&2h+9*RmG9Qz|t3P2IBpa!PDr|Fm)xblT`QKW;+d^K+i@bMPuJP zyU6I796Oznd~QbJI93WF=d6V!Kr4bYYZQtGh-CztOO|LQBdhC-cd{AATHw8(*&Y3q zB6^#Hl$i|R-n*n(^>-Myp=il7s!wIaHM3o7q{Wmvpvi)vv;2xL0rRd{;$EkYytnoY zFf~SOyw-ZLbc!uo33j_e)paFmi27O~pf{y002XwzjP}G@Sap`jTcTqDbXZ&cqyTw9 zhQG3*D=w5!sbOHHx%4hKzZ~CY6fE;GCoQKNH zXzb!%JVACoBdB3XpkNh!)ctsVjjxM;exJVfu8e&xvj%_bHZj*UWT~vjx!J?m4@IhP zyKq)Z&?tz~CtB}!o+==H)O|5y zv`vNUp@Y@w}N?TY)6mPmNpASlO6sPE;JcXFUXh z;`_sjvru`*@5M2jo&7n}*SDV(FFJOcQ%n4$BN7Ovb5JvnYoGF>V{@-lZZpn0dGKO} zoNIHkUfmIqt@brSw>gc?^6y^FFh=4l-oM-Ky?1u{#QIV{l1D;DY($Iw;8F3$^|5X4 zfWOJO0+|EO#8%LEB%md(qK@qW7CIu->7ogPgmUb4E>?i*t^Fwq=w#`b=**yzx}-_= zG=I@UPHXA4Y|diY?5W>5TQ!)(w89*~~djy^r=aSUU6PkTRW#X0~W zlZnCkuL#P?Y{(c#B(5k5H~bR9wHRRul~)9PAtU4WS*JEFm2`THncC(;Xq;UL2<)f; zcu-Hj50wd(f6z#lT;q>(Iiy6cV9m8Wq8cMm;%{1mQEK96>?e6cLhQ!kQ7v0l& ztRPR{iPO_})*q5K1Wrel9)s2E%=_9}v>E1oT!^&hi1HySPXi`l9A;<3*^UlU1f<hc0}k2;zOohyUV2f#MlshB<;+4RJlftel_dAt01=6d;WM*%-rq{rYw2!f4?*%D#eU(Zls~>J*NFnO2{lYdogA)9BX2 zrer)+e)`DZL5GENEZRb*nP#Ux5xpq?;z7zV*FFLh`vAD6heU7xQ}l9O67;tb&YI+2 z4%2;rU98HeB@Z!v%Q5V=gWpRTfmya7Hrl}&0OP@H(yjhozwUEoBNsVgl;PQAYu#10 zyR)g`^*}(Zmr1vzuI4M&2Ho7aw(eNeV4nYV`u=6f_zm5XSZSF`eu!`|I;~RvRdo#Cy&;?fcDccbcDG zxt7&wBv`*b^+b9*D^l9dztN3>?DJX3f%ts^#!(+j1ianT7N#D z8oZUf?5c12KHt!5D+7d~w+&7)oDb4*#rID6;8h)-KmPc!Ifq^UdfMGafc%9pp!!Epe%_z=8R27 z5;8_wNLWU}Lvch~%ul?Rpvb{A=_C(xoOwEEUZLy++B=w+hn~j5H&RLn$6*QwD0$$| zy>6Q}<5?_?6T^~5pZo1$4r5x)kaxVnIltMF5@0hsb~~#LxE3y3&gUCh zYG0dYK$TF1BX9J-!tgr&Z|7xvoVd11TtY^>7;T|S=-QmfP~ z9g-0|K;C(?>7ABzEXqAapTKjSoecIvUvh#i{nOJ}Xo-#%Lq|w}1Q3KM9`J zS`o>X2N(Xjg)X>K2gM8KO z$g{hj_<9^g{r&YT42MSn1>TRBY2+!5*N)6qAhP$4Y$*AK`fCicd5s5M(y=<5X8lbV zw;2&V^0oL(j^BinN}Z^+>5V3+Z>iHYrsU~ogM-}I>RH$OdzU=}j5=pI#sLabPGxl( z!WNy9vTCH$p$VDXyV;)lQ<38_xc8(2<2Nu;f!2QL3cW_~PAz91BU`G!8GFrW!lwpn$jtDy^`m<4ivUe%TXCOs$Adl}|H`!CCi5Ay& zMP`Rg5%b;c@0h2{!lNV>zf-rw^=mz@DdpkA&Ox@n({1%x*I)nf&p$gLlJLu+@WpCp z5wsI-$+U{t&=_>$mBl^_r!-9kN!63p?-I84{dz~7ODCUxieM$s7GqXLxYi2C#ff8& z`BXztg+RZvJsP7mV_0~+U3u!dTjSrmL?Zd@Zmg)VsH~E?JffI2|09y=WP~}Mj6(40 z*ZKXG3Uxr|sbRgsU_!s}a6{FVhcK#J+BwDNQkryUovI&RWEcm5|LMxGssSU76#>+H zJx$*oq0W_`{p4$d`>pP!${d+|M$ z?}+CjC0+Mrb-G8nUW7vHye*7c?ZP3NcBN17(?LpKkG_fcZEg5>L|Skna&Ek~I8VTV zOJ)r9Z0?!yb=(ng(;k{_W+Qmd!O0lRX!*kgRx*N@Mv-;SG(25b_DEwG8C>g5!zuY; zXP@hG$aM1mGKgI_#{|}s-^{XG}z zDxM`p-f+&XnL(CD@NA);<(2`?`9}wr2M{Buc#gM%qH0&Bcb>JoTBn$MuB*JT;;zaMH_pc#Y;o9@Q8KDAf^4fKIPBfZ6q( zuFEyefElkX{61%xm>nDcua#tXY7uwRJ4FS z?~CvGjC}8%Z}gn)SVRu zM}m+1k653+CyINn%qsq2RDWL6K7Y9LAtz$njsT!a1C^Z*M*({;^j_bCrGPXuX}!EK z^n^~J2Tdw1R2@;+7_A9w*W-&fmyMA z*Z=$)!cu5Yf3S+pwViRz@iy!Yy*@4}FZep9&?U^x=F`nbvT+1GqPxHS&HpBunA zXE<)1e-%9?sPCY)E3*!C^gSBkh!Db&(Y^ThTSSLoPv=&=T{A4}Go#a0Ggcfwd6M_x zKaHkT%_WKu4Xr2zd)W}wNT92wD&hq?J-SkDM}kI0RY&j^_shK<41Q4x(p_ApLG z>I$GS0+7to1kFQ^^F6avq-AZvN93tt7SVAzX~Az>y2HVFDQUqRveZ%Q_+SxIzKqv< z$RA!%3+nlF%HCd1tCfd#&FA&MTL&9j?HZ(tLmef^#gn(xarorCZCRRSRL$|M9tir~ zi+txa`aE>|7$br|)_AZwAyxPK`!BZ7tni&2F150h?g}1VI}Vr)TXD=gX+K5bhoX>xjoYFQ@Z}GjZHx(-et+>wl@$>T&a;kCc1G==qxgH+egCTU}t;~Tsh+sE(O=B%6CN zs@--5E2OLX8b3>Zd*olZL3T&g2Htr|bAATSbgy0^L0eB9L5ER43CipDviy~Nl1)-} z9x^R@h{mwLq^-IVnlZSVc8AwG(7wz@KF>k6aF$B;eSKv=dk~Ie2<&yvCG%?(=TQKr z1{R3dV!s&dThRH(x~rI#3B@DksReY3-|L=@PuW#h$fnKg6X{#_78^ylmP z>)-$5&kiW5FnU@j1w+PS7N+_gc-KpxiP+si(IDM0{I0acjE4*clYXAr1C1?+b!n4x zbp!~KyE4-_-=a`@j=-^lu)0B!FEXh9j!5}YK4H+sbmJLy(5owb2Ou>ArR%P9*q}gd zc5z|K)Rj6xVvf(w^>u9v&33lZWj8Lrjt1Q#auf>2>##1oS!*n zw4e=x1dzymEn|!Tr@Br+MT%Eo%mLzY6c0h@#C1IqiVZNSf%`ek#*uwFeuv&so+cic z69)QOf~r=pJY;QyzqH10U{ldT>d@fB7O?8y@A5?u-0fSpqXbjAwmY0<+a5vGcO1;D zA}jxszUX|UEYQ<7)c{8D(b3ay4My(!K43fL^9@w!{T`UUTi7dtFZSNas;}*v zQ}X6CbG`JB_g@J5Ovr(BMQLHYUDx$-T=DKT-E&1m9+duyK=bIPE-!<6|&@%mA!5tlx049wgG>KFsNjTqA zQNa!k%>DhE`X;kQB0aPc9$lek6lASCJa6BFa3c~9rGt)9n#)_1P4kI04G^hKpEW`?4nXRB zp+P^LH;YYM{4Qye_pmZvf)1`3`LY}70K#aG$m$i!Nkg1!FtoF!YMwY;VW2c#=wJ!15kMJx`WcwYP-YnOY>Vt%7K?Pu`F zgN$@|%u3y~K&1GhtnU~BPU5zf^3omLUP?;C8eOxt-$kW|H2f)N)%bR!{XgmBoX;~t z%&{rkDZU_J?M{YS4FXlr^4ue(YzD{I^@V}obdMF0-r8O9clYUZphLmAvMkiBW;6Ez zm|QP@*7wCx$Mkzqw}=+{xeuKcteXW~WyM5w;IgW~BvZ|v`12f8?rr#t_9|_L&&LAP z=EhyeD%#tc>$k)4ao{`x-1Rx?`a);55%!Dxy8S#KXU;sIWva~V{73qeKD4u4?!*JC zU?A>cX2ospc{SUYrLQFf%3?&TQwkH7psWnX0AJUcDho6}7j zKh%(5$TtwCQy_xp>uK$?g}>O!#)kg4mL1s#^VWciXT_=$CfatL&@orlOSST&>ntyK zP5UX^!}}x;=K8;7ylj|v!IBr%flvj76_kpZhq0#X9iUf_DuqG!bV6p0p2`TSgW^$) z@2~&1y>7F!2pfzL&j!d5Q_fRMdEd7iUjo9zI2q-jQa{gG%l3W;fdqC*uMte9lqeY~ zt{eYz&9BM?C0N|x)j=26Ye}%zDvUq{HRsHI8XG4l4~%U*)AxPe0miL13J8z^h4l)O z!5?$Z6XmE5puilBDUEJ1rlTqyy+;A*e5#b{-p{&t3NVec#>@5N@BCipQLY)I5x)aB zZw^VU^{S4yKBsZ+^Y#NUtvs{r7l>Zu2R4p;Rw}ouq%PGB4*~j#YZFvy+#Kr|qwt&V ztF>TFHfeC*ceGtD0DVeHXO^RnLrz#;3l;)jt+ib?6ty-7;7tF|F{7(g=XuJ`7*!5E zS~RmgBlMDJNTW-BoQQO9vtt~0LP?Knwj{r{`yGcu^*5S$Cb?_rCFY zufLBmo8kE@3_7SC<0TC=Z#w!u-%-ZA)++na^a|rEH4lE&hW0$@HP=Rt6>Ug~6rVA7 z=Tdyea*VD|NF%?O4q(gumS*1dG5O%>RCIly>!_c}hg2*2yf+ZA;3TssIop}Z?uQ8S z*{u5}*x>W@9qLf((Y3V)tAQ&^ndy;TKA-DT99QU?`_3StY>C!eE&EAxVS=@8tfPf& zaK5>wI9JIm+gu;IrY=A?%poVQW{BnRD5Ek)21%$(yH4zKL?pnJqhF#M$x@`=7vdylK^X)aK zUDr>@1^LdaGpfw-USWSvFhhG*%$~B+ZN7B0Z3Q~9I$GmhZOB^7KA)d6o`bKYdu)Ur z=@>iZaYQ8toePeYIxqg-%PyW9^oG4&=1rYc_-Jjr{^jrg@nXek>f z)_WV&Ds(jpB!c_3wU57EpDSzBHSdyU79(Oko(d|RB}Q1oq+p#0-qQ%@CP|jD4LMx% zbU%qrL^X0Pn#=IUS|9L6!5u@VYt}4;ewWfq<2NJf8phI`OW$b5dzJNB74Q~=sMdm7 zYkQ9Q%|R%_Whj9IDAz)8-O2O(`Pg%C0J#H{+F69W#>lTWZ^{6&9H9e&?jSP55cfN! zN}ovckN8Pm3|fNUQ&%+SaP7x;_THs~k937zJ;J9o-UncFe$Lmm-Z<8{%}+qPgXg|p zJ_ZLY>;C5RmcYIPn+^;gdf_~iue~!`q==@*r?t<6K`-!i>Z0JgIisY6>zcsHLhc2W ziq+%T4F-H~(_yH}77+w-owR=BXU(G+#Q_-_T$>C?$=3K9R(oS+(V^#pZtCSIC73nq z##PF-#!aWsX;GaG*||KoiEV20S~)lxk947)(|OuuCtJUE@U3gf8~yh;yIbZm?C^sF z5ncZXJnpo^q)|Utrt31jN4r~P2%Kn9Be;FtvT{RBzJewOti)*ay zTN#S(C!D0#&w4I5-FBI%cIh&mOVI;IJ@{#6u^Bwi)vyPx>8Rzsm~lTmIHa#woggRa z1T10uKA(@b?gnq^`CQv4t#v@5Y^jw1AlIV<;Lb}|>{-Y%N;}zc>L!jQOJJXSN%)*I zaNFDLFMs)8r?e~g)L!!{I*Vhy@4J*j4Rfq>F0^47FT_#&UDj(bz?9ns_~IsR@!+|m z&&_Jqq-RknXL;?2-(#**b{dpe*l`?><9z)5{P-drKp}uG%Fmg#&3)1Z z+~2qT{PA;UolGz%H>-oN!6YdVoDYSoFMd}TUC8#%v})daCOFV~#CQ^XRH1zbw_=p$FecXineTqrD-W7jM+7d$2(UDPJKQ0AcH7d&a13A-hcI;4ceZ(K2(p zf*yU3vLVpkU(#8AAZ;Fe)&T~i^r;72H!4U%XSLfW-b;XxpqClIryj|%nwgDR%YywU z?TXt-XBK5*bdUG8yIs!S0wbb*r*#K4WvoTl!3JA(Ds$`^<)@6Ek(D4?Vu|NQ{jg7` zw6^ffRS!1h`Xv3VetvAlFniEu2pg=5HzGhWGxF=Uk#zOv{rdHd1!4x|%>ko5=m4AR zCw|mC$eT`+daerBw`ZG#4eFtN7Wz)*?UBg^FPkaDkPf)cMq^s6MU7LRXi0TdL!_Sqi?1h8* z9NLD=NKu#A$&yQtIBTl>P=EJV<-1y(Vi!l)r*_I~?N-R_4+9 zH~;`307*naRC6y7GkaXuZVSwk5B3Rqg@0jrW>Y#KBU@Fbl6bbc>t2t3jxhox1;Y+I z54G}L3Q)g~z?2qHwSDXUMu#1Fo_l4fQ6~%)j{to)h^3WcnTt9xSh*j6_Oa_ezVMAf zF^>K{E*e2rFcG6UaZQb=7qB}L1gY(!t|{P7-7hAc!gPRw@gq{ivmp`?Fuc-9EOk}@;rJe%a*P|DEHnbFu34gsU4FBQ-j8Q~-Uyg3k(`)34Gk^E(I)&LS; z(rNmv%RhrF>O><4DI(~0&K^1cY?$w}o7wFtfH3rv3^wV=JtE~0u+1}3-W$O5fI$Zk zUB^XKHFV=AXh9mh9XJ>cOnHV%Ip51tc?Obnk;ba$QC_<)=NhsjP~joJ;-J2P&D$z9 zaVN;1e-)h~kXOJrc&a-ex+nR>ZRdNCqX%XC{n*GL0bK{AxrT38C;0#ku*=Egywvl?X^PxZUGVLpS;xn_}cwp}x-AmVz7wY_q~*f(E*Mb|${ zCeHGWqrkadPlq5=>YB$oC3RHHV`OHdD^#cTQ8r9JuKl3f=kp08rhAkc;*$#9P$s0w zefpo1M)5s+I*+FndY#CATHBZA=+4jDtCUAl84@V=d1#zL*JgCZi?&?PD6-e1o)IlOF9P?vRf>K|3INoN>8c z$&#D3vWpa*WYNvDccNiENm^sh4rR~iVCvg#_sR{kv8EG&7qf`ak{2bnbh>P3BLxOR zItUb#$kFI_qR0d0&n$njQCJ(j5_EVO+4Z@?vFh@_4qx%bx#qK;x})puK28UBSCq$! zCOVX~^HbMnT9YvnfD}F$HGARr@U^V~xXQT3MTf=#3NkF~cG;4SpQAW8V~)rq_230{ z-F01uhq7e2&eaVO_Yv%^z-xkP+Vk$&}zR0ienAisZAzl9eBCJl5Y6<{UHe4);&&<$DfR z%kXzv>-X8#(f730J)7e&_`E(gu20~fF*2Ye=RkPD%mN$4IBXyQG|N9?!gYe^l>L6l zuXsN90oJ`h8k;gZ<4L|NO_FX7zz2jvnq_e+5}QyeSxKSlPQ#yi!X+bbzx;ySEU8bqKeC>uA`w5Ftx2n|BbOqSY*VjVcLqYZfC*gJYYN<;Q5~oqJAHR!BRnc(>9&aT#3dg16Qt~J5fp|0)(dSE_to-$83g({&_1RNVdDVGE?W)^K$ zU5_?8ohTZ4!S~FaOvs6@#X2@X?AgOn_PqJM$XmzI3@e>sy1waayRDt`bS5`U5y0!5 zdR#Y1lh%@Z{Y{?Y^C>g@**7-ly)EYHeDa&X&~M~Thm{Q*k1>!oy07ctnz@k8=``$) zLjjxk%!05?_vdf7V(5JP>DV?DC^xgtVd)+^R{1b}3z zWgV0Mi?vC`SeV+`Eh_}-dLEkqXPmUv_|4j3cFne~`?l+&cB(#v+$*PX2iu!kz{Y(b zW9i)2(i!Sy@_&vo$HRbe=aZPjtZV!xL!FP8WYva^kpUe&M|w!vPL_#L?<=5M^-QkI zoOyl@*Mv5<^6zsFUFK!4K0kjP9Fu`^*_Jo_b^&KrUQ2!?4&kBNW)|2@)jG`LbIeX7 zIU2QcN4(l~n}Aa`jM;X7v#AC7VvKKgL>%@3F~-ntjA7Xy9M&B(o;W~UKHPIjAhNNMiAze>FH23P{bS`9WTj*?&Xes zg1NP_?l#uIvQ$OgD};BM$`#-Gvuar&pG$etoGIsV?RaMK_Rg|8mW9v=RsJfus@gUykK|AT*2!pOBUJ0&im`wo{cyvY31Z*ba{vF z;oA4WP0Yz^fPi*F4o#;^2HSdx+6hdZAfMKZ&+mJJM8sa@UE{D-_uyqiA>N<=l?vi&{5e+zt3F) zcd{L>+oWeio7~tH$u@9ixg^-&A*bs}Gb4Jq|v-i^G zeo8jwOot#U0HQ8_;sM^1{Pob2n%mYQq^_K&+f|lq59rjyh+Ieg-W{KwaX$+gC6`$x zkY#*p?X#CT^)K(I@$(!RO@?@d&K&8>VBg+VZ*(U^I)d|%gCrXBJ0+mB&Bmx1b_Mmn z-|7>HU*v%4b^Z14|M6!=1T22i;Lreb0XQisJc9nH!~a~5l(Yz_nz8u(bXwV`_k46` zXuv*{@^Mz?7`AT!C2F!u|% z;GdLYH$JD_BIY{ggJvDv(qW>22`CeE(RgwlN%J@0+zn$YXDiQ?A|}0a^HnMl-7~Xr zGt0^jz5SMqfaiL%3z^Goroi={XwbnRd5S+NlbjF17kSaFowESI7H5dSNtXiZI)!|# zzw^K%8UWmzy1uPD*Q>8BdE)^Vo1WVzVrqTeNsn3YE#)ic?L6(!tnt~Q?}&BEz(kkJ zxAiGb<#9Z?A7Km!^#M)*I;4wruh{Dqygf?fOKpyW&cjaz?)0Xtb)eL3hMs3;aVQt( z%yr_cMAizhKGDuoTRi96ntQM(34i9>HnP&db4+WgbS2AM*V<*D9vyzw?xzn}14F(n z(%UC1ie?P`#RI?g-X*F^=P3E5g0j8M%L>EpAsW51oQ-y#ASdrrWh+3*umixeBt$?u zWPDcM<=I$t?)j{IPr)gtkMp`2&m#&QBb*SwTM6taa1*i@Hca?sHfP-RxaQLNy9d;$ zcdPxPeqQ(5%_74v_hKFK<>E)jD+5 zp0&(Y)=Uf?*n*MFT(=xOCx@Dx>*eyc71*v@15wr_WDw%RQNbuKx{O6zLVI!kjGD|Duoc;2UB5@URG+UXv6$Eg zE`xR1y1zDTM_Ruy+=;r<3uClf#zax@^t4(OjRp%T>5at{aAZq2z4G}kWT8+GK>U0@ zHm+f|vV2R*)?N&AGEZg=^h~GiCm5s~1ZH6rV+|`%M%6e*Mu%v489AdO*DK0{PN$`Tj4IbHzIU7~ zvRlx_hQdOzp2dLf41nnVv6l;SLHZQX@h1O6BTgC9%MEbtnzPL!>l5>Wp`knlt(8r* zTH9Y~IlKeZT7^&b+_jedP#^LK{0yNn<0iL8izq3qjCy#R^ zW%4L~&cEjm%M_Oy@jT&_VISe>@g+;FbfBPXU-?jT$X%>!uL=y@_nmvgdo=eF?`1&F z&dBe-|K8Rx*A715_u)JO^Ka@qsy|?QWpEfF<9>gV%m z`lbaBq#PHPhrIOCQ0jO4MRGA}MP0i+<$3y|p66R&&n6%PZ9n%XX@z&;yZG5WcfxkA zz?kHiue>0>U3FgxWtPc-tGz4G@AN`6dz4ehxWES*4u)GU4>s5c0+ zb3`*59r7it8)E;dRF*Nw#4=__zCYh>{xgWO_s%<`#0rbe1JcD4rLP6Fq%qw=)8u1z z46zOm3_tIjnP(7_7o{p-pmUh7lgF&+a1KhCyTiP~KHc{xY2O?ofM@BB!{j&YFMj6a ztH5sQho@7mfnA{cu~*Q4kYm=tF6U3j-s#~^Ap#4~apx3<4R(@Xw*2rl2YIyu{eI^e zmeMWEKOH-`4QYu1P{s=XvrJ%*_n-gvkDttB#q_SI7%Ww9eHc$`gT4Vg5R5kkQ6$ci ze7=7dInsWb8#X)1g_uAl2E0jT0Mb7-tr8 zR*2WW>h~~ED$xz5>P|UoUlF4#={o^rMO{_UBizhuP<{O6_X&_<7eUF)Go8uGoqv}m zcPKDb6^keV8!QM$J99y0H*XGGfytT&B6A|rfIssh-Uo%yBD-Yx`0wZl!$1=AWT%#a zbEkX%biN{mrS)$H;!innenUn83JFnoF7ZJ$+RrNVh-pP_I&C2MzdF$Ss}JbG&oO;- z49Wm9k0L#bT2gMPa6;aEEU$Go^Lkuv1(_Ek(LS@nNA!^Q0(0j`EasN`O~7dGjjGD$ z`&+nthr6WYCO{6P(${!b(YNLT@Q*#>J*YjCmYhMTs*(|eU?AWZDxf;DtH3=aqx@f zoN34M4285-)xe+FeB1>Corxe0jQ5-~qN(5;wxL%ZVlHRCXx`7@%>7NBMFt*sS^*r@ z{+H9vYZmE&skZ|)1-~}t?wISnv#W{oiMY+P~gEHAnNkmbxNH*!a94UhUR(4i7WY>DbFdNOI@^N z?Jo}o9g8zgzK*p#`!p}HW*x~qI@eKHjk5x^zcWzAa^%00=e)zVk*R6&0G;ZxgbZ9^ zr_AQULDp(H&Yjty8>*31$q>#=L3cm*t!R=j6Xtg~{uBf>OTCHp-1jZ}kAM05&)HcA z46LGJqdj2q6cueG6pESE zypv!Y9j?P;c#pAXOy6VTe?H!s3t)B)hQ!*NaUej;pF@4{Cpho)mFV^Sd>1qKxlf+E zk;c@-$Zhy}>f1;(}X0&b^M|8xIh~iWYpfs-<&L@7JSuyDm05i!lJ~rSCxZAmCM_X~Q+*6Xa%j(J)>~LgMx0&k=cHe&f0ExRWp0SqC3;whiy( zO9(mQ!sVO^K4OZ`2=cG9RQzw2qdwOTyyn`Vyg7n5qdt@N7%MLU8}noEFz3k56XXl} zf}MbzoD>M=@$(tlTfT7}&#C&^js$~Jy3h}U#+VD4VrmRw6nU58JJcA9NCjc&ofEXO z@t*(_znf=|5G9>-<8fvg55}8dlX)l&DDfEEFzj`E=P=3`rvsMC6cj+=&PUSb*Z$2s zA-%?)OH-Lg7z6>J!%>>Fcmsixk1$`=r+iI1Axp^L6Xj0a?)8 z-{U^fOf@_)M!T{+O>LpV5CJF}UbH;t*3#G-mnU*eHZ& zH0WLqPmg})UQn92D{7Gv{BC>!3jB9*Ak{fBYrShsL`xv(Gt%MAhE~1!T`Gu7?@Nwx ztQ@t&Ut&iALzLWp?D2dLrf77m0;-QaAvIBC7U zKlc+qYqYM&WS!N~wpSwZ$jHHw$#;olEv8?z`79~p2vr9K1;n^?gL&``kmJAU6rdcF zOCvb-UA+EoNVr4}&OP?%>+7ph*Q;)=or*3yg9QNTH~e;RF=cK#YYD80ZQR%aMNlODKx^;!pFIOSEI)YHifo#g3b&QdAc?sn4gJGsMHuYQDD9h^ z%+hMu3Eq!i*}B>Xd;EOv#RQ`HT>`D;m{|tbFh}gC2N0r^EjVr7xQ(iY-Zs8krwZ{x zf$Yj8XIpr@QLP_$TK}Rybm!237LIf#}ozkz6|J5^Q4X0tA zZMV7Mo8MH=s*K&i{iF91!dZ5p*-e1|XcXD}WhiTGx~IKK*uXrLN#OZ$3L86xQZg2l7EL6= z@kXNpjG0Jw%Ta9VP;P6jq=5>Zz0eUsruSj(%ohM{Ai>(JIW>*><;d5C zb4^A!H5=Wr(4&STqw|nxz6)tbe?KxIy@Z8jhh@mjnnROwjK8CU+RU5w zJ?L|05g3^Ala7vAT_&hC7vJA;+dIiF{?1@Qq|O0>H{cMXTp`C3$#&}udec!Kz{_GC zc-Exa$F2eRrjb_F)GOR^jOCK~DuE<9b=^q}TO{c6@_hHy$xTPNnW@*jUT*0ybpdmbe9M3{cBk#flby}s>p;+ z0Mz9~qtwL0#!ZmR0FY&%E>J6(VOhqZTGr8ZS#XunvOR=@h|Y9uM{_<}vWk73PCTbH zS&u-MG0!0@GaWmA2kRmJEBScK2wnt`M-~D+#5^|xEHhZsvJuo4_rXIiYsTLhC{z%O zjc^&ib3e;Pn1|p1!O*_7zvQ{69OZk*MTdKd-4$qY=S?5;<+V;{GU}TfkY_uD=K(PI zXCeUDmC=XoNE(PFZ=J}faz+I2#vaX#zew2<)^iQ8i?lf-U}C|GC>xz?!gpph1)pJR zvW;~Q9pd9k(8Eh@+zxknOkGcU5p%i%fB5U-T*vDAii5Et5;rX_n*abH07*naREO%H zXXU_a84(uNyWLUf=gWEk2LG>=i9j7hq#WIe)qTckS_Z?c}CdFbA+>xwLE zIeXJ4aVePD>;Tz=Z6ey*GEdsBxATmFS8-p{-don!mxxIQCd4F~>O4!A-)t$~2>|V& z{k=tWexER(NFC;n5KDAoqp~q_YOuE_jyL2pN$YOQ^XISU>k4~B$T`c#@oegc1!tu) zRNh**-+|U_7GcHGOMG@bElPfut3K>_zzB`4_MiUtpFfXP=YRyYaUl`3{Pc<%lWhiR z<$y4Q!HaUGc*M>fkze$gzl)h7GJt3mN|*AzTJK)E>WoO#OQ!IvQkzM4Y~YciQ%i!v z1`=@T4-V?gY(^Jetkdvb8Vi$sV{q;`mOv23MSH0Mk5M48N3~O6#zke^)^R>BB6*0C z%g6BjSq9S2UT}160Igk-RPYSy4QUIrgk-jdQ?0W;Mc;`2$H8U@Ju*1}s~m~P72f69t2%0^>{rE2P z?c^Wk8SJ@aO zxo)^CDHM3%jff*PHdgoDdz=rC_q;kjOm0=J(KWe(B@apLjIlTk^uwh`WL}MejmSs zd4b=@!67)>m=j-S*h2{;aHSkT9MuTt5Vj(X5-poBM*>T);eSLX$c&q_>i7PDT zK9mjfe{)wwc8oD5JGl7{?ZIvb=rw0xlu7ru(l?$Y+Y#3Z)m(yulBLH?5VYWnxFPq< zXE>lj9%>^h@JF zp?FkCSG5l0@%HY9=4}I5nW6+IX?CJLph~2+J5Xh2;fxJFD$n+_^S$gS@CHN3-@eBR zffa-cMbWrCY?M!Ff3CzL)}l%4Vr-9qf#FpvjVP*OqEa`GBJ~WXRob8IVWWg2l}_ww z{Y;v{s!Q?6*&OspI+LS?aX1?KE91vM1FwOG?R~_{71@+@Fho4c1Ab!uLL>&thR@c( zwoFHvLDejkU>acl4OD86jNk*_yU#6Ry-@&w8}91?7+Sj=Cw>R|lk=QV1~x$`?-v{B z`R>=WFUf$2%VcIg$iQ=#v;r#Kd2nNhI|hob6)8s)x^(Jn0qg6i^gd|HmxCgr&-&@> z>xauuf*g?=wsHxAZTlnV1@BMp}pd&Byt){TG)Wg|uMf><6ic_5v| znm_Km(a_Q0Y0R+#EYI@0lp~Ti0D@`w*jBxL*wDj1Vc(da(9FW;@^q9$o)_9yjdaO= zWzAe~@_8Tz6P$G@@X&(`_+0^76ERH(uGkbTuAifO_uU zeerGY%HG+7uJcS3n$6^T!ZFQYgE{X3cpET^Q2E!$=z`9?ubg@8j#p(AXNfFl3jnM? zK`V@jXCW(l@3bY%3!ufJ;5h4BjXhp_%f7yZ&tmYO*WPi~@FVx_CD@!%zC2`X`VszDhd(VTqQG}M>vH0t=2Fe3t+D~82Mlv7QL&PFtTCgEu{Nd|^D`zg_XY2S4e2_t>vx!q$*(Pw zChR~-U4k1QIJA%f3<{vd_QL0gh$Ffl`aAgjEZ+=BdG6D`V0?_jdpq}NMe~-KsQ|z7 z`asvb+s7@{h9N0$Xd+42*U+Kt>3)Wg$X3xAc-&wz_b9>Am z;Q6=A3!zF*j`Z(7nmokZ!RO$$wCU%F=*mnk@Xf@k88D-+e9&h*Iz1)UV@D^d zEmC(wcf|j2UzG=Nd>zRrp({J?Kt=>I#hJw(U`@G^!h^o{9dgiRi0O-Wu#Q^0+evnM z8DsG!hKc>jc1?_m`SyFg)4$dk5P(9ySdN_oI0N+pq$fu-UF5;YxU2*k z(Mw8pGMS{Z?4=mfII|$*J-kR3-i-904n$Hh#RfM}6Iuv|%9wF{qdG|G3Sypzh<1m2 zw=#$cjCs?z6eNu_9*bFI@~<0AAEp|uAr#c>(9NR zXd^2~XRrW0Wb7(C)uRP`I1g*dPy9SPUTK|=s7HD<;SDt8Jpc@*O#Vm1_;fJp=6I}? z=L!K%o_J)w>N$~cJgM{y`@x2WqekrLr?SxAYIO2gdlnfK>7A{ZhoO9{B*MZ;E~SZR z$J)d384kiUVmvOs!|iwHUUu471P<>iqtFlk@i^tMOYtT1$e`0KUrEO=!I$Q}7ju4a zsF@}R+9p)0P69h;*Rr@2tQF z)89K&5wu?a#p8YFF=myiq7nkX<6z?C0poX_D)a94 z!+9prJ)d-BtbtGRUpQ2$*B=grHM!@{JlyW%6CSg- z@=<%N2eR8_HUh4Xz4u>b7HQ(Wwx3c#?6r4fKQ12tdLDeEIFDgf8c&Wv($l1s(sCC& z*o7t+Q3C!JIOV-M=VTU?^_d8QAaLv{ixhzh=0om2WpH2!KTQ4r?kh)^yRxN8$d`kuj2;TdBvZ&5bE=ITM!H2+cuz)3SR|c43&!Dga6QTwZA&tQt{M|JgV6Ytkl-U3q6 zKUpzy^tHazyMIB6cZ2mTxk+$J<3s5&FesU+`SQUz2DJ=wz-w=SWdiwY590!UCmNVk zd%$xLOdC?m3JG7^mJ3ihuYh?cxE{DQ1 zy_P!-4!_sBj`C6k|C0khWn_yE%#UuA>gQbsq=C?RD48$QLb=5Rdd+bl8R7qmkNVtT zAFyvz=QGc-_DidT1#`ySCf_gs;Q&XCRlG3A z^mSCZA)f`D^3%o|bnnm9&*owDASTiD=`bd~NPdZNNl(r17XOv5T!BY6H5w=B6U(`ov_t1*YYVSC zui@u)v>-EftJcoJSL_Rd`BTTT{$u%4QSX8^jR$|$s+u(s%XWRJ_!5!q=unDYI1i1OyOL(YW#ZyeLZgI#kqit9AX{P z!QNg-GqGX`MSf0#!w&qan?V0K$Y$_dUh?g?rcc3K6{**lH(L9N;Lr~;Ni_%GhrWjp zICsvTI@`FEA-zQW%JpK@jg&$QAK z?TQriw>I0uSYY3Uu2}2kLEss?jjPG z?u878d`w>9GC2ymJkZ-Aw77JL8sZ~yhPD;Z9Yl>u`G^XT@utL-0*V;*>kpI?`Ej5zll zpjD(&j2Z?V#^#xh6V-Gca7kP$EpikxVkkXAS|BBy6&(KC1=eX_lgJFLQqitex1@`B zO(J>oP0^}lRCOv@f7KIcveN@V!HV~sJ3+jdv`EcK#n^!}GdGwGp73-Yu#U+zVB`tz z8qgTVX00V3I09?Sxp62PbnlTTj&iJ3on63NQ*loP!5>zHygmki^S!)>ykB!&$h5HG z;EODiCKMr=2d+TNd2ktXz@8=0SSv5Q%zdQ{-P~*DE6@?|>9n5UqNmKEtikKdzmw*w znjN~#D*gIYhR+f;<~0V^34li%Vy1mI1|W{ed4i^KCW0@_YWpy{gz=mnb=Zo7#>MxO zhw$A+^nIN>$>{`XJfGZG3FAdZJ>Mbrh(`MwHFYK~w1l$&0J}pM;vFcVQt+!j4|Y3v z=(>w_Zh?x@E0{0Ss$~+z5&-h|%8&&pl@9Xe#hEO>(A}I-o8YE9TPy7o=H@cb!KJ6e z%FcDkvSy&I?R8cV6kklaEyt;N`k`w9@RWZa)dj>$SS$0F&#w-k@`ae70Xz1rpRjMK zBh183UGU1EH(Sc{LYAmxR@~+fdi4DjI>7s^LC5&rcJ@jEfUFEk3ISy;Pz-=tnGQZ{ zxa9MRvL0Y0?b*;N!vO!fJebjVfcB<bIR#nP5-xh*R=L)25Q{C^|QV2j&jL#Iu+NKTt9wm^qsPwa+&86PCs8H zRk@NfDw6sj@lx!ulB~6s-&%8<4jS(d-iJ?LU(d(}*>k}33 z#OD)Tt4f(;wfDDoKH%~lzWTj3ZfE*NM4}hHMi;CeiNkx_hc+M2X5H^WOFE9yF&KmK z(OMUerNuDtg3+s52b+f*}Ci?z{o_B<+}(vt@!f>=J-$anC8gRjKynKtJz3U{K1A4g(3?e*xglAT{@f4jwaT!F#z(FW*hSzdv^a1567Z$M-r6q8ar8 z?{&G{o^d)vFqAEu5o2M^8H6A@@tocOAPgLXbpC$R50Ubphvzv;&kDI@J0kreEz^*+ z*;7H*hxae{N8z}3S?B$2Wl`~AM}~hlfwlvF56rMUFLKJ@d?sjztP)sZnj|0bcOIG2 zp?_EhTBq+?E2D@2NNkuv&I!Kof#dja!i5eNlWY}_S8xXx_pt+mU;yUDI=t3e;7SAR zE}e2-d{XV0d7mUo23enxle&tgpYQLS2iphyZ0htDAXra10-xX+b}Z77vL1z;eAo45 z$$jb60!fX3q?eTfMC08EE={1!pBYHNfqUjrF%gSf+>zO>GNyjkg`Gu?W~1>-IaKc-3*R z%@?-dC4+^%o=(EAf+!*q9l?lqDWGW91FQT!zEPd$Sgn;S@bUHIw>$^L&K*GSIVaC8 z;63L&OT(ECBG&H)BkaKUZ7>f{T1-r{mgD0|Q(ixGj0cz_XcS?!!W_P_$d2&5{UXs@ zIFsvR7c+nstfzQRu8%t|xGn_$84pWle`bIVI{l7v(iW6V8S(k$t?qVYdAE%&q+Lq(}gH2+$HJzq`G`VI2@xj&zLuHDa|6*XXmd(QDJ$U?if)dZvrUUwE* z;rp-{ub4iCOJ}zbN#pUTCmuZf`|rOec)*9pZxLPMDf|wO&RR>pzP^b59kBEFP;1RC zI60z-`SFEd?6iowBLTyV?@tFIm82Bt@Vjz~pHOf9#$P@1ERB~iA6NLbclho-E->Qn zu;QEJbk}=lrQHJ|78Rc{B)N?6(hHGJe@c^6;9YHAYf*xyVEf-OPxM>{$XTdpKuP4 z->X`5oTWddQ>)QIj!kli!}s8=)>y+NY0UZp4x`glQ%_;eDBW^;-Az82pV$Cne;70Y z?7}G$g*@CDto!=<5)p~ZbvwUL{$oc|L`$}ZK4o3R{F)$JI=Er}hCakP@cy@pAt#?Q z4~s}sETy5ZLKrdyR{f*TVf7 z2o&}`z-zm{;HrtPub4mX`7C7!{ey3f`a9%Oo6u`_o!na*d`>*qI4swk>^= zXFn)%3}ZXeS1H(cygvaQNB>uMLeQW7c%ymM>gtg7&A2(w5=#Nj8KqQQ3l9mJI<4cuJ;hBu&)4{_uoUuke6Nj+?GFnhYku3`u zCf(*gExEwBDI4R$RStAmIGnB*+2QN_3nu_$f~R`s%9@NNzymND^l5TR&$FEK_-5#n zPf^?eBMw@729x;@(ewH7XE>u>`vc{F&fV6;K&y0!kHa!lI*76X(o1J5qC3t;QYMj| zN0zk)q8rWYoC5X^V?P2Yke>joScBW?-sx)2jrXhFTS5AX-?i3m&tY#w;aER2jc`U_ z52tg}YxFI7f*sDe7cf7loVY*Lu)-*+KkYd-nwfa3Cj3Gq&<*AJM zSq{IxzU15=`Fwv1bjbe0U;g7K_jP_85F~($XRZrijy(8da_;ZU0`TNmz>$@}EvvZr z1e0Xu74f=fj?`nkd>)Y_;W5JKi^Q$!qn7jlxb>_IN}D`dD9NapR|+5^KF6~Co2s{O zl(sPx6~cEp%R-EiKxZgkXC4;-R+45GmpxYci~@-%0L*-dz$h`*G@8sj?YmH#<_C^H z-(kFBZTEf4*L7ui4(f?{Eprd^X90+E&D06QXuQlGP=s&-X683mvUm^gA-8XZvS*qx zKQZ`wbKLM@fX%d>^W|so$-TFV7i9UO)qL`o!pd7E?}=DjPWg3c?mkKlC&KOHzjLF3(czLnm@ zw9zf9y8m?^{`&e#$BuchB0t^P=XECFBcrCmz&oiXv-3`Kw$;z=)ZGR}=cHxqQ$|aT zoDC@%LBNUU%8m!~64Qd^gq?Ye@c^JwXG2&AP1})99qC4ZHqI_MExpC~8_)5Y+t0}W zBddWRSazHlW99r-IaS>mUs*mk!@(Up4fYJ09h5bDMY(O-xdyWtJHc-gDNuU2j1j z^z1im#dTewBf$?=cR!4An z(TRX-&XI!6b-A2W;MQt?nBS%@@B2u6Es*C5o?;AiB?L`PD%<|`<43-e%c6MgS2WLQ zbfs)7pX=aq$?4Q%#VYRfwbCb%?Ec7Ld}0vhg{h~(pWw64r(d$Eji>H7FV%y!=m1#! zShPlS1tpA&@n8$5-u7T}U4U9V9OryKCv_BfkAq^q=ECpA7u86|gA3n|8H1PdBEqRm zaHt7*=P5iM2|$b9bNeNO%*<2Rrot&D)er26@Bu(XBZ83D(~xZ3IARI>@O6E)><(Wl zV}bN?uB#LhN)2Y+BnZ5NJ{4Unhk`!|@>h>8^WT{CYx&Fgb8T{D%p%$`>wFmy;azhddH&p5&YvleJulz_7=_~JgLJI? z^4}wJ(f2_fdv%|?m5y+!2%h2jbCjar=^$BBgPW8e#@{Tn3*fn$Q`H3{3#oZP`dNGb z<{V6*=wGU}BO1@+H3h2`ePab4!=x(A$Su8R^1~ZYOj)P3B7&MAkFrEef3d0w_xJg% zpuh_x)_2;WRjadax&Hw&vF7`}^FZ<284q?4u)pAbp$Py0AOJ~3K~xNsOOAwiqzaK5 zjTX8u)tL!=zn2^u)q!vW9zkdnh` z=NT&if8D3DgE^LzZQ*tLIncs7t@?(XrL;rDtN5hjd$>|WG9ywB?K6-7yV9^M*(eTb zb-C?(So5slFb8xY(~t)=XeoZ9eFcww|F`5>?9li74}bmp&&f~;g6w2_P5vZ!2b0}* z7=9eA8;oq0UTxnnz>_pTd+*TSLt z60ib8ecc(|q&B&!40hGLcaY8Nw=!^}cC~{X&3%BPd~-$^2r{7IeVtJZ&v?~bi)ILr z5%5;eY^?#{rsKqlgaIH6lbNR^na{Xm3xkyiD5L;kY=C`$6wH0CGVD-@?R(OlBaw1m zQepA_o4uZ40PmqQL^If#S}sG?%TKiJPjG{Xl#*e`P!-J!O2JIN=DqrrBfxe04;k4j zjWRo6{ETWi2cij}SY{i@lpbm1y)iTS+#mV+`g%O0OGORF9pKI*R(@WocwWd5V13Nv zDI==Q`4FKxd9$n$Pe+0?7Et9Z`4*MOf- z*_lDXlG)mWx3fD4Ce7b5-%OdBJTrL#YhwEUBQP_-r!{d*4e8kNFh_9Bk|RL9{=2+^SwO%;mdgbzX^sPM}xmno{%4 zc{nDbE+Zzr)DZLG3_UmGn7HiRM`ZO5p1!`SoRU;aq~q3#qZTF>L08ysWU%(1{`QZb ztPo0x7lV{St_Y}#N2u=4x7<-1X4cDGh$EY!ZOWC)R7gk|oMiv>P?T^I_&unLgu{dR z9}@H`A-kGF!XtpXvUn%Nk9 zKA*cOf^q;*H(7Il(#3iwIP&s~9uZ{bLqsXlGD-7*l@M$#1Mi0vdn$SwLIyFMR-J|b z&)s)#cbR>wr3>~Hde!RFoq`hpnOSriA^tw^ed86aXXf{v_f80!k#mkib5W0;nM7^? z(AO_grC3nTD9K~`-lreFN7Rj-^BIME1DaD za0v>ml-(UNt3j(1ZDo_5X07ZBSr;#BxO1*BjGT?AwYvl37b>mt&;R@Acy#ifnSv*Rd!8NXKDsqI9eZnX^u1W74}Nh9k_j6)D`au zJaK^;>z)b3=gqGZQqx$Venb^DrNu3m-HcYoe?K z+b1(?rFZ=P8C{(Y8Ux1!;UaCl({V_7KNX00`!w52WAgi5U(E8dXJ7)Id6>RW+VA9( z2}I|fvQvp&KUVjPmDxi}_71A?&KWp+bFA|3=^&R5EgIZ-DDh5Wh7}zr15@xmW#>-3 zD|tN1#h6ymqqK)i%W1z5IAMBTUsqdm$0Oar0ga#o<^gorh8cupFj;gjoWL^90agBB zJp5PP={n}r2-4<$5?u#o#0(;4`xzW)UQ_r-OoWPv)h)ciK7%r99T! zyQ7s8YhqCf`sG-{td%$Avx7dNpo2a;JHxWR1pT1zn(PTm<09)2cqVyUqpMg1Stf?* zJQN4bX@5%2il&-a^?7dA0|-2}CRSGwIiGLefAA-CuP)ht`q%&biLb#UVugOgD~g3F zP2SFt`}T60>B7J2?JqoG_=B zF_TiFlcymY0F)1!(Y^>}lwcq-n8ABSd&4wFdEk7`JLHuiDgLiWd9`_zbbN$(0(t|% z0FGAez0-L`6b^p}Pnz|bWD&{MjCR6-GjY8VdfhB8my{U@xHF?y``ke(-c#+wpSM3Z zBR3+K;4_x_rkfNr^S$M0EAOq(ulO5!rRv8k)10(X31i;p!2n=_9(*^Wwxi?$&)UV0^>Kgk)`Tzi$=K$it_93vq@2&SpTf=k=d)xcq z6RCZHLnjvdH5w5xZ@tkT?`7u%&-ghRWG%_z*|?lk;u2s4jS9?Va8yvH*B#B7jW2yG zdCrn$K6S!yKBl9Ib+OZbDBAo+8`it5XO(QdSkIK;{k)Fp9H6|d_7vsAJNK3K!(3DC z(=!9cx`6+__9g4Xb9&GL4m{b60^L4rD4#bY9413Ny>s?i*af40BcOirBD!W`l)!Hy>T&yfMCs31iL?%sY3o3fW50z02?C;HOI zv;1icX;oAM0D=iJ7;t8)C{`&J6@Y0(f>GZ$74SJ8Sw_$Q2>@9cthM40XGLuQP}f?1 z4?&y*5GlnuFQ`+|_Dn@;EB(YqQ=~^DSZT9j!KNdPC{jLHGMQG11q&i-ta0$aGfR)6 z7qfB8O^UKdwq_C2IS;r~kR8lO!SP(?nwV#J{rER4_XL%}+yLHe{L9dm!T_P*(EQ4f z@!GHJqWe~Y1{BeUU#ALyTX$7pez>G*$^sktXZaS0kg z(p1z9IFkWq!>IbKXU03Y%*@xR8E{~u$)FW$RPhcTxEL#e?uq{Gs{otR=S!A~ob#cK z5TeMwC!q5*ASq+v#7|%W{^p-^^N7hS6L?Q2TOxV{y4BvVoF{-C_CEPN9Py=9hi--p zBj{)Ca#HLK0!rBL2B_69484*sVoi(ZP4(IV`cpUTYBg$B?Pr-5_kGKcA3yxNh|+P^ zWzfy6mmAD8BLGl!HmoAIEJMt1Nhk+^wx)th3$h*!{1pZ(kUX)%sQp^tDK#^pI~pEL#Z|QtPt~| zX8@69SCM${9%ak>>Ls*17TXKR5Ay+Tm1jGHKNCcUu11GTU7C(PbbMb^2Y|R61?^-f z&$0f)ns_eI{Vlk%Rs}zHcgo)M=vx+zGm-c%^Deh&&haS-%X{p$w6~?kdwINRx3PW> zu2ZH<&w>dAMNk6n&hy zc~pC;P8KW=@)w;;Tcr%plcvFCsxu zHdc{>wg)3h0!1exai<5OQ(y>5Kz7a@mzkCD(pC_&Nz$L^J!!Sp5)F{%2Du_Ck7(Oi zL%T!djs8Tt6gHKlHPgEs$?m-57zg$IQYA!EJTetSDJXXDRCK}M3%$?Udd{&dVaYkP z&Th}_iVS7I{J{!Qq(EV<{h3ulAb{_MnE;0k0gT;jdHLYAU(C^eUT0P2+}SW%RHhSjM&3Z5;GN?g-hCfr*`y3r8w|!VDD&_cdZ8aOxE_Yq#lAo<- zJ(8F8DZ6|}#&nDrh*f58b58wi(17PxZR}T;Kj2xslO2dGi>8|Fa#~$D@Lg{E z%(R=b%hWd-^P&IFIeLpFV<|O$k;%zi?KN+-_u%3KyM0A3WAhE<#(_^Pk=9^+|p?3bKDZf-reR6 zM6<$wQ)K8Ow$uSdrRHi)_)aR{i#t*k*lJOAqT{)%n-rMtzN>Z_%p*jztyO;4YacD0 z#!|%420qvA9Wd-1+3OOtc*DV~JT#Xz^A&-psJ2kIqU!j84qa`% z@iU|{-+0>OWTZKx2Na1g6Vd(5F0g#f=s4!bK&r+oB|P6JBAI!FGn<`CgrY>!8wr?M zrt?3aPs_AS#|QIRYmNIuo(GaSvnUJ>g9%kpZh6wNgrguue>z-}=brLbYUzMtM*j+MN&t~=h$eu7j5E!V%1$Rm zP0npmGU8_@?#~fbD<^8xUNvK?xhD*w7>KX6@`9@AB(Z+&fJNcT3qfLmA#+R-@1V7_ z?D%+9vX)UnspzK<`*h+R$O8xfP?l3YotfIVo&{pw;Yc;w!KU5Fh+qYjFee1hrY$IN z(t);GfB$rFa_3SO1qdyrC?1kMG^HP3@-!M1MFo+JCn+@b~g zbzKy(*2YiOTHYF8U@m;a^mOW&hATi?fo}lDojhe$WjZ@rnB$Oe2ft6<0w=2L!%a4E zH@lhN8$9mvEcr|aZTK;Q4Vv~F`;>DFImSFef7Tt0VSLQp=y;CbbA|om-!Tm!CsRk{ z9ZCbEOS3pjpvlh+{!CuTHRw~Oux?-k=%hnc z58c_X;D(QbZl?&2RmK4=oEMGB^nlYnv(J?+;2_C!PJ35b=jZ-NcKi|vUDxd+)9CFo z-5R$l3Vgf@EHxXUB1udeLm_Qi9DhKP)oJ^UfAkm>_L!Go6Z=RQ5K<7V)IN&@4jC~2OhT<-Irvf<< z8KI7095Tdu@^U)@5lnyZ1Mer#m-qWEnrBA!r}S)lZguDO{`A(8tXS}!7JbtvnBJ?W z>KUYDq-vCo@w=wdhSSUn5qEW1o0H#&i?X;zhXEo=mTF%$z=U_*drKQXb<#9MI3tlf zA^{FeGE;-#3C5bT_Pi*qqQ=<&$K0eFFA>QzaaGRf{AA~NfCsb}fb+;esAezv;yV#B zX`ot!X;*s*C$Z}R8T;7-0|1c>10`NQi2eJfB{`^kK<$Qg4W7H4g=$}gd-@m;19#(vYUEN>iu z0B!f)SsukaSNv*O-U$FD(n~PKdH^ly5PVzTMWCsJV64~Q*BwB7ID_&CfP}smbtjhF zA>+d(Hfeu{E)}biIt0B8kryexn_zqDKc;a70qc3_lbMCa`dMB~+(unL{)zO$Xx|$$ zH0kVXgHuTuL3)6M=lgIb#6+zyPiA;i{!vo46A$2%d=H!x_BQdM)crJ{yjk2DFPBrW zGX%_444}u_J|-$VaGSX(ZY9UueUuIR5jc5PJ0$-MJ}G_G?RgMIBs1p~Y*SUoiT5Y` z1IN5fbN(Phz4z|-fK*Gy-8R(^gx+!@>R@3w0WKJr@a8^@o;*R;bMbs5qa_1kbMStA z7aQt}tzOXSkLuYxx6EyNX_vIHpaU^-(yP&F+HJJv@0nYVxwV$WLy83z(lZ*$lI4GX$TDX{{jlC-V;DOo~91X&XXcPVe$ z4H1J}rVXc$TUlSoDa%aHv~->qk(PdMpoRcA*7XKJCQ#}QaqX#>Y(^>=vJ$NhnU5z3 znm`VH=+Pks@2C=pqCLLPXI?-Tv#2G9jAZFWC{_x7^n;h(d7s&gF7I?chjhve8m!ze z0(q8GX$F4Y10W^^KC!M@)<(|I)VVqDkf#>xu@M|0zGtVA*X?^f8ahy^0d$C;i72Ot zGus?7EQh*)%-2`cf`Vjbx3dmjAfJ>z+Bhe}-bH$M|Nr>sWcYdQsRLRk;NJV{sj}H#6~HprDh3uZHT_*2Occ`B(9eAS^v#I{PyGt0YCQZy=l!)^7M@eTgD zPjs|g1!`am8RPN3zF|;r_|k(#Ah{i2LW~LLmfQF4MspF76IB~M)8VCYOe4kMVg|+gJv?O_39b zqFF-ORbX?P%#)s4lL>F z&j(;s&HG{4Tc2z3HL_9YDftfEI?&5?$pBC)y{#a zPJD+I6oV+U0@-%rT!VF`okD;5`ml$y9MUMojQz&`^M11uWo3l&I45EKj_*&%^fS%l zq;iGf!xL2k)6M`;wrGNdmPw>F^k}V!sI_MS791C}V z)htAl_xqkI?R#5uZ1U8vc#iQ5*1=~3yRKorl*jk-`vCsU{~;YUz&AeNS5ydG*H`9I z`CUA35l0t{n|SZp`FZ1qNe|vbt_I=p_SX;5jnY=vc`XuY2dvVoC2 z1G*xWq09e**OsmfwBsFVGZ9!sW0ib)ZZb}90?i=K3E3m;(;&YoK`<*A9}(aCzO&m% z>`r_yBHsBUoN=i0DG8QDN~njRVxA5@Rx9GEeHu+q zSGWLN4LG@<+*>iz+(e|+_~V%g9+B1Hh$$POsa#lom>-#@=k8JX8Ks&u=CxMce~%Ww z$uO^%_oT+Jak*?WX^!;n|y+^hSpdSs^mG!h(T^Kmu5*L307A3V=IZ}~nrvyipU(|C91MgRLe{K5-{}0laGbJ{Qbkt<|!7cxLVq z#^C+rb>r+CzRy5TRomIRNpslp3mK2FWfeGmzt|6BHD_2mFu&vM5ir{xJm=plVD9_S zok^CpDFdkC$A@tS^A6i|9&=`Ly4?>T{Pjb0Z85UvUZ#6z^#RjFt4OKsC(Azb{tQAV zZX>-=wC|<1j2}fLY-rfJaqfj}KJEeGpc>;W)?uJ&?zwt!kZ}y~cB_c+w+D~h`Tm9_ z*ODC$DANhJWOMe7=x|W+5lvm5ciNQ`gMZ)Ozo$-Txq}~oXL%kP&iDSqU;g9g69mVh zn)@T4@85IdzM_O^8i@JtIobMoMI4%f63G&aF2?d;tk;Y5X#Vjffl6%#A~uE@4B#4q z3?q=kh;$)6sBN}(u=08N_iwew&TAO4+(YNwa%cQ3qjcWFxY zsfh60&Rb|DW8I?8_NaT6vDZy`Qv`Mz#J1*D`^bCF&RGmd@9EJZ2o(-x=Nk6xxYNP% zVuv?`pR)tgadn5TqA%cKWLVNb$}@t2xpQU#^PjD#p}@F|sQ9SLquS4@V-CwzJy(Vu zOD_4~3_xW-@#)}-l=Fxj#gGpNP6kNBnn5p=XrW|amS7^Yga8C&Z}N7QgT$QJ_<&BB z&XhU+yQ*g2bm%If_trb#qoMriK;2UQQobYTfkXEBtW+I3jh1`=##<=65qb8)$NM=V z27W+8f}|In&oAn6p z+g$PC@2s_Dmh$?~9blN%xes;-=6EbiB2_xvvdOUVvCk*=6wa>OF-aSWb+ArUA?KUu z&w4FO?hpi|PF}2MlUAdn6z_Y=0_htDkT>b-X-giUckqgcv`PwGeAxJv=7j&4uO=8S zPSRE(z;?@DU1LEmbDwA(dG{9PNFC2Gk6+nQrWfcjo3Ma(=E~c_@z+;ec=~iA@(j&5 ztA*#@@C5S_0+!`))cLVCF9olZt)BV;e86p?ReFHK=hKlZ;~?lp1X||4XO=~3A9+uh zKB^j7<#CoMF)Pa5UB@8!*z82Zpx{|ceQai#6@9ZIW|AE@^Ue{afRk{;kLp@kj}^W5 zpa1Q@elj!RMd#ddf4*yx+VA@CfqlX=O~v4_z#t9-_774k-9L`gBPS z(UI45e?For88tEM3XGMVNH}TM%ggvbd`fw`I>X%yDrocT27F(a(+j{T=_+l1=Dg>- z_>+50VEqkrq%yT0A>e(=?~wqD$YY=Jc^*)cED7ZIq6Ft{Ea!uM7;u7GfFX>QWmLfH1-rxIhKc8Jc71DN%b4V9Vm^`ODO}P%gd$^ zRekWO)osDJ4VK3hbAWSax0{ubCw4v>PeTU~xBxhrk&P)cjgQFSO43L&tMlMvkyjqz zf1`X85^;Y%sj$s@r!GXirc6P3pHpYiSnqP%&^O~%hP#(kfaj*(1kW|&M>-W{R%u*A zkFx`Mtj^!$&xnp|mvJf`T66UIg_A)%?1wD98xYUe=U8C9$r(8ry!NW!u585wPyXC# zG@8LLwB4=!5uz`~b6H$`o-O!8OtKk6?O)ev%(v{snswvOXE0QIsb!5dd?`E{Y;L!A{h!}oXabOk|DXEs`r!wS9`ViWT`tqv zE7d9io?OQa=deCbV;nD-jVy{bJI+;|vd>bO4t(gCEapab%2kis&Hc}R`H!C&iM+l0 z%DF#c=i`Qv6bYygP%;mFbpmvz$QM!sjsXOsSuBVXj7|_efgCefi^S0lj=$+tl#!n4(Y*5mdr1sC!4*fk z%46*y694Tmq`-xKAsQ)3+KcSWFnEEZ{Vd?K9^Coj3FesYJa69j+ItZOSolmK?n2n3 z+37)HJNAl<6t7=Z2T(H zWLBUOL0tU)^ZB%lU(%N%jIfNOCFTUjO4fx;pO*hqoL(~V%)bnV?57u!+6ud zh8_{AXgl_`8E%tIyR)PB;P-G&R5W~G6SdN@`8$-LNjR}_%Q55>^J)Nt$}*O&2k%W= z!n8;|OuFh>Uu~(^IZKKUK+XVkK#RZRll(h5!QfF5$;KsXd2Ka+r_J)AXQut?=NxAz zEF6qK5w*;DO6gP9UlWiqz282`=O~$d3FuX+3HYWvr4#VJz0c=z)4c9shb5hjq=8D( zYX)0kTXBIP%OKC~%`pHN}^j`d_J25xDX1mNS<@khC+J_n2@w7CVyAee+DES?6KK zYrveCYkh}GLSqolAiiNoUIX(n#RV6QW(eIySQFU)f?_{x5Q}Gs&eJ(h_=woPZG7AhF%~!8HKpP8}hSxs< z96)hXI$>P-(*$7vE*44%A0o_%;Aa$rfs@wZ!v=<|9D}vXNwQ-J;*h3)i@vbK$Bx-` zUA;3x5C*ru-Vw#q0EVD{NlP)W2;bAt!6DYk#;v7-$uJ|rKOGEaVvMUxA4ZFx=Y8Sd z@tiR?C^FvP6f6Q8tX%lNqHopMGykb-Dvf5?DPncsccqHO>Q;3rh3Nk%W6$gCG%wC; zP7yhG$wLEtAlk?V0CYT7EmR#a-Lxh*bX<}#K^OA^Xvefd3Ef`R=YImD(jh|ftU>!8 ze83!#=I6t=cpj1AE3$mw-`_b${5R#u_l|34Yt4SgNkx3-_jvsrQRgw)@k)JS1k4w7 zq;n|m9jyL2-pk(&GxibXdy>W`m^?ENDQh;eT~fSV?aoJuE3I>`4P#^-wQ6&uYdzrc z9&u-Y2RUot3_gxJol@V?g{nz&kvu1ewQ#wn>;9@?XL-XrW`L*oxgUhahl4QR-`{fW z>WGL|!@j0|h<@sG?j*xH4RSm8g7q5f*OHl)`##qLo~cFw`!T2ac>pYdO)*jF4l)Bl z=-jtEnBZ_>PJ9+(mMOBMRP=v$ns{GO=8XNAQFG9K(pN-UW&*(q#t7K2X+NfO^9V$Y zea4_}j^XqWu9dltwdnG&g`_#Rd$KeWu2o#wC{~#OV#~AE<1eb*S9z07w zIiPiqKqB@}MCc~;W3p7_MA;R0yi##~sEvlF6ax-L$QwSrzG=|}kO8!SDEDIT4DwO01_NUmX}~TAJty* zrz!uv^0^7*m$=*$<$+M?V8g5w zbb**>bh6rh*G;xn56yh^uD_U1@6g{Jc+|Q8{1nF6Mr2bei|x<$cNJ|snvZ`^u$p_M z^}Pueu!l1fhkw_)ie6;|sa2>+wUpQ1b0ZPi+u992{ z2L}Nr)>EtxnWi&{H|K}{rd;8>*x%{A1C+5|+82Ve|uLj7VCul$Gmwj5%6YPUUI>~k!Pj~A8tv!SJ^H9?tbj`baozkOnN2-`WSoQ z^M*Yn-N3dv0!UK_aIk+Zzp(Z@8bRefC1bv>r@Y|-IEC@iTKdSMr+%;zXi}>73EKJZ zkKb@Eowu1cIV&|YPFNG~T{<9Q78i-c$D)2K1f;;Xr>*v`D1@{HdD@7<-()H%uQvn4 zk$ep$hB`Vnl2afW)6$JG+$>A-h;WqN?Mu9qj%Ka?8{@G;xFe#%O4Gkr z%*WY=ja#izGfDsk@0f!ex#|TYO_~FB~>*Yv{Dw5`_>#6+EZRP zuNO`}l$ZtsLM~xk{oSk5^2uiaX%S&j@Nd<=veU(%+;>r#7e8TcLIIQnuyhX%?pnz8 zsa9tmt=7*|hRo`6vqgLXeFMG1j===$wXPcPW!r@h4#R-6E@RnXqn+@fHfQC& zAAkxpWO?3kK>Q6bHDE>hx%Q6E7lyv<<(d7kGvDA28g>BJb$5c70HwSJ25S?zV?RM3 zwmENL7CZzXrJ@NqPzHRCg&ez`6zRH+ovoHlS4l?~&p+$QM|9qLO}&#IQCytef!?n+ z+6YLb3=fBl=ed9hf}d0>OOpYuDAB}S27D>4hzB{**yLCCg*#3HhcKTqU>1=Kpt_yx zk?Uh8Z4a6A2guL4NZ}roZk}_JF4I0urw`9#&+zYjE_KzNnK|aghYa~I8s8(Ji05CO zdo2vY&Svs41umR^<(RJld<(qB{+Ly%>j+-0>nr6iu@Kpr)M27DXOX-Va@86D*fEc_ zRz~odMjWWYzfbZXVNcpi-mjcH>DLy7RFV6x^SEpICBdT4vS}Y@2ez|OG74GbKto{J zcBbihF2$@@CSBK#o6t3N1u`M-yzhKREwl6`%aBUxg5=@*BO1Y-tfGl-Y&|$z^Mrkv z_5gqGKmY9?KiwmCgLuDqk(tKDMvUKs0im$*I~Fo{>>@o<#0$q*`1v%X_wAip-T(+I zB3>vPjd$jf_6`@2XL*+Y8wy7&pa{Tv7M z__;p!>Qd1RmRTwtr;`JT73C-*ng`l37ArvrKLcMOx)q%@1xn<3xJjfdQz%9@LK8?W zUD1>JdA@+tf2_#6;*??FXXN!+o{(}unGgOQ8$cd2`4FjJnlHeA&YwW-1daS@#xX!P z%AsIb0iN<*=d>(AIrTVbch~(k@q1R5ERURaeehMhD+pgan*31v;+W7|2HNSVT2{2K zqd1#UO(Gz3HLg93AnzBVbmu0%TT$91*7!Yv_F5up1j||E*#^-ps7t2o>Is!#;hY8OG zfRqo6^JQ>FlQ;uH-`9<(xJIy~N=hb8kO7BYct7N?Z7;yvY`6G%0AoayRk}0R0HYS~ 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

teD_{Jep@Ic*J#y#dF(*P08k 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 literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_button_regular_height_50_medium_rounded_normal.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_button_regular_height_50_medium_rounded_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..d6602ee1d56974ab1965976fb27e2f999ed058a5 GIT binary patch literal 890 zcmV-=1BLvFP)gC7CJ7=(Fk4pP1kCJMvW!^G771yx zMv5X10E7b|!h(Gy4uEgK+yE~SQXmK?W4G<@`pBZ4FtpkpJBhGg>Hk}e++AI7S^Z9Z zbhWFM)h^!^ z*QTG_^=>M^?)*)zyI22nE$7rL3f&wW>DKXJ>@_%j{MF}UCrO_@_~y6C%7Z*WYcet|J&Qty>nTo!aE)H`?`HR(EGP;j*oi&qu#wQzdn0@IU7Eo zma1PTZ%1X<1p{pIF7J`{wf1@cy-nRamCZ^?3Nb0fD9H`qyM27#Th`V2biPnk2j#Bh z1#mEO&Z_I6X*pNFSDg5&4tGgjz>bu&st{F&c;f326%)w|Sdw!yl=k`Rf)xN0a+Xrc z@{F7TtFk;>K!9C--vI!4b0jceRF>pfzXEJ>q6Y>{YZ91V7%+(*7%;3!V78I~bDBjg zk{2+`lfQsXPU2BYz%mxG0E6;s>xelpV31oSEyKvt*XfZv`Sk40B-Xz!7S%BETqSVuy!W~>=#MXc{^J}ohj$@tbCWw7&siwTZ3*?6ve1lmfu~Bo=ha^B@0V!Z07*qoM6N<$g7*lj;s5{u literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_button_regular_height_50_medium_rounded_pressed.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_button_regular_height_50_medium_rounded_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..2a74c6f4bc40cd6ddc71feb9d81f41551698e107 GIT binary patch literal 895 zcmV-_1AzRAP)MpA_;>}OpeCV5P*SErlt}~a z30}cLMN3O{B^|D4Nlk-$kk02Mws+^xbA{u`-fW!9-AVRH-%n-D&dxk*&7+y!opri# zdj9OmJm>S6;^$^MHZuX(4bFLarwiBVKL7ofpMJY7m!xmbpAAA?|9L%~4W{!-Ax7yo ze{ET9MYC*EvcE~a_4Z9BC)cR&ZjauH$4Rnfd9x4KXmd4=W&LJ(+p+Zs<(y>8c30~+ zd)Rax&3@YYUp=Q0Lu;M3|G3$QYaF_JZ2h|Ki?9flUazOa5Boa&_@j~U*PnL3 z{Pz3P@#Jzao?NL8VLf?QJ9{V?V3YSbMw)GHbNsza-;X>u<*XEwQc99EI8^_vTZM3T zbv;vE2W1iw*lF2JbscnhJyoyUIrddmA60?m1xk_4RE4Mz)3FaRD5t#bm;gM2<*X2+ ze9oJnAp_VwW~OW=Px=CdGRbc{1^{o*Km4*8z^-Bj28zW!Fi0jUzh3FEgoVq`vRrnH4;!Tme4@KNMN8;j=j)8x%iwAC>dKRfufPX zK(W}!0Thh{28zW!Fi|Q28!lW4BL(Yz*|Tu$mc);10{;pOx;*bWo}Pw z=m5%*b5e?xe9mb&pS+Z%wC$Jxyn&pO=98B)vkUK>8+w_hG+wlQtkwUF{ zdZqcR|K(*$rswYH`0FRLdj9vUss=gdZN~`U0p5EZ?C+2M`Rk9T{$luI?Dllh>-I+8 z^HvGiT}~bE)$4UfKI>#rvf`7^zBtWhXC`+fW0N$nGn|uT!%nv|%m?x3(Qr7Hq}Kz2 VWwdjE=UD&%002ovPDHLkV1njlvO@p> literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_gauge_medium_backgrounds_active.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_gauge_medium_backgrounds_active.png new file mode 100644 index 0000000000000000000000000000000000000000..9a2669de1aa61dec53b0165c83c9d2efde7e4449 GIT binary patch literal 15408 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

}jXU%b+M*#QeOqa%ISHYTwFvszhP)Qi7cu+N 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 Bzk~n) literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_gauge_medium_needles_smooth.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_gauge_medium_needles_smooth.png new file mode 100644 index 0000000000000000000000000000000000000000..144d692dfd76624071beb9c5649dd2e6d649c92b GIT binary patch literal 847 zcmV-V1F-ywP)Z z65tK;3Y4j`Wdcp!08@BEhZ!6&-k(chODnDJ{&5PAz1F9DB%PH+5TxT#oTq$K0LX`Q zwwT;bs%?}6rWv0z5EBqbfB9T$BZ5@0w%@7z-U@=qHfBQH1C$%LgN)KDs7FPVAagIP zY#aBR944nRbp!SOD6qD9@bb77OgB|fA`KAw8j0^`DdD=hUKF>#_IT1EriA zEw+~4`g&kCsDJaTd98bq16A|tfl^M5s(JN5W(wYdvQvK;ovl`9+qc@VEmqgpw+gBS zt9k8i6%AvQa_YEgu-Y)j>i8|F@m-7R)#v^w&LaNW9R#u>ij{QDY*Un_ zd#X=Pjnt5jRnzfZr-GDL;x)6K)T&QTjfhyQrsKO#Oo)|q%>;M`;2uCCR%B=uf?Ie$$6uyc6&9zak@RDlokhr4$X04#q^uQzs&G=NbP zL(Et6htF>TATke^zoyqucAtM+zu|F(Nst#8^M@}VZ6{LCT90+Q{TS!P@W(RA_aR=-o zmMKtY$l#;FPL17b?pL1bh`Zr)+6Y>G@f2c-nOVNRNQYIkI06V@c%M3nHuuZS>}PRh zzkaAY4d=^FMK9SyW@dkhE6+uhw%H?QW^+{0>g{8S>=84wIT4IS!I(W_W;RD+S)y>t z9x*ffhrR^tvoFld<`n5r)=k|@blEdzX1`I;t(wJA-(fgkcB-@`*d%_LnE{|+3~{PN d_t@0005^ttF*aP3ZJ7W7002ovPDHLkV1k_^aUTEx literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_rounded_dark.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_rounded_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..24099fe67f0652eacc9958262a2cb7c63f655447 GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNDEQFR z#W5tJ_3d@TphF2Ft`Cdj1$sj-S=>6vSHe1JZVLMjk(eg!iLwXyJjAUuW+W(mjAVG+ zQ#pWkylwp8FOJlM26lPEDKjUEcouQJ>qdZnrZr+?eo@fujK# z89V5-cb$%$Eg_H)m9hQvl6|@1&U@1Ozdv5Nbmg}=cgYnmjNg^cKKRsn-#QzUoim^D ootK?Dy=Ypfan<}~x0wGhd1iQ(i{Jb32k2P_Pgg&ebxsLQ00kU-^#A|> literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_track_medium.png b/Appli/TouchGFX/assets/images/__generated/alternate_theme_images_widgets_slider_horizontal_thick_track_medium.png new file mode 100644 index 0000000000000000000000000000000000000000..002081eb35fc1818ae38148fa07449522bdb3a2e GIT binary patch literal 303 zcmV+~0nq-5P)sGi_{gZUV@0uhmTjbn@bcC`dZ0rF8j z!+j1^V5gCFA|gLj2G`kHY29wy*r2SZj?bg3L`06V!&RCM%R8WoZV?eVE~zXpFFiU# zM5Ld$3Fd8dhKNW%D-zt+(HSBlf6yeD-9}f4i1cxMk#@Vyb2hjDV-g)CBJwNu+5YwM zJ_YFBHxDPn^B1rJ9YYcM7rX^qarm5myge-ez5vRUI*U9rjDG+C002ovPDHLkV1ke= Bc(VWi literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/glass_theme_images_backgrounds_800x480_gradient_rainbow.png b/Appli/TouchGFX/assets/images/__generated/glass_theme_images_backgrounds_800x480_gradient_rainbow.png new file mode 100644 index 0000000000000000000000000000000000000000..a476692f43bf26e152af08815aca6146fbc127ec GIT binary patch literal 128968 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

#N^6^EI0fFys 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 literal 0 HcmV?d00001 diff --git a/Appli/TouchGFX/assets/images/__generated/icon_theme_images_action_done_50_50_E8F6FB.svg.png b/Appli/TouchGFX/assets/images/__generated/icon_theme_images_action_done_50_50_E8F6FB.svg.png new file mode 100644 index 0000000000000000000000000000000000000000..e77bc0b75584dc75913a3309c7bba8cb80fe631a GIT binary patch literal 301 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-&H|6fVg?2QH4tWO-sU3;6uj^0 z;uw&4khzF`youJ04Q5HLZjH~ql26z_9S?#}8zXOO@!CCE#2>6QCi z-yYxj_V~?Rf0LgXT=P2c`|Fx>J7u1{(z;^c?YM>`g5#0n0VM%_Cb5Pd2M41R5hfu; zWx)w7lD!QqCwN#`oYNE)1dN0kdnddXxHkEmn*;NaPfX?8_kXq6n#cc4R*8$TP5Y9S zj|!93`-z)YFI*&e;p3GoSv_XPx&8NVO^D<$Sfgxv|Dr%M!{eqKU7b!1$*JoTl>{Hu wxSrgje(H|;mvw)q_BCAb;twHd>xCkUEgeS^_TKpR zIEC#}Qf!*>wV*hqdrjL{c=p;d{q)W~=-hQ>#=G|IsoLr{w_LJ2+vjmaTIge&OVozt zEzA2AejVE;ufAITU~u!CoXi!>L#Cy;+SCS{Qu7)u{GZEjweb49hZo&>5o`F zZ;{)CvlG>t-hB`eJT`;Le)IAfTW5$%7zlpT?coc%H=)D)QispAZjJpCdGlmHmSz5( mYO+!^NTuo + + + + + + + + + + + + + diff --git a/Appli/TouchGFX/assets/texts/texts.xsd b/Appli/TouchGFX/assets/texts/texts.xsd new file mode 100644 index 0000000..347db69 --- /dev/null +++ b/Appli/TouchGFX/assets/texts/texts.xsd @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Appli/TouchGFX/gui/include/gui/common/FrontendApplication.hpp b/Appli/TouchGFX/gui/include/gui/common/FrontendApplication.hpp new file mode 100644 index 0000000..19cfde8 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/common/FrontendApplication.hpp @@ -0,0 +1,24 @@ +#ifndef FRONTENDAPPLICATION_HPP +#define FRONTENDAPPLICATION_HPP + +#include + +class FrontendHeap; + +using namespace touchgfx; + +class FrontendApplication : public FrontendApplicationBase +{ +public: + FrontendApplication(Model& m, FrontendHeap& heap); + virtual ~FrontendApplication() { } + + virtual void handleTickEvent() + { + model.tick(); + FrontendApplicationBase::handleTickEvent(); + } +private: +}; + +#endif // FRONTENDAPPLICATION_HPP diff --git a/Appli/TouchGFX/gui/include/gui/common/FrontendHeap.hpp b/Appli/TouchGFX/gui/include/gui/common/FrontendHeap.hpp new file mode 100644 index 0000000..6ee0370 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/common/FrontendHeap.hpp @@ -0,0 +1,74 @@ +#ifndef FRONTENDHEAP_HPP +#define FRONTENDHEAP_HPP + +#include + +class FrontendHeap : public FrontendHeapBase +{ +public: + /* List any user-defined view types here*/ + typedef touchgfx::meta::TypeList< touchgfx::meta::Nil, //Replace this with first user-defined type + touchgfx::meta::Nil //List must always end with meta::Nil ! + > UserDefinedViewTypes; + + /* List any user-defined presenter types here*/ + typedef touchgfx::meta::TypeList< touchgfx::meta::Nil, //Replace this with first user-defined type + touchgfx::meta::Nil //List must always end with meta::Nil ! + > UserDefinedPresenterTypes; + + /* List any user-defined transition types here*/ + typedef touchgfx::meta::TypeList< touchgfx::meta::Nil, //Replace this with first user-defined type + touchgfx::meta::Nil //List must always end with meta::Nil ! + > UserDefinedTransitionTypes; + + + + /* Calculate largest view, both from generated and user-defined typelists */ + typedef touchgfx::meta::select_type_maxsize< UserDefinedViewTypes >::type MaxUserViewType; + + typedef touchgfx::meta::TypeList< MaxGeneratedViewType, + touchgfx::meta::TypeList< MaxUserViewType, + touchgfx::meta::Nil + > > CombinedViewTypes; + + typedef touchgfx::meta::select_type_maxsize< CombinedViewTypes >::type MaxViewType; + + /* Calculate largest presenter, both from generated and user-defined typelists */ + typedef touchgfx::meta::select_type_maxsize< UserDefinedPresenterTypes >::type MaxUserPresenterType; + + typedef touchgfx::meta::TypeList< MaxGeneratedPresenterType, + touchgfx::meta::TypeList< MaxUserPresenterType, + touchgfx::meta::Nil + > > CombinedPresenterTypes; + typedef touchgfx::meta::select_type_maxsize< CombinedPresenterTypes >::type MaxPresenterType; + + /* Calculate largest transition, both from generated and user-defined typelists */ + typedef touchgfx::meta::select_type_maxsize< UserDefinedTransitionTypes >::type MaxUserTransitionType; + + typedef touchgfx::meta::TypeList< MaxGeneratedTransitionType, + touchgfx::meta::TypeList< MaxUserTransitionType, + touchgfx::meta::Nil + > > CombinedTransitionTypes; + typedef touchgfx::meta::select_type_maxsize< CombinedTransitionTypes >::type MaxTransitionType; + + static FrontendHeap& getInstance() + { + static FrontendHeap instance; + return instance; + } + + touchgfx::Partition< CombinedPresenterTypes, 1 > presenters; + touchgfx::Partition< CombinedViewTypes, 1 > views; + touchgfx::Partition< CombinedTransitionTypes, 1 > transitions; + Model model; + FrontendApplication app; + +private: + FrontendHeap() : FrontendHeapBase(presenters, views, transitions, app), + app(model, *this) + { + gotoStartScreen(app); + } +}; + +#endif // FRONTENDHEAP_HPP diff --git a/Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenPresenter.hpp b/Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenPresenter.hpp new file mode 100644 index 0000000..46c73d1 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenPresenter.hpp @@ -0,0 +1,36 @@ +#ifndef INITSCREENPRESENTER_HPP +#define INITSCREENPRESENTER_HPP + +#include +#include + +using namespace touchgfx; + +class InitScreenView; + +class InitScreenPresenter : public touchgfx::Presenter, public ModelListener +{ +public: + InitScreenPresenter(InitScreenView& v); + + /** + * The activate function is called automatically when this screen is "switched in" + * (ie. made active). Initialization logic can be placed here. + */ + virtual void activate(); + + /** + * The deactivate function is called automatically when this screen is "switched out" + * (ie. made inactive). Teardown functionality can be placed here. + */ + virtual void deactivate(); + + virtual ~InitScreenPresenter() {} + +private: + InitScreenPresenter(); + + InitScreenView& view; +}; + +#endif // INITSCREENPRESENTER_HPP diff --git a/Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenView.hpp b/Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenView.hpp new file mode 100644 index 0000000..7106bb2 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/initscreen_screen/InitScreenView.hpp @@ -0,0 +1,17 @@ +#ifndef INITSCREENVIEW_HPP +#define INITSCREENVIEW_HPP + +#include +#include + +class InitScreenView : public InitScreenViewBase +{ +public: + InitScreenView(); + virtual ~InitScreenView() {} + virtual void setupScreen(); + virtual void tearDownScreen(); +protected: +}; + +#endif // INITSCREENVIEW_HPP diff --git a/Appli/TouchGFX/gui/include/gui/model/Model.hpp b/Appli/TouchGFX/gui/include/gui/model/Model.hpp new file mode 100644 index 0000000..26217cd --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/model/Model.hpp @@ -0,0 +1,21 @@ +#ifndef MODEL_HPP +#define MODEL_HPP + +class ModelListener; + +class Model +{ +public: + Model(); + + void bind(ModelListener* listener) + { + modelListener = listener; + } + + void tick(); +protected: + ModelListener* modelListener; +}; + +#endif // MODEL_HPP diff --git a/Appli/TouchGFX/gui/include/gui/model/ModelListener.hpp b/Appli/TouchGFX/gui/include/gui/model/ModelListener.hpp new file mode 100644 index 0000000..ae6b996 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/model/ModelListener.hpp @@ -0,0 +1,21 @@ +#ifndef MODELLISTENER_HPP +#define MODELLISTENER_HPP + +#include + +class ModelListener +{ +public: + ModelListener() : model(0) {} + + virtual ~ModelListener() {} + + void bind(Model* m) + { + model = m; + } +protected: + Model* model; +}; + +#endif // MODELLISTENER_HPP diff --git a/Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1Presenter.hpp b/Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1Presenter.hpp new file mode 100644 index 0000000..dc06faf --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1Presenter.hpp @@ -0,0 +1,36 @@ +#ifndef SCREEN1PRESENTER_HPP +#define SCREEN1PRESENTER_HPP + +#include +#include + +using namespace touchgfx; + +class Screen1View; + +class Screen1Presenter : public touchgfx::Presenter, public ModelListener +{ +public: + Screen1Presenter(Screen1View& v); + + /** + * The activate function is called automatically when this screen is "switched in" + * (ie. made active). Initialization logic can be placed here. + */ + virtual void activate(); + + /** + * The deactivate function is called automatically when this screen is "switched out" + * (ie. made inactive). Teardown functionality can be placed here. + */ + virtual void deactivate(); + + virtual ~Screen1Presenter() {} + +private: + Screen1Presenter(); + + Screen1View& view; +}; + +#endif // SCREEN1PRESENTER_HPP diff --git a/Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1View.hpp b/Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1View.hpp new file mode 100644 index 0000000..30b9619 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/screen1_screen/Screen1View.hpp @@ -0,0 +1,18 @@ +#ifndef SCREEN1VIEW_HPP +#define SCREEN1VIEW_HPP + +#include +#include + +class Screen1View : public Screen1ViewBase +{ +public: + Screen1View(); + virtual ~Screen1View() {} + virtual void setupScreen(); + virtual void tearDownScreen(); + virtual void slider1Clicked(int value); +protected: +}; + +#endif // SCREEN1VIEW_HPP diff --git a/Appli/TouchGFX/gui/src/common/FrontendApplication.cpp b/Appli/TouchGFX/gui/src/common/FrontendApplication.cpp new file mode 100644 index 0000000..042b28e --- /dev/null +++ b/Appli/TouchGFX/gui/src/common/FrontendApplication.cpp @@ -0,0 +1,7 @@ +#include + +FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap) + : FrontendApplicationBase(m, heap) +{ + +} diff --git a/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenPresenter.cpp b/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenPresenter.cpp new file mode 100644 index 0000000..f8bfc6d --- /dev/null +++ b/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenPresenter.cpp @@ -0,0 +1,18 @@ +#include +#include + +InitScreenPresenter::InitScreenPresenter(InitScreenView& v) + : view(v) +{ + +} + +void InitScreenPresenter::activate() +{ + +} + +void InitScreenPresenter::deactivate() +{ + +} diff --git a/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenView.cpp b/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenView.cpp new file mode 100644 index 0000000..9e2b75b --- /dev/null +++ b/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenView.cpp @@ -0,0 +1,16 @@ +#include + +InitScreenView::InitScreenView() +{ + +} + +void InitScreenView::setupScreen() +{ + InitScreenViewBase::setupScreen(); +} + +void InitScreenView::tearDownScreen() +{ + InitScreenViewBase::tearDownScreen(); +} diff --git a/Appli/TouchGFX/gui/src/model/Model.cpp b/Appli/TouchGFX/gui/src/model/Model.cpp new file mode 100644 index 0000000..ace0ba2 --- /dev/null +++ b/Appli/TouchGFX/gui/src/model/Model.cpp @@ -0,0 +1,12 @@ +#include +#include + +Model::Model() : modelListener(0) +{ + +} + +void Model::tick() +{ + +} diff --git a/Appli/TouchGFX/gui/src/screen1_screen/Screen1Presenter.cpp b/Appli/TouchGFX/gui/src/screen1_screen/Screen1Presenter.cpp new file mode 100644 index 0000000..321680b --- /dev/null +++ b/Appli/TouchGFX/gui/src/screen1_screen/Screen1Presenter.cpp @@ -0,0 +1,18 @@ +#include +#include + +Screen1Presenter::Screen1Presenter(Screen1View& v) + : view(v) +{ + +} + +void Screen1Presenter::activate() +{ + +} + +void Screen1Presenter::deactivate() +{ + +} diff --git a/Appli/TouchGFX/gui/src/screen1_screen/Screen1View.cpp b/Appli/TouchGFX/gui/src/screen1_screen/Screen1View.cpp new file mode 100644 index 0000000..e347785 --- /dev/null +++ b/Appli/TouchGFX/gui/src/screen1_screen/Screen1View.cpp @@ -0,0 +1,20 @@ +#include + +Screen1View::Screen1View() +{ + +} + +void Screen1View::setupScreen() +{ + Screen1ViewBase::setupScreen(); +} + +void Screen1View::tearDownScreen() +{ + Screen1ViewBase::tearDownScreen(); +} +void Screen1View::slider1Clicked(int value) +{ + gauge1.setValue(value); +} diff --git a/Appli/TouchGFX/target/CortexMMCUInstrumentation.cpp b/Appli/TouchGFX/target/CortexMMCUInstrumentation.cpp new file mode 100644 index 0000000..0311f1f --- /dev/null +++ b/Appli/TouchGFX/target/CortexMMCUInstrumentation.cpp @@ -0,0 +1,48 @@ +#include +#include + +namespace touchgfx +{ +void CortexMMCUInstrumentation::init() +{ + // See: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/CEGHJDCF.html + // + // [24] Read/write TRCENA This bit must be set to 1 to enable use of the trace and debug blocks: + // Data Watchpoint and Trace (DWT) + // Instrumentation Trace Macrocell (ITM) + // Embedded Trace Macrocell (ETM) + // Trace Port Interface Unit (TPIU). + // This enables control of power usage unless tracing is required. The application can enable this, for ITM use, or use by a debugger. + + // Enable Debug Exception and Monitor Control Register + *((volatile unsigned int*)0xE000EDFC) |= 0x01000000; + // Enable Lock Access Register + *((volatile unsigned int*)0xE0001FB0) |= 0xC5ACCE55; + // Enable Data Watchpoint and Trace Control Register + *((volatile unsigned int*)0xE0001000) |= 1; +} + +//Board specific clockfrequency +unsigned int CortexMMCUInstrumentation::getElapsedUS(unsigned int start, unsigned int now, unsigned int clockfrequency) +{ + return ((now - start) + (clockfrequency / 2)) / clockfrequency; +} + +unsigned int CortexMMCUInstrumentation::getCPUCycles() +{ + return *((volatile unsigned int*)0xE0001004); +} + +void CortexMMCUInstrumentation::setMCUActive(bool active) +{ + if (active) //idle task sched out + { + uint32_t cc_temp = getCPUCycles() - cc_in; + cc_consumed += cc_temp; + } + else //idle task sched in + { + cc_in = getCPUCycles(); + } +} +} diff --git a/Appli/TouchGFX/target/CortexMMCUInstrumentation.hpp b/Appli/TouchGFX/target/CortexMMCUInstrumentation.hpp new file mode 100644 index 0000000..ff4af0f --- /dev/null +++ b/Appli/TouchGFX/target/CortexMMCUInstrumentation.hpp @@ -0,0 +1,74 @@ +#ifndef CORTEXMMCUINSTRUMENTATION_HPP +#define CORTEXMMCUINSTRUMENTATION_HPP + +#include +#include + +namespace touchgfx +{ +/** + * @class CortexMMCUInstrumentation CortexMMCUInstrumentation.hpp platform/core/arm/cortex-m/CortexMMCUInstrumentation.hpp + * + * @brief Interface for instrumenting Cortex-M processors to measure MCU load via measured CPU + * cycles. + * + * Interface for instrumenting Cortex-M processors to measure MCU load via measured CPU + * cycles. + * + * @sa MCUInstrumentation + */ +class CortexMMCUInstrumentation : public MCUInstrumentation +{ +public: + /** + * @fn virtual void CortexMMCUInstrumentation::init(); + * + * @brief Initialization. + * + * Initialization. + */ + virtual void init(); + + /** + * @fn virtual unsigned int CortexMMCUInstrumentation::getElapsedUS(unsigned int start, unsigned int now, unsigned int clockfrequency); + * + * @brief Gets elapsed microseconds basedon clockfrequency. + * + * Gets elapsed microseconds basedon clockfrequency. + * + * @param start Start time. + * @param now Current time. + * @param clockfrequency Clock frequency of the system. + * + * @return Elapsed microseconds start and now. + */ + virtual unsigned int getElapsedUS(unsigned int start, unsigned int now, unsigned int clockfrequency); + + /** + * @fn virtual unsigned int CortexMMCUInstrumentation::getCPUCycles(); + * + * @brief Gets CPU cycles from register. + * + * Gets CPU cycles from register. + * + * @return CPU cycles. + */ + virtual unsigned int getCPUCycles(); + + /** + * @fn virtual void CortexMMCUInstrumentation::setMCUActive(bool active); + * + * @brief Register if MCU is active by measuring cpu cycles. + * + * Register if MCU is active by measuring cpu cycles. If user wishes to track + * MCU load, this method should be called whenever the OS Idle task is scheduled + * in or out. This method makes calls to a concrete implementation of GPIO + * functionality and a concrete implementation of cpu cycles. + * + * @param active If true, MCU is registered as being active, inactive otherwise. + */ + virtual void setMCUActive(bool active); +}; +} // namespace touchgfx + +#endif // CORTEXMMCUINSTRUMENTATION_HPP diff --git a/Appli/TouchGFX/target/STM32TouchController.cpp b/Appli/TouchGFX/target/STM32TouchController.cpp new file mode 100644 index 0000000..4a2cbee --- /dev/null +++ b/Appli/TouchGFX/target/STM32TouchController.cpp @@ -0,0 +1,94 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : STM32TouchController.cpp + ****************************************************************************** + * This file was created by TouchGFX Generator 4.22.1. This file is only + * generated once! Delete this file from your project and re-generate code + * using STM32CubeMX or change this file manually to update it. + ****************************************************************************** + * @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 */ + +/* USER CODE BEGIN STM32TouchController */ +#include +#include +#include +#include "main.h" + +volatile bool doSampleTouch = false; + +extern "C" I2C_HandleTypeDef hi2c1; + +using namespace touchgfx; +extern "C" +{ + void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) + { + if (GPIO_Pin == TP_IRQ_Pin) + { + /* Communication with TS is done via I2C. + Often the sw requires ISRs (interrupt service routines) to be quick while communication + with I2C can be considered relatively long (depending on SW requirements). + Considering that the TS feature don't need immediate reaction, + it is suggested to use polling mode instead of EXTI mode, + in order to avoid blocking I2C communication on interrupt service routines */ + + /* Here an example of implementation is proposed which is a mix between pooling and exit mode: + On ISR a flag is set (exti5_received), the main loop polls on the flag rather then polling the TS; + Mcu communicates with TS only when the flag has been set by ISR. This is just an example: + the users should choose they strategy depending on their application needs.*/ + + doSampleTouch = true; + return; + } + } +} + +void STM32TouchController::init() +{ + // No init needed +} + +bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y) +{ + uint8_t touches = 0; + uint8_t buf[6]; + const uint16_t STATUS_REG = 0x814E; + const uint16_t TOUCH_POS_REG = 0x8150; + uint8_t ZERO = 0; + + NVIC_DisableIRQ(TP_IRQ_EXTI_IRQn); + if (doSampleTouch) + { + HAL_I2C_Mem_Read(&hi2c1, 0xBA, STATUS_REG, 2, buf, 1, HAL_MAX_DELAY); + touches = (0x0F & buf[0]); + + HAL_I2C_Mem_Write(&hi2c1, 0xBA, STATUS_REG, 2, &ZERO, 1, HAL_MAX_DELAY); + + doSampleTouch = false; + + if (touches > 0) + { + HAL_I2C_Mem_Read(&hi2c1, 0xBA, TOUCH_POS_REG, 2, buf, 4, HAL_MAX_DELAY); + x = buf[0] + (buf[1] << 8); + y = buf[2] + (buf[3] << 8); + } + } + NVIC_EnableIRQ(TP_IRQ_EXTI_IRQn); + + return (touches > 0); +} +/* USER CODE END STM32TouchController */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/STM32TouchController.hpp b/Appli/TouchGFX/target/STM32TouchController.hpp new file mode 100644 index 0000000..a7645db --- /dev/null +++ b/Appli/TouchGFX/target/STM32TouchController.hpp @@ -0,0 +1,72 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : STM32TouchController.hpp + ****************************************************************************** + * This file was created by TouchGFX Generator 4.22.1. This file is only + * generated once! Delete this file from your project and re-generate code + * using STM32CubeMX or change this file manually to update it. + ****************************************************************************** + * @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 */ + +/* USER CODE BEGIN STM32TouchController */ + +#ifndef STM32TOUCHCONTROLLER_HPP +#define STM32TOUCHCONTROLLER_HPP + +#include + +/** + * @class STM32TouchController + * + * @brief This class specializes TouchController Interface. + * + * @sa touchgfx::TouchController + */ + +class STM32TouchController : public touchgfx::TouchController +{ +public: + + STM32TouchController() {} + + /** + * @fn virtual void STM32TouchController::init() = 0; + * + * @brief Initializes touch controller. + * + * Initializes touch controller. + */ + virtual void init(); + + /** + * @fn virtual bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y) = 0; + * + * @brief Checks whether the touch screen is being touched, and if so, what coordinates. + * + * Checks whether the touch screen is being touched, and if so, what coordinates. + * + * @param [out] x The x position of the touch + * @param [out] y The y position of the touch + * + * @return True if a touch has been detected, otherwise false. + */ + virtual bool sampleTouch(int32_t& x, int32_t& y); +}; + +#endif // STM32TOUCHCONTROLLER_HPP + +/* USER CODE END STM32TouchController */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/TouchGFXGPIO.cpp b/Appli/TouchGFX/target/TouchGFXGPIO.cpp new file mode 100644 index 0000000..4af5a14 --- /dev/null +++ b/Appli/TouchGFX/target/TouchGFXGPIO.cpp @@ -0,0 +1,176 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : TouchGFXGPIO.cpp + ****************************************************************************** + * This file was created by TouchGFX Generator 4.22.1. This file is only + * generated once! Delete this file from your project and re-generate code + * using STM32CubeMX or change this file manually to update it. + ****************************************************************************** + * @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 */ + +#include + +/** + * GPIO_ID Enum + * The signals represented by this enum are used by TouchGFX framework to signal internal events. + * + * VSYNC_FREQ, /// Pin is toggled at each VSYNC + * RENDER_TIME, /// Pin is high when frame rendering begins, low when finished + * FRAME_RATE, /// Pin is toggled when the frame buffers are swapped. + * MCU_ACTIVE /// Pin is high when framework is utilizing the MCU. + * + * Configure GPIO's with the same name as the GPIO_IDs above, as output, in CubeMX to export + * the signals for performance measuring. See support.touchgfx.com for further details. + * + */ + +/* USER CODE BEGIN TouchGFXGPIO.cpp */ +#include "main.h" + +using namespace touchgfx; + +/* + * Perform configuration of IO pins. + */ +void GPIO::init() +{ + +} + +/* + * Sets a pin high. + */ +void GPIO::set(GPIO_ID id) +{ + switch (id) + { + case GPIO::VSYNC_FREQ: +#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin) + HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_SET); +#endif + break; + case GPIO::RENDER_TIME: +#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin) + HAL_GPIO_WritePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin, GPIO_PIN_SET); +#endif + break; + case GPIO::FRAME_RATE: +#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin) + HAL_GPIO_WritePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin, GPIO_PIN_SET); +#endif + break; + case GPIO::MCU_ACTIVE: +#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin) + HAL_GPIO_WritePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin, GPIO_PIN_SET); +#endif + break; + } +} + +/* + * Sets a pin low. + */ +void GPIO::clear(GPIO_ID id) +{ + switch (id) + { + case GPIO::VSYNC_FREQ: +#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin) + HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_RESET); +#endif + break; + case GPIO::RENDER_TIME: +#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin) + HAL_GPIO_WritePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin, GPIO_PIN_RESET); +#endif + break; + case GPIO::FRAME_RATE: +#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin) + HAL_GPIO_WritePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin, GPIO_PIN_RESET); +#endif + break; + case GPIO::MCU_ACTIVE: +#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin) + HAL_GPIO_WritePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin, GPIO_PIN_RESET); +#endif + break; + } +} + +/* + * Toggles a pin. + */ +void GPIO::toggle(GPIO_ID id) +{ + switch (id) + { + case GPIO::VSYNC_FREQ: +#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin) + HAL_GPIO_TogglePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin); +#endif + break; + case GPIO::RENDER_TIME: +#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin) + HAL_GPIO_TogglePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin); +#endif + break; + case GPIO::FRAME_RATE: +#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin) + HAL_GPIO_TogglePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin); +#endif + break; + case GPIO::MCU_ACTIVE: +#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin) + HAL_GPIO_TogglePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin); +#endif + break; + } +} + +/* + * Gets the state of a pin. + */ +bool GPIO::get(GPIO_ID id) +{ + GPIO_PinState bitstatus = GPIO_PIN_RESET; + switch (id) + { + case GPIO::VSYNC_FREQ: +#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin) + bitstatus = HAL_GPIO_ReadPin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin); +#endif + break; + case GPIO::RENDER_TIME: +#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin) + bitstatus = HAL_GPIO_ReadPin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin); +#endif + break; + case GPIO::FRAME_RATE: +#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin) + bitstatus = HAL_GPIO_ReadPin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin); +#endif + break; + case GPIO::MCU_ACTIVE: +#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin) + bitstatus = HAL_GPIO_ReadPin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin); +#endif + break; + } + return (bitstatus == GPIO_PIN_SET); +} + +/* USER CODE END TouchGFXGPIO.cpp */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/TouchGFXHAL.cpp b/Appli/TouchGFX/target/TouchGFXHAL.cpp new file mode 100644 index 0000000..7ee3cee --- /dev/null +++ b/Appli/TouchGFX/target/TouchGFXHAL.cpp @@ -0,0 +1,189 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : TouchGFXHAL.cpp + ****************************************************************************** + * This file was created by TouchGFX Generator 4.22.1. This file is only + * generated once! Delete this file from your project and re-generate code + * using STM32CubeMX or change this file manually to update it. + ****************************************************************************** + * @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 */ + +#include + +/* USER CODE BEGIN TouchGFXHAL.cpp */ +#include "FreeRTOS.h" + +using namespace touchgfx; + +namespace +{ +LOCATION_PRAGMA_NOLOAD("TouchGFX_Framebuffer") +uint32_t animationBuffer[(800 * 480 * 2 + 3) / 4] LOCATION_ATTRIBUTE_NOLOAD("TouchGFX_Framebuffer"); +} + +void TouchGFXHAL::initialize() +{ + // Calling parent implementation of initialize(). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + // Please note, HAL::initialize() must be called to initialize the framework. + + TouchGFXGeneratedHAL::initialize(); + setAnimationStorage((void*)animationBuffer); //enable the animation storage to allow slide animations + instrumentation.init(); + setMCUInstrumentation(&instrumentation); + enableMCULoadCalculation(true); +} + +/** + * Gets the frame buffer address used by the TFT controller. + * + * @return The address of the frame buffer currently being displayed on the TFT. + */ +uint16_t* TouchGFXHAL::getTFTFrameBuffer() const +{ + // Calling parent implementation of getTFTFrameBuffer(). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + + return TouchGFXGeneratedHAL::getTFTFrameBuffer(); +} + +/** + * Sets the frame buffer address used by the TFT controller. + * + * @param [in] address New frame buffer address. + */ +void TouchGFXHAL::setTFTFrameBuffer(uint16_t* address) +{ + // Calling parent implementation of setTFTFrameBuffer(uint16_t* address). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + + TouchGFXGeneratedHAL::setTFTFrameBuffer(address); +} + +/** + * This function is called whenever the framework has performed a partial draw. + * + * @param rect The area of the screen that has been drawn, expressed in absolute coordinates. + * + * @see flushFrameBuffer(). + */ +void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect) +{ + // Calling parent implementation of flushFrameBuffer(const touchgfx::Rect& rect). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + // Please note, HAL::flushFrameBuffer(const touchgfx::Rect& rect) must + // be called to notify the touchgfx framework that flush has been performed. + // To calculate he start adress of rect, + // use advanceFrameBufferToRect(uint8_t* fbPtr, const touchgfx::Rect& rect) + // defined in TouchGFXGeneratedHAL.cpp + + TouchGFXGeneratedHAL::flushFrameBuffer(rect); +} + +bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes) +{ + return TouchGFXGeneratedHAL::blockCopy(dest, src, numBytes); +} + +/** + * Configures the interrupts relevant for TouchGFX. This primarily entails setting + * the interrupt priorities for the DMA and LCD interrupts. + */ +void TouchGFXHAL::configureInterrupts() +{ + // Calling parent implementation of configureInterrupts(). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + + TouchGFXGeneratedHAL::configureInterrupts(); +} + +/** + * Used for enabling interrupts set in configureInterrupts() + */ +void TouchGFXHAL::enableInterrupts() +{ + // Calling parent implementation of enableInterrupts(). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + + TouchGFXGeneratedHAL::enableInterrupts(); +} + +/** + * Used for disabling interrupts set in configureInterrupts() + */ +void TouchGFXHAL::disableInterrupts() +{ + // Calling parent implementation of disableInterrupts(). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + + TouchGFXGeneratedHAL::disableInterrupts(); +} + +/** + * Configure the LCD controller to fire interrupts at VSYNC. Called automatically + * once TouchGFX initialization has completed. + */ +void TouchGFXHAL::enableLCDControllerInterrupt() +{ + // Calling parent implementation of enableLCDControllerInterrupt(). + // + // To overwrite the generated implementation, omit call to parent function + // and implemented needed functionality here. + + TouchGFXGeneratedHAL::enableLCDControllerInterrupt(); +} + +bool TouchGFXHAL::beginFrame() +{ + return TouchGFXGeneratedHAL::beginFrame(); +} + +void TouchGFXHAL::endFrame() +{ + TouchGFXGeneratedHAL::endFrame(); +} + +extern "C" +{ + portBASE_TYPE IdleTaskHook(void* p) + { + if ((int)p) //idle task sched out + { + touchgfx::HAL::getInstance()->setMCUActive(true); + } + else //idle task sched in + { + touchgfx::HAL::getInstance()->setMCUActive(false); + } + return pdTRUE; + } +} +/* USER CODE END TouchGFXHAL.cpp */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/TouchGFXHAL.hpp b/Appli/TouchGFX/target/TouchGFXHAL.hpp new file mode 100644 index 0000000..05fda1b --- /dev/null +++ b/Appli/TouchGFX/target/TouchGFXHAL.hpp @@ -0,0 +1,174 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : TouchGFXHAL.hpp + ****************************************************************************** + * This file was created by TouchGFX Generator 4.22.1. This file is only + * generated once! Delete this file from your project and re-generate code + * using STM32CubeMX or change this file manually to update it. + ****************************************************************************** + * @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 */ +#ifndef TouchGFXHAL_HPP +#define TouchGFXHAL_HPP + +/* USER CODE BEGIN TouchGFXHAL.hpp */ + +#include +#include + +/** + * @class TouchGFXHAL + * + * @brief HAL implementation for TouchGFX. + * + * @sa HAL + */ +class TouchGFXHAL : public TouchGFXGeneratedHAL +{ +public: + /** + * @fn TouchGFXHAL::TouchGFXHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : TouchGFXGeneratedHAL(dma, display, tc, width, height) + * + * @brief Constructor. + * + * Constructor. Initializes members. + * + * @param [in,out] dma Reference to DMA interface. + * @param [in,out] display Reference to LCD interface. + * @param [in,out] tc Reference to Touch Controller driver. + * @param width Width of the display. + * @param height Height of the display. + */ + TouchGFXHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : TouchGFXGeneratedHAL(dma, display, tc, width, height) + { + } + + virtual void initialize(); + + /** + * @fn virtual void TouchGFXHAL::disableInterrupts(); + * + * @brief Disables the DMA and LCD interrupts. + * + * Disables the DMA and LCD interrupts. + */ + virtual void disableInterrupts(); + + /** + * @fn virtual void TouchGFXHAL::enableInterrupts(); + * + * @brief Enables the DMA and LCD interrupts. + * + * Enables the DMA and LCD interrupts. + */ + virtual void enableInterrupts(); + + /** + * @fn virtual void TouchGFXHAL::configureInterrupts(); + * + * @brief Sets the DMA and LCD interrupt priorities. + * + * Sets the DMA and LCD interrupt priorities. + */ + virtual void configureInterrupts(); + + /** + * @fn virtual void TouchGFXHAL::enableLCDControllerInterrupt(); + * + * @brief Configure the LCD controller to fire interrupts at VSYNC. + * + * Configure the LCD controller to fire interrupts at VSYNC. Called automatically + * once TouchGFX initialization has completed. + */ + virtual void enableLCDControllerInterrupt(); + + virtual bool beginFrame(); + + virtual void endFrame(); + + /** + * @fn virtual void TouchGFXHAL::flushFrameBuffer(); + * + * @brief This function is called whenever the framework has performed a complete draw. + * + * This specialization is only in place to keep compilers happy. Base impl. will call the + * Rect version. + * @see HAL::flushFrameBuffer + */ + virtual void flushFrameBuffer() + { + TouchGFXGeneratedHAL::flushFrameBuffer(); + } + + /** + * @fn virtual void TouchGFXHAL::flushFrameBuffer(const Rect& rect); + * + * @brief This function is called whenever the framework has performed a partial draw. + * + * This function is called whenever the framework has performed a partial draw. + * On the STM32F7, make sure to clean and invalidate the data cache. This is to + * ensure that LTDC sees correct data when transferring to the display. + * + * @param rect The area of the screen that has been drawn, expressed in absolute coordinates. + * + * @see flushFrameBuffer(). + */ + virtual void flushFrameBuffer(const touchgfx::Rect& rect); + + /** + * @fn virtual bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes); + * + * @brief This function performs a platform-specific memcpy. + * + * This function performs a platform-specific memcpy, if supported by the hardware. + * + * @param [out] dest Pointer to destination memory. + * @param [in] src Pointer to source memory. + * @param numBytes Number of bytes to copy. + * + * @return true if the copy succeeded, false if copy was not performed. + */ + virtual bool blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes); + +protected: + /** + * @fn virtual uint16_t* TouchGFXHAL::getTFTFrameBuffer() const; + * + * @brief Gets the frame buffer address used by the TFT controller. + * + * Gets the frame buffer address used by the TFT controller. + * + * @return The address of the frame buffer currently being displayed on the TFT. + */ + virtual uint16_t* getTFTFrameBuffer() const; + + /** + * @fn virtual void TouchGFXHAL::setTFTFrameBuffer(uint16_t* adr); + * + * @brief Sets the frame buffer address used by the TFT controller. + * + * Sets the frame buffer address used by the TFT controller. + * + * @param [in,out] adr New frame buffer address. + */ + virtual void setTFTFrameBuffer(uint16_t* adr); +private: + touchgfx::CortexMMCUInstrumentation instrumentation; +}; + +/* USER CODE END TouchGFXHAL.hpp */ + +#endif // TouchGFXHAL_HPP + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/DirectFrameBufferVideoController.hpp b/Appli/TouchGFX/target/generated/DirectFrameBufferVideoController.hpp new file mode 100644 index 0000000..869ec85 --- /dev/null +++ b/Appli/TouchGFX/target/generated/DirectFrameBufferVideoController.hpp @@ -0,0 +1,370 @@ +/** + ****************************************************************************** + * File Name : DirectFrameBufferVideoController.hpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#ifndef TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP +#define TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP + +#include +#include +#include +#include + +/** + * Strategy: + * Decode directly into the framebuffer in draw. + * Tick will decide if we are going to a new frame. + */ +template +class DirectFrameBufferVideoController : public touchgfx::VideoController +{ +public: + DirectFrameBufferVideoController() + : VideoController(), allowSkipFrames(true) + { + assert((no_streams > 0) && "Video: Number of streams zero!"); + + // Clear arrays + memset(mjpegDecoders, 0, sizeof(mjpegDecoders)); + } + + virtual Handle registerVideoWidget(touchgfx::VideoWidget& widget) + { + // Find stream handle for Widget + Handle handle = getFreeHandle(); + + streams[handle].isActive = true; + + //Set Widget buffer format and address + widget.setVideoBufferFormat(output_format, 0, 0); + widget.setVideoBuffer((uint8_t*)0); + + return handle; + } + + virtual void unregisterVideoWidget(const Handle handle) + { + streams[handle].isActive = false; + } + + virtual void setFrameRate(const Handle handle, uint32_t ui_frames, uint32_t video_frames) + { + assert(handle < no_streams); + Stream& stream = streams[handle]; + + // Reset counters + stream.frameCount = 0; + stream.tickCount = 0; + + // Save requested frame rate ratio + stream.frame_rate_ticks = ui_frames; + stream.frame_rate_video = video_frames; + } + + virtual void setVideoData(const Handle handle, const uint8_t* movie, const uint32_t length) + { + assert(handle < no_streams); + + // Reset decoder to first frame + mjpegDecoders[handle]->setVideoData(movie, length); + + // Lower flag to show the first frame + Stream& stream = streams[handle]; + stream.frameNumber = mjpegDecoders[handle]->getCurrentFrameNumber(); + stream.doDecodeNextFrame = false; + + // Stop playing + setCommand(handle, PAUSE, 0); + } + + virtual void setVideoData(const Handle handle, touchgfx::VideoDataReader& reader) + { + assert(handle < no_streams); + + // Reset decoder to first frame + mjpegDecoders[handle]->setVideoData(reader); + + // Lower flag to show the first frame + Stream& stream = streams[handle]; + stream.frameNumber = mjpegDecoders[handle]->getCurrentFrameNumber(); + stream.doDecodeNextFrame = false; + + // Stop playing + setCommand(handle, PAUSE, 0); + } + + virtual void setCommand(const Handle handle, Command cmd, uint32_t param) + { + assert(handle < no_streams); + Stream& stream = streams[handle]; + + switch (cmd) + { + case PLAY: + // Cannot Play without movie + if (mjpegDecoders[handle]->hasVideo()) + { + stream.isPlaying = true; + stream.isShowingOneFrame = false; + // Reset counters + stream.frameCount = 0; + stream.tickCount = 0; + // If non-repeating video stopped at the end, kick to next frame + if (!stream.repeat) + { + MJPEGDecoder* const decoder = mjpegDecoders[handle]; + if (decoder->getCurrentFrameNumber() == decoder->getNumberOfFrames()) + { + decoder->gotoNextFrame(); + } + } + } + break; + case PAUSE: + stream.isPlaying = false; + stream.isShowingOneFrame = false; + break; + case SEEK: + stream.seek_to_frame = param; + // Reset counters + stream.frameCount = 0; + stream.tickCount = 0; + break; + case SHOW: + stream.seek_to_frame = param; + stream.isShowingOneFrame = true; + stream.doDecodeNextFrame = true; + // Reset counters + stream.frameCount = 0; + stream.tickCount = 0; + break; + case STOP: + stream.isPlaying = false; + stream.isShowingOneFrame = false; + stream.seek_to_frame = 1; + // Reset counters + stream.frameCount = 0; + stream.tickCount = 0; + break; + case SET_REPEAT: + stream.repeat = (param > 0); + break; + } + } + + virtual bool updateFrame(const Handle handle, touchgfx::VideoWidget& widget) + { + assert(handle < no_streams); + Stream& stream = streams[handle]; + + bool hasMoreFrames = true; + + if (stream.isPlaying || stream.isShowingOneFrame) + { + // Increase tickCount + stream.tickCount += HAL::getInstance()->getLCDRefreshCount(); + + // Lower flag + stream.isShowingOneFrame = false; + + if (stream.doDecodeNextFrame) + { + MJPEGDecoder* const decoder = mjpegDecoders[handle]; + // Invalidate to get widget redrawn + widget.invalidate(); + // Seek or increment video frame + if (stream.seek_to_frame > 0) + { + decoder->gotoFrame(stream.seek_to_frame); + hasMoreFrames = (stream.seek_to_frame < decoder->getNumberOfFrames()); + stream.seek_to_frame = 0; + } + else + { + if (stream.skip_frames > 0) + { + decoder->gotoFrame(decoder->getCurrentFrameNumber() + stream.skip_frames); + stream.frameCount += stream.skip_frames; + stream.skip_frames = 0; + } + if (stream.repeat) + { + hasMoreFrames = decoder->gotoNextFrame(); + } + else + { + if (decoder->getCurrentFrameNumber() < decoder->getNumberOfFrames()) + { + hasMoreFrames = decoder->gotoNextFrame(); + } + else + { + stream.isPlaying = false; + hasMoreFrames = false; + } + } + } + + stream.frameNumber = decoder->getCurrentFrameNumber(); + stream.frameCount++; + } + + // Save decode status for next frame + stream.doDecodeNextFrame = decodeForNextTick(stream); + } + + return hasMoreFrames; + } + + virtual void draw(const Handle handle, const touchgfx::Rect& invalidatedArea, const touchgfx::VideoWidget& widget) + { + assert(handle < no_streams); + + if (output_format != Bitmap::RGB565 && output_format != Bitmap::RGB888 && output_format != Bitmap::ARGB8888) + { + return; + } + + if (mjpegDecoders[handle]->hasVideo()) + { + uint8_t* wbuf = (uint8_t*)touchgfx::HAL::getInstance()->lockFrameBufferForRenderingMethod(touchgfx::HAL::HARDWARE); + touchgfx::Rect absolute = widget.getAbsoluteRect(); + DisplayTransformation::transformDisplayToFrameBuffer(absolute); + + // Get frame buffer pointer to upper left of widget in framebuffer coordinates + switch (output_format) + { + case Bitmap::RGB565: + wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 2; + break; + case Bitmap::RGB888: + wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 3; + break; + case Bitmap::ARGB8888: + wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 4; + break; + default: + break; + } + + // Decode relevant part of the frame to the framebuffer + mjpegDecoders[handle]->decodeFrame(invalidatedArea, wbuf, touchgfx::HAL::FRAME_BUFFER_WIDTH); + // Release frame buffer + touchgfx::HAL::getInstance()->unlockFrameBuffer(); + } + } + + void addDecoder(MJPEGDecoder& decoder, uint32_t index) + { + assert(index < no_streams); + mjpegDecoders[index] = &decoder; + } + + virtual uint32_t getCurrentFrameNumber(const Handle handle) + { + assert(handle < no_streams); + Stream& stream = streams[handle]; + + return stream.frameNumber; + } + + virtual void getVideoInformation(const Handle handle, touchgfx::VideoInformation* data) + { + assert(handle < no_streams); + mjpegDecoders[handle]->getVideoInfo(data); + } + + virtual bool getIsPlaying(const Handle handle) + { + assert(handle < no_streams); + Stream& stream = streams[handle]; + return stream.isPlaying; + } + + virtual void setVideoFrameRateCompensation(const bool allow) + { + allowSkipFrames = allow; + } + +private: + class Stream + { + public: + Stream() + : frameCount(0), frameNumber(0), tickCount(0), + frame_rate_video(0), frame_rate_ticks(0), + seek_to_frame(0), + isActive(false), isPlaying(false), isShowingOneFrame(false), repeat(true), + doDecodeNextFrame(false) + { + } + uint32_t frameCount; // Video frames decoded since play + uint32_t frameNumber; // Video frame showed number + uint32_t tickCount; // UI frames since play + uint32_t frame_rate_video; // Ratio of frames wanted counter + uint32_t frame_rate_ticks; // Ratio of frames wanted divider + uint32_t seek_to_frame; // Requested next frame number + uint32_t skip_frames; // Number of frames to skip to keep frame rate + bool isActive; + bool isPlaying; + bool isShowingOneFrame; + bool repeat; + bool doDecodeNextFrame; // High if we should go to next frame in next tick + }; + + MJPEGDecoder* mjpegDecoders[no_streams]; + Stream streams[no_streams]; + bool allowSkipFrames; + + /** + * Return true, if new video frame should be decoded for the next tick (keep video decode framerate low) + */ + bool decodeForNextTick(Stream& stream) + { + // Running in UI thread + + // Compare tickCount/frameNumber to frame_rate_ticks/frame_rate_video + if ((stream.tickCount * stream.frame_rate_video) > (stream.frame_rate_ticks * stream.frameCount)) + { + if (allowSkipFrames) + { + stream.skip_frames = (stream.tickCount * stream.frame_rate_video - stream.frame_rate_ticks * stream.frameCount) / stream.frame_rate_ticks; + if (stream.skip_frames > 0) + { + stream.skip_frames--; + } + } + return true; + } + return false; + } + + Handle getFreeHandle() + { + for (uint32_t i = 0; i < no_streams; i++) + { + if (streams[i].isActive == false) + { + return static_cast(i); + } + } + + assert(0 && "Unable to find free video stream handle!"); + return static_cast(0); + } +}; + +#endif // TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP diff --git a/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp b/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp new file mode 100644 index 0000000..d9ff4a8 --- /dev/null +++ b/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp @@ -0,0 +1,934 @@ +/** + ****************************************************************************** + * File Name : HardwareMJPEGDecoder.cpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include +#include + +extern "C" +{ +#include +#include + + uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef* hjpeg, uint8_t* input, uint32_t chunkSizeIn, uint8_t* output); + uint32_t JPEG_OutputHandler(JPEG_HandleTypeDef* hjpeg); + void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef* hjpeg); + void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef* hjpeg); + void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef* hjpeg, uint8_t* pDataOut, uint32_t OutDataLength); + void DMA2D_CropBuffer(JPEG_Data_BufferTypeDef& job); + void DMA2D_CopyBuffer(JPEG_Data_BufferTypeDef& job); + void DMA2D_ExternalJobCompleted(JPEG_Data_BufferTypeDef& job); +} + +namespace +{ +uint8_t* FrameBufferAddress; +uint32_t JPEG_InputImageIndex; +uint32_t JPEG_InputImageSize_Bytes; +uint32_t JPEG_InputImageAddress; +volatile uint32_t Jpeg_HWDecodingEnd = 0; +volatile uint32_t JPEG_output_is_paused = 0; +volatile uint32_t JpegProcessing_End = 0; +uint32_t MCU_TotalNb = 0; +touchgfx::DMA_Interface* DMA2D_reference; +volatile uint32_t JPEG_OUT_Write_BufferIndex = 0; +uint32_t FrameBufferWidth; +volatile uint32_t line_count = 0; +} + +#define MCU_WIDTH_PIXELS ((uint32_t)16) +#define MCU_HEIGHT_PIXELS ((uint32_t)16) +#define MCU_CHROMA_420_SIZE_BYTES ((uint32_t)384) + +#define CHUNK_SIZE_IN ((uint32_t)(1024*52)) /* Max block size */ +#define CHUNK_SIZE_OUT ((uint32_t)(MCU_CHROMA_420_SIZE_BYTES * ((800 + MCU_WIDTH_PIXELS - 1) / MCU_WIDTH_PIXELS))) + +LOCATION_PRAGMA_32("TouchGFX_MCU_Data_OutBuffer0") +uint8_t MCU_Data_OutBuffer0[CHUNK_SIZE_OUT] LOCATION_ATTRIBUTE_32("TouchGFX_MCU_Data_OutBuffer0"); +LOCATION_PRAGMA_32("TouchGFX_MCU_Data_OutBuffer1") +uint8_t MCU_Data_OutBuffer1[CHUNK_SIZE_OUT] LOCATION_ATTRIBUTE_32("TouchGFX_MCU_Data_OutBuffer1"); + +uint8_t MCU_Cropping_Buffer[MCU_WIDTH_PIXELS * MCU_HEIGHT_PIXELS * 2]; + +__IO uint32_t MCU_BlockIndex = 0; + +SEM_TYPE semDecodingDone; + +extern JPEG_ConfTypeDef* JPEG_Info; +extern JPEG_HandleTypeDef hjpeg; + +volatile uint32_t JPEG_OUT_Read_BufferIndex = 0; +volatile uint32_t DMA2D_CopyBufferEnd = 0; + +JPEG_Data_BufferTypeDef Jpeg_OUT_BufferTab[NB_OUTPUT_DATA_BUFFERS] = +{ + {JPEG_BUFFER_EMPTY, MCU_Data_OutBuffer0, 0, 0, NULL, false, false, 0, false}, + {JPEG_BUFFER_EMPTY, MCU_Data_OutBuffer1, 0, 0, NULL, false, false, 0, false}, +}; + +static struct JPEG_MCU_RGB_Converter +{ + uint32_t WidthExtend; + uint32_t ScaledWidth; + uint32_t LastLineHeight; + uint32_t MCU_pr_line; + uint32_t bytes_pr_pixel; + uint32_t startY; + uint32_t endY; + uint32_t startX; + uint32_t endX; + uint32_t MCUStart; + uint32_t MCUEnd; + uint32_t MCU_pr_job; + uint32_t firstColOffset; + uint32_t firstRowOffset; + uint32_t lastColOffset; + uint32_t lastRowOffset; +} JPEG_ConvertorParams; + +HardwareMJPEGDecoder::HardwareMJPEGDecoder() + : frameNumber(0), currentMovieOffset(0), indexOffset(0), firstFrameOffset(0), lastFrameEnd(0), movieLength(0), movieData(0), + reader(0), aviBuffer(0), aviBufferLength(0), aviBufferStartOffset(0), lastError(AVI_NO_ERROR) +{ + /* Clear video info */ + videoInfo.frame_height = 0; + videoInfo.frame_width = 0; + videoInfo.ms_between_frames = 0; + videoInfo.number_of_frames = 0; + + /* Create decoding semaphore */ + semDecodingDone = SEM_CREATE(); +} + +int HardwareMJPEGDecoder::compare(const uint32_t offset, const char* str, uint32_t num) +{ + const char* src; + if (reader != 0) + { + /* Assuming data is in buffer! */ + src = reinterpret_cast(aviBuffer + (offset - aviBufferStartOffset)); + } + else + { + src = (const char*)movieData + offset; + } + return strncmp(src, str, num); +} + +inline uint32_t HardwareMJPEGDecoder::getU32(const uint32_t offset) +{ + if (reader != 0) + { + /* Assuming data is in buffer! */ + const uint32_t index = offset - aviBufferStartOffset; + return aviBuffer[index + 0] | (aviBuffer[index + 1] << 8) | (aviBuffer[index + 2] << 16) | (aviBuffer[index + 3] << 24); + } + else + { + volatile const uint8_t* const d = movieData + offset; + uint32_t val = 0U; + val |= d[0]; + val |= d[1] << 8; + val |= d[2] << 16; + val |= d[3] << 24; + return val; + } +} + +inline uint32_t HardwareMJPEGDecoder::getU16(const uint32_t offset) +{ + if (reader != 0) + { + /* Assuming data is in buffer! */ + const uint32_t index = offset - aviBufferStartOffset; + return aviBuffer[index + 0] | (aviBuffer[index + 1] << 8); + } + else + { + volatile const uint8_t* const d = movieData + offset; + uint32_t val = 0U; + val |= d[0]; + val |= d[1] << 8; + return val; + } +} + +const uint8_t* HardwareMJPEGDecoder::readData(uint32_t offset, uint32_t length) +{ + if (reader != 0) + { + if (length > aviBufferLength) + { + lastError = AVI_ERROR_FILE_BUFFER_TO_SMALL; + assert(!"Buffer to small"); + } + + reader->seek(offset); + if (!reader->readData(aviBuffer, length)) + { + lastError = AVI_ERROR_EOF_REACHED; + } + + aviBufferStartOffset = offset; + return aviBuffer; + } + + return movieData + offset; +} + +bool HardwareMJPEGDecoder::decodeNextFrame(uint8_t* buffer, uint16_t buffer_width, uint16_t buffer_height, uint32_t buffer_stride) +{ + assert((frameNumber > 0) && "HardwareMJPEGDecoder decoding without frame data!"); + + /* find next frame and decode it */ + readData(currentMovieOffset, 8); + uint32_t streamNo = getU16(currentMovieOffset); + uint32_t chunkType = getU16(currentMovieOffset + 2); + uint32_t chunkSize = getU32(currentMovieOffset + 4); + + const uint16_t STREAM0 = 0x3030; + const uint16_t TYPEDC = 0x6364; + + bool isCurrentFrameLast; + /* play frame if we have it all */ + if (currentMovieOffset + 8 + chunkSize < movieLength) + { + if (streamNo == STREAM0 && chunkType == TYPEDC && chunkSize > 0) + { + currentMovieOffset += 8; + /* decode frame */ + const uint8_t* chunk = readData(currentMovieOffset, chunkSize); + decodeMJPEGFrame(chunk, chunkSize, buffer, buffer_width, buffer_height, buffer_stride); + frameNumber++; + } + + isCurrentFrameLast = false; + + /* Advance to next frame */ + currentMovieOffset += chunkSize; + if (chunkSize == 0) /* Empty frame - Skip */ + { + currentMovieOffset += 8; + } + currentMovieOffset = (currentMovieOffset + 1) & 0xFFFFFFFE; /* pad to next word */ + + if (currentMovieOffset == lastFrameEnd) + { + frameNumber = 1; + currentMovieOffset = firstFrameOffset; /* start over */ + isCurrentFrameLast = true; + } + } + else + { + frameNumber = 1; + currentMovieOffset = firstFrameOffset; /* start over */ + isCurrentFrameLast = true; + } + return !isCurrentFrameLast; +} + +bool HardwareMJPEGDecoder::gotoNextFrame() +{ + assert((frameNumber > 0) && "HardwareMJPEGDecoder decoding without frame data!"); + + readData(currentMovieOffset, 8); + uint32_t chunkSize = getU32(currentMovieOffset + 4); + + /* increment until next video frame */ + while (currentMovieOffset + 8 + chunkSize < movieLength) + { + /* increment one frame */ + currentMovieOffset += chunkSize + 8; + currentMovieOffset = (currentMovieOffset + 1) & 0xFFFFFFFE; /* pad to next word */ + frameNumber++; + + /* next chunk */ + readData(currentMovieOffset, 8); + /* check it is a video frame */ + uint32_t streamNo = getU16(currentMovieOffset); + uint32_t chunkType = getU16(currentMovieOffset + 2); + chunkSize = getU32(currentMovieOffset + 4); + const uint16_t STREAM0 = 0x3030; + const uint16_t TYPEDC = 0x6364; + + if (streamNo == STREAM0 && chunkType == TYPEDC) + { + /* Found next frame */ + return true; + } + } + + /* skip back to first frame */ + frameNumber = 1; + currentMovieOffset = firstFrameOffset; /* start over */ + return false; +} + +void HardwareMJPEGDecoder::setVideoData(const uint8_t* movie, const uint32_t length) +{ + movieData = movie; + movieLength = length; + reader = 0; /* not using reader */ + + readVideoHeader(); +} + +void HardwareMJPEGDecoder::setVideoData(touchgfx::VideoDataReader& reader) +{ + this->reader = &reader; + movieData = 0; + movieLength = reader.getDataLength(); + + readVideoHeader(); +} + +bool HardwareMJPEGDecoder::hasVideo() +{ + return (reader != 0) || (movieData != 0); +} + +void HardwareMJPEGDecoder::readVideoHeader() +{ + /* Start from the start */ + currentMovieOffset = 0; + lastError = AVI_NO_ERROR; + + /* Make header available in buffer */ + readData(0, 72); + + /* Decode the movie header to find first frame */ + /* Must be RIFF file */ + if (compare(currentMovieOffset, "RIFF", 4)) + { + lastError = AVI_ERROR_NOT_RIFF; + assert(!"RIFF header not found"); + } + + /* skip fourcc and length */ + currentMovieOffset += 8; + if (compare(currentMovieOffset, "AVI ", 4)) + { + lastError = AVI_ERROR_AVI_HEADER_NOT_FOUND; + assert(!"AVI header not found"); + } + + currentMovieOffset += 4; + if (compare(currentMovieOffset, "LIST", 4)) + { + lastError = AVI_ERROR_AVI_LIST_NOT_FOUND; + assert(!"AVI LIST not found"); + } + + /* save AVI List info */ + const uint32_t aviListSize = getU32(currentMovieOffset + 4); + const uint32_t aviListOffset = currentMovieOffset; + assert(aviListSize); + + /* look into header to find frame rate */ + bool foundFrame = true; + uint32_t offset = currentMovieOffset + 8; + if (compare(offset, "hdrl", 4)) + { + lastError = AVI_ERROR_AVI_HDRL_NOT_FOUND; + foundFrame = false; + } + + offset += 4; + if (compare(offset, "avih", 4)) + { + lastError = AVI_ERROR_AVI_AVIH_NOT_FOUND; + foundFrame = false; + } + + if (foundFrame) + { + offset += 8; /* skip fourcc and cb in AVIMAINHEADER */ + videoInfo.ms_between_frames = getU32(offset) / 1000; + videoInfo.number_of_frames = getU32(offset + 16); + videoInfo.frame_width = getU32(offset + 32); + videoInfo.frame_height = getU32(offset + 36); + } + /* skip rest of AVI header, start from end of AVI List */ + + /* look for list with 'movi' header */ + uint32_t listOffset = aviListOffset + aviListSize + 8; + readData(listOffset, 12); + while (compare(listOffset + 8, "movi", 4) && (lastError == AVI_NO_ERROR) && listOffset < movieLength) + { + const uint32_t listSize = getU32(listOffset + 4) + 8; + listOffset += listSize; + readData(listOffset, 12); + } + + if (lastError != AVI_NO_ERROR) + { + lastError = AVI_ERROR_MOVI_NOT_FOUND; + return; + } + + /* save first frame and end of last frame */ + currentMovieOffset = listOffset + 8 + 4; /* skip LIST and 'movi' */ + lastFrameEnd = listOffset + 8 + getU32(listOffset + 4); + + /* find idx */ + const uint32_t listSize = getU32(listOffset + 4) + 8; + listOffset += listSize; + readData(listOffset, 4); + if (!compare(listOffset, "idx1", 4)) + { + indexOffset = listOffset; + } + else + { + lastError = AVI_ERROR_IDX1_NOT_FOUND; + return; + } + + /* start on first frame */ + frameNumber = 1; /* next frame number is 1 */ + firstFrameOffset = currentMovieOffset; +} + +void HardwareMJPEGDecoder::decodeMJPEGFrame(const uint8_t* const mjpgdata, const uint32_t length, uint8_t* outputBuffer, uint16_t bufferWidth, uint16_t bufferHeight, uint32_t bufferStride) +{ + if (length == 0) + { + return; + } + + if (outputBuffer) /* only decode if buffers are assigned. */ + { + /* Update JPEG conversion parameters */ + JPEG_ConvertorParams.bytes_pr_pixel = 2; + JPEG_ConvertorParams.WidthExtend = videoInfo.frame_width; + if ((JPEG_ConvertorParams.WidthExtend % 16) != 0) + { + JPEG_ConvertorParams.WidthExtend += 16 - (JPEG_ConvertorParams.WidthExtend % 16); + } + JPEG_ConvertorParams.ScaledWidth = 800 * JPEG_ConvertorParams.bytes_pr_pixel; + JPEG_ConvertorParams.MCU_pr_line = JPEG_ConvertorParams.WidthExtend / MCU_WIDTH_PIXELS; + JPEG_ConvertorParams.LastLineHeight = (videoInfo.frame_height % MCU_HEIGHT_PIXELS) == 0 ? 0 : MCU_HEIGHT_PIXELS - (videoInfo.frame_height % MCU_HEIGHT_PIXELS); + + FrameBufferWidth = bufferStride / 2; + FrameBufferAddress = outputBuffer; + + JPEG_Decode_DMA(&hjpeg, const_cast(mjpgdata), length, outputBuffer); + DMA2D_reference = dma; + do + { + JpegProcessing_End = JPEG_OutputHandler(&hjpeg); + + /* If nothing to do, allow other tasks */ + if (JpegProcessing_End == 2) + { + SEM_WAIT(semDecodingDone); + } + } while (JpegProcessing_End != 1); + + /* reset flag */ + Jpeg_HWDecodingEnd = 0; + DMA2D_CopyBufferEnd = 0; + } +} + +bool HardwareMJPEGDecoder::decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebuffer_width) +{ + /* Assuming that chunk is available and streamNo and chunkType is correct. */ + /* Check by gotoNextFrame */ + readData(currentMovieOffset, 8); + const uint32_t length = getU32(currentMovieOffset + 4); + + /* Ensure whole frame is read */ + const uint8_t* mjpgdata = readData(currentMovieOffset + 8, length); + + /* Update JPEG conversion parameters */ + JPEG_ConvertorParams.bytes_pr_pixel = 2; + JPEG_ConvertorParams.WidthExtend = videoInfo.frame_width; + if ((JPEG_ConvertorParams.WidthExtend % 16) != 0) + { + JPEG_ConvertorParams.WidthExtend += 16 - (JPEG_ConvertorParams.WidthExtend % 16); + } + JPEG_ConvertorParams.ScaledWidth = 800 * JPEG_ConvertorParams.bytes_pr_pixel; + JPEG_ConvertorParams.MCU_pr_line = JPEG_ConvertorParams.WidthExtend / MCU_WIDTH_PIXELS; + JPEG_ConvertorParams.startY = area.y; + JPEG_ConvertorParams.endY = MIN((uint32_t)area.bottom(), videoInfo.frame_height); + JPEG_ConvertorParams.startX = area.x; + JPEG_ConvertorParams.endX = MIN((uint32_t)area.right(), videoInfo.frame_width); + JPEG_ConvertorParams.MCUStart = JPEG_ConvertorParams.startX / MCU_WIDTH_PIXELS; + JPEG_ConvertorParams.MCUEnd = (JPEG_ConvertorParams.endX + MCU_WIDTH_PIXELS - 1) / MCU_WIDTH_PIXELS; // Ceil division + JPEG_ConvertorParams.MCU_pr_job = JPEG_ConvertorParams.MCUEnd - JPEG_ConvertorParams.MCUStart; + JPEG_ConvertorParams.firstColOffset = JPEG_ConvertorParams.startX % MCU_WIDTH_PIXELS; + JPEG_ConvertorParams.firstRowOffset = JPEG_ConvertorParams.startY % MCU_HEIGHT_PIXELS; + JPEG_ConvertorParams.lastColOffset = (JPEG_ConvertorParams.endX % MCU_WIDTH_PIXELS) == 0 ? 0 : MCU_WIDTH_PIXELS - (JPEG_ConvertorParams.endX % MCU_WIDTH_PIXELS); + JPEG_ConvertorParams.lastRowOffset = (JPEG_ConvertorParams.endY % MCU_HEIGHT_PIXELS) == 0 ? 0 : MCU_HEIGHT_PIXELS - (JPEG_ConvertorParams.endY % MCU_HEIGHT_PIXELS); + + FrameBufferWidth = framebuffer_width; + FrameBufferAddress = frameBuffer; + + JPEG_Decode_DMA(&hjpeg, const_cast(mjpgdata), length, frameBuffer); + DMA2D_reference = dma; + do + { + JpegProcessing_End = JPEG_OutputHandler(&hjpeg); + + /* If nothing to do, wait */ + if (JpegProcessing_End == 2) + { + SEM_WAIT(semDecodingDone); + } + } while (JpegProcessing_End != 1); + + /* reset flag */ + Jpeg_HWDecodingEnd = 0; + DMA2D_CopyBufferEnd = 0; + + return true; +} + +bool HardwareMJPEGDecoder::decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height) +{ + assert(0); + return false; +} + +void HardwareMJPEGDecoder::gotoFrame(uint32_t frameNumber) +{ + if (frameNumber == 0) + { + frameNumber = 1; + } + + if (frameNumber > getNumberOfFrames()) + { + frameNumber = getNumberOfFrames(); + } + + uint32_t offset = indexOffset + 8 + (frameNumber - 1) * 16; + + readData(offset, 16); + + currentMovieOffset = getU32(offset + 8) + firstFrameOffset - 4; + this->frameNumber = frameNumber; +} + +uint32_t HardwareMJPEGDecoder::getNumberOfFrames() +{ + return videoInfo.number_of_frames; +} + +void HardwareMJPEGDecoder::setRepeatVideo(bool repeat) +{ + +} + +void HardwareMJPEGDecoder::getVideoInfo(touchgfx::VideoInformation* data) +{ + *data = videoInfo; +} + +/* C HELPER FUNCTIONS */ + +extern "C" +{ + /** + * @brief Decode_DMA + * @param hjpeg: JPEG handle pointer + * @param JPEGImageBufferAddress : jpg image buffer Address. + * @param JPEGImageSize_Bytes : jpg image size in bytes. + * @param DestAddress : ARGB8888 destination Frame Buffer Address. + * @retval None + */ + uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef* hjpeg, uint8_t* input, uint32_t chunkSizeIn /* length */, uint8_t* output) + { + JPEG_output_is_paused = 0; + JPEG_OUT_Read_BufferIndex = 0; + JPEG_OUT_Write_BufferIndex = 0; + JPEG_InputImageIndex = 0; + JPEG_InputImageAddress = (uint32_t)input; + JPEG_InputImageSize_Bytes = chunkSizeIn; + MCU_BlockIndex = 0; + line_count = 0; + + /* Init buffers */ + for (uint32_t i = 0; i < NB_OUTPUT_DATA_BUFFERS; ++i) + { + Jpeg_OUT_BufferTab[i].State = JPEG_BUFFER_EMPTY; + Jpeg_OUT_BufferTab[i].DataBufferSize = 0; + Jpeg_OUT_BufferTab[i].MCU_index = 0; + Jpeg_OUT_BufferTab[i].OutputBuffer = NULL; + Jpeg_OUT_BufferTab[i].MCU_drawn = 0; + Jpeg_OUT_BufferTab[i].DoCropping = false; + Jpeg_OUT_BufferTab[i].FirstJob = false; + Jpeg_OUT_BufferTab[i].LastJob = false; + } + Jpeg_OUT_BufferTab[0].FirstJob = true; + if (JPEG_ConvertorParams.firstRowOffset != 0) + { + Jpeg_OUT_BufferTab[0].DoCropping = true; + } + + /* Do not return from this function until done with decoding all chunks. */ + HAL_JPEG_Decode_DMA(hjpeg, input, CHUNK_SIZE_IN, Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBuffer, MCU_CHROMA_420_SIZE_BYTES * JPEG_ConvertorParams.MCU_pr_line); + + return 0; + } + + /** + * @brief JPEG Info ready callback + * @param hjpeg: JPEG handle pointer + * @param pInfo: JPEG Info Struct pointer + * @retval None + */ + void HAL_JPEG_InfoReadyCallback(JPEG_HandleTypeDef* hjpeg, JPEG_ConfTypeDef* pInfo) + { + uint32_t hMCU, vMCU; + + if (pInfo->ChromaSubsampling == JPEG_420_SUBSAMPLING) + { + if ((pInfo->ImageWidth % 16) != 0) + { + pInfo->ImageWidth += (16 - (pInfo->ImageWidth % 16)); + } + + if ((pInfo->ImageHeight % 16) != 0) + { + pInfo->ImageHeight += (16 - (pInfo->ImageHeight % 16)); + } + + hMCU = (pInfo->ImageWidth / MCU_WIDTH_PIXELS); + vMCU = (pInfo->ImageHeight / MCU_HEIGHT_PIXELS); + MCU_TotalNb = (hMCU * vMCU); + } + else + { + if (pInfo->ChromaSubsampling == JPEG_422_SUBSAMPLING) + { + if ((pInfo->ImageWidth % 16) != 0) + { + pInfo->ImageWidth += (16 - (pInfo->ImageWidth % 16)); + } + + if ((pInfo->ImageHeight % 8) != 0) + { + pInfo->ImageHeight += (8 - (pInfo->ImageHeight % 8)); + } + } + + if (pInfo->ChromaSubsampling == JPEG_444_SUBSAMPLING) + { + if ((pInfo->ImageWidth % 8) != 0) + { + pInfo->ImageWidth += (8 - (pInfo->ImageWidth % 8)); + } + + if ((pInfo->ImageHeight % 8) != 0) + { + pInfo->ImageHeight += (8 - (pInfo->ImageHeight % 8)); + } + } + } + } + + /** + * @brief JPEG Get Data callback. + * @param hjpeg: JPEG handle pointer + * @param NbDecodedData: Number of decoded (consummed) bytes from input buffer + * @retval None + */ + void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef* hjpeg, uint32_t NbDecodedData) + { + /* Input buffer has been consumed by the peripheral and to ask for a new data chunk if the operation (encoding/decoding) has not been complete yet. */ + JPEG_InputImageIndex += NbDecodedData; + if (JPEG_InputImageIndex < JPEG_InputImageSize_Bytes) + { + JPEG_InputImageAddress = JPEG_InputImageAddress + NbDecodedData; + uint32_t inDataLength = JPEG_InputImageSize_Bytes - JPEG_InputImageIndex; + HAL_JPEG_ConfigInputBuffer(hjpeg, (uint8_t*)JPEG_InputImageAddress, inDataLength >= CHUNK_SIZE_IN ? CHUNK_SIZE_IN : inDataLength); + } + } + + /** + * @brief JPEG Data Ready callback. Data has been converted from JPEG to YCbCr. + * @param hjpeg: JPEG handle pointer + * @param pDataOut: pointer to the output data buffer + * @param OutDataLength: length of output buffer in bytes + * @retval None + */ + void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef* hjpeg, uint8_t* pDataOut, uint32_t OutDataLength) + { + line_count += MCU_HEIGHT_PIXELS; + + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].OutputBuffer = FrameBufferAddress; + + /* Increment framebuffer */ + FrameBufferAddress += FrameBufferWidth * MCU_HEIGHT_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel; + + /* Decode until we reach area to draw */ + if (line_count <= JPEG_ConvertorParams.startY) + { + HAL_JPEG_ConfigOutputBuffer(hjpeg, Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBuffer, MCU_CHROMA_420_SIZE_BYTES * JPEG_ConvertorParams.MCU_pr_line); + return; + } + + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].State = JPEG_BUFFER_FULL; + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBufferSize = OutDataLength; + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].MCU_drawn = 0; + + /* Left column requires cropping */ + if (JPEG_ConvertorParams.firstColOffset != 0) + { + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DoCropping = true; + } + + if (line_count < JPEG_ConvertorParams.endY) + { + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].LastJob = false; + + JPEG_OUT_Write_BufferIndex++; + if (JPEG_OUT_Write_BufferIndex >= NB_OUTPUT_DATA_BUFFERS) + { + JPEG_OUT_Write_BufferIndex = 0; + } + + /* if the other buffer is full, then ui thread might be converting it */ + if (Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].State != JPEG_BUFFER_EMPTY) + { + HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_OUTPUT); + JPEG_output_is_paused = 1; + } + + HAL_JPEG_ConfigOutputBuffer(hjpeg, Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBuffer, MCU_CHROMA_420_SIZE_BYTES * JPEG_ConvertorParams.MCU_pr_line); + } + + /* Stop decoding when we exit area to draw */ + if (line_count >= JPEG_ConvertorParams.endY) + { + Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].LastJob = true; + Jpeg_HWDecodingEnd = 1; + + HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_OUTPUT); + } + + /* Signal Hardware Decoding to wake up */ + if (!DMA2D_reference->isDMARunning()) + { + SEM_POST(semDecodingDone); + } + } + + /** + * @brief JPEG Error callback + * @param hjpeg: JPEG handle pointer + * @retval None + */ + void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef* hjpeg) + { + __disable_irq(); + while (1) + { + } + } + + /** + * @brief JPEG Decode complete callback + * @param hjpeg: JPEG handle pointer + * @retval None + */ + void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef* hjpeg) + { + Jpeg_HWDecodingEnd = 1; + } +} + +/** + * @brief JPEG Ouput Data BackGround Postprocessing . + * @param hjpeg: JPEG handle pointer + * @retval 1 : if JPEG processing has finished, 0 : if JPEG processing still ongoing + */ +uint32_t JPEG_OutputHandler(JPEG_HandleTypeDef* hjpeg) +{ + /* Decode frame complete */ + if (Jpeg_HWDecodingEnd && DMA2D_CopyBufferEnd) + { + /* Abort any ongoing operations */ + if (HAL_JPEG_GetState(hjpeg) == HAL_JPEG_STATE_BUSY_DECODING) + { + HAL_JPEG_Abort(hjpeg); + } + return 1; + } + + /* Try to start DMA2D video transfer if next buffer if full */ + if (!DMA2D_reference->isDMARunning() && (Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].State == JPEG_BUFFER_FULL) && (DMA2D_CopyBufferEnd == 0)) + { + DMA2D_reference->start(); + } + + /* Start JPEG IP if paused and next buffer is empty */ + if ((JPEG_output_is_paused == 1) && (Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].State == JPEG_BUFFER_EMPTY) && (Jpeg_HWDecodingEnd == 0)) + { + JPEG_output_is_paused = 0; + HAL_JPEG_Resume(hjpeg, JPEG_PAUSE_RESUME_OUTPUT); + } + + return 2; +} + +/** + * @brief Configures external DMA2D job to copy YCbCr data to RGB buffer(s) + * @param job: External job reference + * @retval None + */ +void DMA2D_CopyBuffer(JPEG_Data_BufferTypeDef& job) +{ + const uint32_t width = JPEG_ConvertorParams.MCU_pr_job * MCU_WIDTH_PIXELS - job.MCU_drawn * MCU_WIDTH_PIXELS - JPEG_ConvertorParams.lastColOffset; + const uint32_t scaledWidth = (width % MCU_WIDTH_PIXELS) == 0 ? 0 : MCU_WIDTH_PIXELS - (width % MCU_WIDTH_PIXELS); + const uint32_t srcOffset = (JPEG_ConvertorParams.MCUStart + job.MCU_drawn) * MCU_CHROMA_420_SIZE_BYTES; + const uint32_t dstOffset = JPEG_ConvertorParams.MCUStart * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel + + job.MCU_drawn * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel; + + /* Mark job as fully drawn */ + job.MCU_drawn = JPEG_ConvertorParams.MCU_pr_job; + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + if (job.LastJob) /* Last line of frame */ + { + WRITE_REG(DMA2D->NLR, (MCU_HEIGHT_PIXELS - JPEG_ConvertorParams.lastRowOffset) | (width << DMA2D_NLR_PL_Pos)); + } + else + { + WRITE_REG(DMA2D->NLR, MCU_HEIGHT_PIXELS | (width << DMA2D_NLR_PL_Pos)); + } + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(job.OutputBuffer + dstOffset)); + + /* DMA2D OOR register configuration */ + WRITE_REG(DMA2D->OOR, FrameBufferWidth - width); + + /* DMA2D FGOR register configuration */ + WRITE_REG(DMA2D->FGOR, scaledWidth); + + /* DMA2D FGPFCCR register configuration */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_YCBCR | (DMA2D_CSS_420 << DMA2D_FGPFCCR_CSS_Pos) | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (0xFFU << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(job.DataBuffer + srcOffset)); + + /* Configure DMA2D contol register */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); +} + +/** + * @brief Configures external DMA2D job to copy and crop YCbCr data to an RGB cropping buffer + * @param job: External job reference + * @retval None + */ +void DMA2D_CropBuffer(JPEG_Data_BufferTypeDef& job) +{ + const uint32_t colLeftOffset = job.MCU_drawn == 0 ? JPEG_ConvertorParams.firstColOffset : 0; + const uint32_t colRightOffset = job.MCU_drawn == JPEG_ConvertorParams.MCU_pr_job - 1 ? JPEG_ConvertorParams.lastColOffset : 0; + const uint32_t rowTopOffset = job.FirstJob ? JPEG_ConvertorParams.firstRowOffset : 0; + const uint32_t rowBottomOffset = job.LastJob ? JPEG_ConvertorParams.lastRowOffset : 0; + const uint32_t srcOffset = (JPEG_ConvertorParams.MCUStart + job.MCU_drawn) * MCU_CHROMA_420_SIZE_BYTES; + const uint32_t dstOffset = JPEG_ConvertorParams.MCUStart * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel + + job.MCU_drawn * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel + + rowTopOffset * JPEG_ConvertorParams.bytes_pr_pixel * FrameBufferWidth + + colLeftOffset * JPEG_ConvertorParams.bytes_pr_pixel; + const uint32_t cropSrcOffset = colLeftOffset * JPEG_ConvertorParams.bytes_pr_pixel + + rowTopOffset * JPEG_ConvertorParams.bytes_pr_pixel * MCU_HEIGHT_PIXELS; + + /* Update job and assert if more cropping is needed */ + job.MCU_drawn++; + if ((JPEG_ConvertorParams.firstRowOffset == 0) || !job.FirstJob) + { + job.DoCropping = false; + } + + /* Configure BlitOp */ + touchgfx::BlitOp blitOp; + blitOp.operation = touchgfx::BLIT_OP_COPY; + blitOp.pSrc = reinterpret_cast(MCU_Cropping_Buffer + cropSrcOffset); + blitOp.nSteps = MCU_WIDTH_PIXELS - colLeftOffset - colRightOffset; + blitOp.nLoops = MCU_HEIGHT_PIXELS - rowTopOffset - rowBottomOffset; + blitOp.srcLoopStride = MCU_WIDTH_PIXELS; + blitOp.dstLoopStride = FrameBufferWidth; + blitOp.pDst = reinterpret_cast(job.OutputBuffer + dstOffset); + blitOp.srcFormat = touchgfx::Bitmap::RGB565; + blitOp.dstFormat = touchgfx::Bitmap::RGB565; + DMA2D_reference->addToQueue(blitOp); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, MCU_HEIGHT_PIXELS | (MCU_WIDTH_PIXELS << DMA2D_NLR_PL_Pos)); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(MCU_Cropping_Buffer)); + + /* DMA2D OOR register configuration */ + WRITE_REG(DMA2D->OOR, 0); + + /* DMA2D FGOR register configuration */ + WRITE_REG(DMA2D->FGOR, 0); + + /* DMA2D FGPFCCR register configuration */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_YCBCR | (DMA2D_CSS_420 << DMA2D_FGPFCCR_CSS_Pos) | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (0xFFU << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(job.DataBuffer + srcOffset)); + + /* Configure DMA2D contol register */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); +} + +/** + * @brief External DMA2D job complete callback + * @param job: External job reference + * @retval None + */ +void DMA2D_ExternalJobCompleted(JPEG_Data_BufferTypeDef& job) +{ + /* Mark job done if all MCUs are drawn */ + if (job.MCU_drawn == JPEG_ConvertorParams.MCU_pr_job) + { + job.State = JPEG_BUFFER_EMPTY; + job.DataBufferSize = 0; + job.DoCropping = false; + job.FirstJob = false; + + JPEG_OUT_Read_BufferIndex++; + if (JPEG_OUT_Read_BufferIndex >= NB_OUTPUT_DATA_BUFFERS) + { + JPEG_OUT_Read_BufferIndex = 0; + } + + /* Check if last line */ + if (job.LastJob) + { + DMA2D_CopyBufferEnd = 1; + } + + /* Signal decoder thread to wake up and continue decoding */ + SEM_POST(semDecodingDone); + } +} diff --git a/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.hpp b/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.hpp new file mode 100644 index 0000000..e8c889f --- /dev/null +++ b/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.hpp @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * File Name : HardwareMJPEGDecoder.hpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#ifndef TOUCHGFX_HARDWAREMJPEGDECODER_HPP +#define TOUCHGFX_HARDWAREMJPEGDECODER_HPP + +#include +#include + +#include "cmsis_os2.h" +#if defined(osCMSIS) && (osCMSIS < 0x20000) +#define MUTEX_CREATE() osMutexCreate(0) +#define MUTEX_LOCK(m) osMutexWait(m, osWaitForever) +#define MUTEX_TYPE osMutexId +#define MUTEX_UNLOCK(m) osMutexRelease(m) +#define SEM_CREATE() osSemaphoreCreate(0, 1) +#define SEM_POST(s) osSemaphoreRelease(s) +#define SEM_TYPE osSemaphoreId +#define SEM_WAIT(s) osSemaphoreWait(s, osWaitForever) +#else +#define MUTEX_CREATE() osMutexNew(0) +#define MUTEX_LOCK(m) osMutexAcquire(m, osWaitForever) +#define MUTEX_TYPE osMutexId_t +#define MUTEX_UNLOCK(m) osMutexRelease(m) +#define SEM_CREATE() osSemaphoreNew(1, 0, 0) +#define SEM_POST(s) osSemaphoreRelease(s) +#define SEM_TYPE osSemaphoreId_t +#define SEM_WAIT(s) osSemaphoreAcquire(s, osWaitForever) +#endif + +class HardwareMJPEGDecoder : public MJPEGDecoder +{ +public: + HardwareMJPEGDecoder(); + + //Set video data for the decoder + virtual void setVideoData(const uint8_t* movie, const uint32_t length); + virtual void setVideoData(touchgfx::VideoDataReader& reader); + virtual bool hasVideo(); + //Increment position to next frame and decode + virtual bool decodeNextFrame(uint8_t* frameBuffer, uint16_t width, uint16_t height, uint32_t framebuffer_width); + //Increment position to next frame and decode + virtual bool gotoNextFrame(); + //Decode part of the current frame + virtual bool decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebuffer_width); + virtual bool decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height); + virtual void gotoFrame(uint32_t frameno); + virtual uint32_t getCurrentFrameNumber() const + { + return frameNumber; + } + virtual uint32_t getNumberOfFrames(); + virtual void setRepeatVideo(bool repeat); + virtual void getVideoInfo(touchgfx::VideoInformation* data); + + void setAVIFileBuffer(uint8_t* buffer, uint32_t size) + { + aviBuffer = buffer, aviBufferLength = size; + } + + virtual AVIErrors getLastError() + { + return lastError; + } + void addDMA(touchgfx::DMA_Interface& dma) + { + this->dma = &dma; + } +private: + void readVideoHeader(); + void decodeMJPEGFrame(const uint8_t* const mjpgdata, const uint32_t length, uint8_t* buffer, uint16_t width, uint16_t height, uint32_t stride); + int compare(const uint32_t offset, const char* str, uint32_t num); + uint32_t getU32(const uint32_t offset); + uint32_t getU16(const uint32_t offset); + const uint8_t* readData(uint32_t offset, uint32_t length); + + touchgfx::VideoInformation videoInfo; + uint32_t frameNumber; + uint32_t currentMovieOffset; + uint32_t indexOffset; + uint32_t firstFrameOffset; + uint32_t lastFrameEnd; + uint32_t movieLength; + const uint8_t* movieData; + touchgfx::VideoDataReader* reader; + uint8_t* aviBuffer; + uint32_t aviBufferLength; + uint32_t aviBufferStartOffset; + AVIErrors lastError; + touchgfx::DMA_Interface* dma; +}; + +#endif // TOUCHGFX_HARDWAREMJPEGDECODER_HPP diff --git a/Appli/TouchGFX/target/generated/MJPEGDecoder.hpp b/Appli/TouchGFX/target/generated/MJPEGDecoder.hpp new file mode 100644 index 0000000..681cc59 --- /dev/null +++ b/Appli/TouchGFX/target/generated/MJPEGDecoder.hpp @@ -0,0 +1,89 @@ +/** + ****************************************************************************** + * File Name : MJPEGDecoder.hpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#ifndef TOUCHGFX_MJPEGDECODER_HPP +#define TOUCHGFX_MJPEGDECODER_HPP + +#include +#include + +class MJPEGDecoder +{ +public: + virtual ~MJPEGDecoder() + { + } + + //Set video data for the decoder + virtual void setVideoData(const uint8_t* movie, const uint32_t length) = 0; + + //Set video data for the decoder + virtual void setVideoData(touchgfx::VideoDataReader& reader) = 0; + + /** + * Check if MJPEGDecoder has a video. + * + * @return Returns true if the MJPEGDecoder has a video. + */ + virtual bool hasVideo() = 0; + + //Increment position to next frame and decode and convert to RGB + virtual bool decodeNextFrame(uint8_t* buffer, uint16_t width, uint16_t height, uint32_t stride) = 0; + + //Increment position to next frame and decode. Used with decodeFrame. + virtual bool gotoNextFrame() = 0; + + //Decode part of the current frame, framebuffer is locked, area is drawn relative to frameBuffer + virtual bool decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebufferStride) = 0; + + //Decode thumbnail, assumes buffer stride is width + virtual bool decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height) = 0; + + //Set current frame number + virtual void gotoFrame(uint32_t frameno) = 0; + + //Get current frame number + virtual uint32_t getCurrentFrameNumber() const = 0; + + //Get number of frames in video + virtual uint32_t getNumberOfFrames() = 0; + + //Read video information + virtual void getVideoInfo(touchgfx::VideoInformation* data) = 0; + + enum AVIErrors + { + AVI_NO_ERROR, + AVI_NO_BUFFERS, + AVI_NO_FILE, + AVI_ERROR_NOT_RIFF, + AVI_ERROR_AVI_HEADER_NOT_FOUND, + AVI_ERROR_AVI_LIST_NOT_FOUND, + AVI_ERROR_AVI_HDRL_NOT_FOUND, + AVI_ERROR_AVI_AVIH_NOT_FOUND, + AVI_ERROR_AVI_HEADER_TO_SHORT, //not full header provided + AVI_ERROR_FILE_BUFFER_TO_SMALL, + AVI_ERROR_MOVI_NOT_FOUND, + AVI_ERROR_IDX1_NOT_FOUND, + AVI_ERROR_FRAMENO_TO_HIGH, + AVI_ERROR_EOF_REACHED + }; + + AVIErrors virtual getLastError() = 0; +}; + +#endif // TOUCHGFX_MJPEGDECODER_HPP diff --git a/Appli/TouchGFX/target/generated/OSWrappers.cpp b/Appli/TouchGFX/target/generated/OSWrappers.cpp new file mode 100644 index 0000000..8f36eeb --- /dev/null +++ b/Appli/TouchGFX/target/generated/OSWrappers.cpp @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * File Name : OSWrappers.cpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include +#include + +#include +#include + +static osSemaphoreId_t frame_buffer_sem = NULL; +static osMessageQueueId_t vsync_queue = NULL; + +// Just a dummy value to insert in the VSYNC queue. +static uint32_t dummy = 0x5a; + +using namespace touchgfx; + +/* + * Initialize frame buffer semaphore and queue/mutex for VSYNC signal. + */ +void OSWrappers::initialize() +{ + // Create a queue of length 1 + frame_buffer_sem = osSemaphoreNew(1, 1, NULL); // Binary semaphore + assert((frame_buffer_sem != NULL) && "Creation of framebuffer semaphore failed"); + + // Create a queue of length 1 + vsync_queue = osMessageQueueNew(1, 4, NULL); + assert((vsync_queue != NULL) && "Creation of vsync message queue failed"); +} + +/* + * Take the frame buffer semaphore. Blocks until semaphore is available. + */ +void OSWrappers::takeFrameBufferSemaphore() +{ + osSemaphoreAcquire(frame_buffer_sem, osWaitForever); +} + +/* + * Release the frame buffer semaphore. + */ +void OSWrappers::giveFrameBufferSemaphore() +{ + osSemaphoreRelease(frame_buffer_sem); +} + +/* + * Attempt to obtain the frame buffer semaphore. If semaphore is not available, do + * nothing. + * + * Note must return immediately! This function does not care who has the taken the semaphore, + * it only serves to make sure that the semaphore is taken by someone. + */ +void OSWrappers::tryTakeFrameBufferSemaphore() +{ + osSemaphoreAcquire(frame_buffer_sem, 0); +} + +/* + * Release the frame buffer semaphore in a way that is safe in interrupt context. Called + * from ISR. + * + * Release the frame buffer semaphore in a way that is safe in interrupt context. + * Called from ISR. + */ +void OSWrappers::giveFrameBufferSemaphoreFromISR() +{ + osSemaphoreRelease(frame_buffer_sem); +} + +/* + * Signal that a VSYNC has occurred. Should make the vsync queue/mutex available. + * + * Note This function is called from an ISR, and should (depending on OS) trigger a + * scheduling. + */ +void OSWrappers::signalVSync() +{ + osMessageQueuePut(vsync_queue, &dummy, 0, 0); +} + +/* + * Signal that the rendering of the frame has completed. Used by + * some systems to avoid using any previous vsync. + */ +void OSWrappers::signalRenderingDone() +{ + // Empty implementation for CMSIS V2 +} + +/* + * This function blocks until a VSYNC occurs. + * + * Note This function must first clear the mutex/queue and then wait for the next one to + * occur. + */ +void OSWrappers::waitForVSync() +{ + uint32_t dummyGet; + // First make sure the queue is empty, by trying to remove an element with 0 timeout. + osMessageQueueGet(vsync_queue, &dummyGet, 0, 0); + + // Then, wait for next VSYNC to occur. + osMessageQueueGet(vsync_queue, &dummyGet, 0, osWaitForever); +} + +/* + * A function that causes executing task to sleep for a number of milliseconds. + * + * A function that causes executing task to sleep for a number of milliseconds. + * This function is OPTIONAL. It is only used by the TouchGFX in the case of + * a specific frame refresh strategy (REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL). + * Due to backwards compatibility, in order for this function to be useable by the HAL + * the function must be explicitly registered: + * hal.registerTaskDelayFunction(&OSWrappers::taskDelay) + * + * see HAL::setFrameRefreshStrategy(FrameRefreshStrategy s) + * see HAL::registerTaskDelayFunction(void (*delayF)(uint16_t)) + */ +void OSWrappers::taskDelay(uint16_t ms) +{ + osDelay(static_cast(ms)); +} + +/** + * A function that causes the executing task to yield control to + * another thread. This function is used by the framework when it + * is necessary to wait a little before continuing (e.g. drawing). + * + * The implementation should typically request the operating + * system to change to another task of similar priority. When + * running without an operating system, the implementation can run + * a very short task and return. + */ +void OSWrappers::taskYield() +{ + osThreadYield(); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/STM32DMA.cpp b/Appli/TouchGFX/target/generated/STM32DMA.cpp new file mode 100644 index 0000000..f7b4803 --- /dev/null +++ b/Appli/TouchGFX/target/generated/STM32DMA.cpp @@ -0,0 +1,1030 @@ + +/** + ****************************************************************************** + * File Name : STM32DMA.cpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include "stm32h7rsxx_hal.h" +#include "stm32h7rsxx_hal_dma2d.h" +#include +#include +#include +#include + +/* Makes touchgfx specific types and variables visible to this file */ +using namespace touchgfx; + +typedef struct +{ + const uint16_t format; + const uint16_t size; + const uint32_t* const data; +} clutData_t; + +extern "C" DMA2D_HandleTypeDef hdma2d; + +extern "C" { + static void DMA2D_XferCpltCallback(DMA2D_HandleTypeDef* handle) + { + (void)handle; // Unused argument + HAL::getInstance()->signalDMAInterrupt(); + } + + static void DMA2D_XferErrorCallback(DMA2D_HandleTypeDef* handle) + { + (void)handle; // Unused argument + while (1) + { + + } + } +} + +STM32DMA::STM32DMA() + : DMA_Interface(dma_queue), dma_queue(queue_storage, sizeof(queue_storage) / sizeof(queue_storage[0])), started_by_external_job(false) +{ + +} + +STM32DMA::~STM32DMA() +{ + /* Disable DMA2D global Interrupt */ + NVIC_DisableIRQ(DMA2D_IRQn); +} + +void STM32DMA::initialize() +{ + /* Ensure DMA2D Clock is enabled */ + __HAL_RCC_DMA2D_CLK_ENABLE(); + __HAL_RCC_DMA2D_FORCE_RESET(); + __HAL_RCC_DMA2D_RELEASE_RESET(); + + /* Add transfer error callback function */ + hdma2d.XferErrorCallback = DMA2D_XferErrorCallback; + + /* Add transfer complete callback function */ + hdma2d.XferCpltCallback = DMA2D_XferCpltCallback; + + /* Enable DMA2D global Interrupt */ + NVIC_EnableIRQ(DMA2D_IRQn); +} + +inline uint32_t STM32DMA::getChromARTInputFormat(Bitmap::BitmapFormat format) +{ + // Default color mode set to ARGB8888 + uint32_t dma2dColorMode = DMA2D_INPUT_ARGB8888; + + switch (format) + { + case Bitmap::ARGB8888: /* DMA2D input mode set to 32bit ARGB */ + dma2dColorMode = DMA2D_INPUT_ARGB8888; + break; + case Bitmap::RGB888: /* DMA2D input mode set to 24bit RGB */ + dma2dColorMode = DMA2D_INPUT_RGB888; + break; + case Bitmap::RGB565: /* DMA2D input mode set to 16bit RGB */ + dma2dColorMode = DMA2D_INPUT_RGB565; + break; + case Bitmap::ARGB2222: /* Fall through */ + case Bitmap::ABGR2222: /* Fall through */ + case Bitmap::RGBA2222: /* Fall through */ + case Bitmap::BGRA2222: /* Fall through */ + case Bitmap::L8: /* DMA2D input mode set to 8bit Color Look up table*/ + dma2dColorMode = DMA2D_INPUT_L8; + break; + case Bitmap::BW: /* Fall through */ + case Bitmap::BW_RLE: /* Fall through */ + case Bitmap::GRAY4: /* Fall through */ + case Bitmap::GRAY2: /* Fall through */ + default: /* Unsupported input format for DMA2D */ + assert(0 && "Unsupported Format!"); + break; + } + + return dma2dColorMode; +} + +inline uint32_t STM32DMA::getChromARTOutputFormat(Bitmap::BitmapFormat format) +{ + // Default color mode set to ARGB8888 + uint32_t dma2dColorMode = DMA2D_OUTPUT_ARGB8888; + + switch (format) + { + case Bitmap::ARGB8888: /* DMA2D output mode set to 32bit ARGB */ + dma2dColorMode = DMA2D_OUTPUT_ARGB8888; + break; + case Bitmap::RGB888: /* Fall through */ + case Bitmap::ARGB2222: /* Fall through */ + case Bitmap::ABGR2222: /* Fall through */ + case Bitmap::RGBA2222: /* Fall through */ + case Bitmap::BGRA2222: /* DMA2D output mode set to 24bit RGB */ + dma2dColorMode = DMA2D_OUTPUT_RGB888; + break; + case Bitmap::RGB565: /* DMA2D output mode set to 16bit RGB */ + dma2dColorMode = DMA2D_OUTPUT_RGB565; + break; + case Bitmap::L8: /* Fall through */ + case Bitmap::BW: /* Fall through */ + case Bitmap::BW_RLE: /* Fall through */ + case Bitmap::GRAY4: /* Fall through */ + case Bitmap::GRAY2: /* Fall through */ + default: /* Unsupported output format for DMA2D */ + assert(0 && "Unsupported Format!"); + break; + } + + return dma2dColorMode; +} + +BlitOperations STM32DMA::getBlitCaps() +{ + return static_cast(BLIT_OP_FILL + | BLIT_OP_FILL_WITH_ALPHA + | BLIT_OP_COPY + | BLIT_OP_COPY_L8 + | BLIT_OP_COPY_WITH_ALPHA + | BLIT_OP_COPY_ARGB8888 + | BLIT_OP_COPY_ARGB8888_WITH_ALPHA + | BLIT_OP_COPY_A4 + | BLIT_OP_COPY_A8); +} + +/* + * void STM32DMA::setupDataCopy(const BlitOp& blitOp) handles blit operation of + * BLIT_OP_COPY + * BLIT_OP_COPY_L8 + * BLIT_OP_COPY_WITH_ALPHA + * BLIT_OP_COPY_ARGB8888 + * BLIT_OP_COPY_ARGB8888_WITH_ALPHA + * BLIT_OP_COPY_A4 + * BLIT_OP_COPY_A8 + */ +void STM32DMA::setupDataCopy(const BlitOp& blitOp) +{ + uint32_t dma2dForegroundColorMode = getChromARTInputFormat(static_cast(blitOp.srcFormat)); + uint32_t dma2dBackgroundColorMode = getChromARTInputFormat(static_cast(blitOp.dstFormat)); + uint32_t dma2dOutputColorMode = getChromARTOutputFormat(static_cast(blitOp.dstFormat)); + + /* DMA2D OOR register configuration */ + WRITE_REG(DMA2D->OOR, blitOp.dstLoopStride - blitOp.nSteps); + + /* DMA2D BGOR register configuration */ + WRITE_REG(DMA2D->BGOR, blitOp.dstLoopStride - blitOp.nSteps); + + /* DMA2D FGOR register configuration */ + WRITE_REG(DMA2D->FGOR, blitOp.srcLoopStride - blitOp.nSteps); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, dma2dOutputColorMode); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (blitOp.nLoops | (blitOp.nSteps << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(blitOp.pDst)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(blitOp.pSrc)); + + switch (blitOp.operation) + { + case BLIT_OP_COPY_A4: + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A4 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (blitOp.alpha << 24)); + + /* set DMA2D foreground color */ + WRITE_REG(DMA2D->FGCOLR, blitOp.color); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(blitOp.pDst)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + break; + case BLIT_OP_COPY_A8: + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A8 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (blitOp.alpha << 24)); + + /* set DMA2D foreground color */ + WRITE_REG(DMA2D->FGCOLR, blitOp.color); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(blitOp.pDst)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + break; + case BLIT_OP_COPY_WITH_ALPHA: + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (blitOp.alpha << 24)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(blitOp.pDst)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + break; + case BLIT_OP_COPY_L8: + { + bool blend = true; + const clutData_t* const palette = reinterpret_cast(blitOp.pClut); + + /* Write foreground CLUT memory address */ + WRITE_REG(DMA2D->FGCMAR, reinterpret_cast(&palette->data)); + + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (blitOp.alpha << 24)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(blitOp.pDst)); + + /* Configure CLUT */ + switch ((Bitmap::ClutFormat)palette->format) + { + case Bitmap::CLUT_FORMAT_L8_ARGB8888: + /* Write foreground CLUT size and CLUT color mode */ + MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((palette->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_ARGB8888 << DMA2D_FGPFCCR_CCM_Pos))); + break; + case Bitmap::CLUT_FORMAT_L8_RGB888: + if (blitOp.alpha == 255) + { + blend = false; + } + MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((palette->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_RGB888 << DMA2D_FGPFCCR_CCM_Pos))); + break; + + case Bitmap::CLUT_FORMAT_L8_RGB565: + default: + assert(0 && "Unsupported format"); + break; + } + + /* Enable the CLUT loading for the foreground */ + SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START); + + while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U) + { + } + DMA2D->IFCR = (DMA2D_FLAG_CTC); + + /* Set DMA2D mode */ + if (blend) + { + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + } + else + { + WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + } + } + break; + case BLIT_OP_COPY_ARGB8888: + case BLIT_OP_COPY_ARGB8888_WITH_ALPHA: + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (blitOp.alpha << 24)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(blitOp.pDst)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + break; + default: /* BLIT_OP_COPY */ + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (blitOp.alpha << 24)); + + /* Perform pixel-format-conversion (PFC) If Bitmap format is not same format as framebuffer format */ + if (blitOp.srcFormat != blitOp.dstFormat) + { + /* Start DMA2D : PFC Mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + } + else + { + /* Start DMA2D : M2M Mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE); + } + break; + } +} + +/* + * void STM32DMA::setupDataFill(const BlitOp& blitOp) handles blit operation of + * BLIT_OP_FILL + * BLIT_OP_FILL_WITH_ALPHA + */ +void STM32DMA::setupDataFill(const BlitOp& blitOp) +{ + uint32_t dma2dOutputColorMode = getChromARTOutputFormat(static_cast(blitOp.dstFormat)); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, dma2dOutputColorMode); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (blitOp.nLoops | (blitOp.nSteps << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(blitOp.pDst)); + + /* DMA2D OOR register configuration */ + WRITE_REG(DMA2D->OOR, blitOp.dstLoopStride - blitOp.nSteps); + + if (blitOp.operation == BLIT_OP_FILL_WITH_ALPHA) + { + /* DMA2D BGOR register configuration */ + WRITE_REG(DMA2D->BGOR, blitOp.dstLoopStride - blitOp.nSteps); + + /* DMA2D FGOR register configuration */ + WRITE_REG(DMA2D->FGOR, blitOp.dstLoopStride - blitOp.nSteps); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, dma2dOutputColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Write DMA2D FGPFCCR register */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A8 | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | ((blitOp.alpha << 24) & DMA2D_FGPFCCR_ALPHA)); + + /* DMA2D FGCOLR register configuration */ + WRITE_REG(DMA2D->FGCOLR, blitOp.color); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(blitOp.pDst)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(blitOp.pDst)); + + /* Enable the Peripheral and Enable the transfer complete interrupt */ + WRITE_REG(DMA2D->CR, (DMA2D_IT_TC | DMA2D_CR_START | DMA2D_M2M_BLEND | DMA2D_IT_CE | DMA2D_IT_TE)); + } + else + { + /* Write DMA2D FGPFCCR register */ + WRITE_REG(DMA2D->FGPFCCR, dma2dOutputColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos)); + + /* DMA2D FGOR register configuration */ + WRITE_REG(DMA2D->FGOR, 0); + + /* Set color */ + WRITE_REG(DMA2D->OCOLR, blitOp.color); + + /* Enable the Peripheral and Enable the transfer complete interrupt */ + WRITE_REG(DMA2D->CR, (DMA2D_IT_TC | DMA2D_CR_START | DMA2D_R2M | DMA2D_IT_CE | DMA2D_IT_TE)); + } +} + +namespace touchgfx +{ +namespace paint +{ +namespace +{ +const clutData_t* L8CLUT = 0; +uint32_t L8ClutLoaded = 0; +} // namespace + +void setL8Palette(const uint8_t* const data) +{ + L8CLUT = reinterpret_cast(data - offsetof(clutData_t, data)); + L8ClutLoaded = 0; +} + +/** + * @fn void tearDown(); + * + * @brief Waits until previous DMA drawing operation has finished + */ +void tearDown() +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); +} + +/** Flushes a line of pixels in the data cache if used. + * + * @brief Flushes decoded RGB pixels when rendering compressed images + */ +void flushLine(uint32_t* addr, int sizebytes) +{ + // This function is used when decompressing data to flush + // the currently decoded data in the cache to allow the DMA2D + // to blend the pixels correctly. + if (SCB->CCR & SCB_CCR_DC_Msk) + { + SCB_CleanDCache_by_Addr(addr, sizebytes); + } +} + +/** + * @fn void invalidateTextureCache(); + * + * @brief Flushes the data cache if used. + */ +void invalidateTextureCache() +{ + // This function is used when decompressing data to invalidate + // the currently decoded data in RAM to allow the GPU2D texture + // cache to render the pixels correctly. + HAL_ICACHE_Invalidate(); +} + +namespace rgb565 +{ +/** + * @fn void lineFromColor(); + * + * @brief Renders Canvas Widget chunks using DMA. + * This functions will not generate an interrupt, and will not affect the DMA queue. + */ +void lineFromColor(uint16_t* const ptr, const unsigned count, const uint32_t color, const uint8_t alpha, const uint32_t color565) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + if (alpha < 0xFF) + { + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_OUTPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Write DMA2D FGPFCCR register */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A8 | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* DMA2D FGCOLR register configuration */ + WRITE_REG(DMA2D->FGCOLR, color); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, (uint32_t)ptr); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, (uint32_t)ptr); + + /* Enable the Peripheral and Enable the transfer complete interrupt */ + WRITE_REG(DMA2D->CR, (DMA2D_CR_START | DMA2D_M2M_BLEND)); + } + else + { + /* Write DMA2D FGPFCCR register */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_OUTPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos)); + + /* Set color */ + WRITE_REG(DMA2D->OCOLR, color565); + + /* Enable the Peripheral and Enable the transfer complete interrupt */ + WRITE_REG(DMA2D->CR, (DMA2D_CR_START | DMA2D_R2M)); + } +} + +void lineFromRGB565(uint16_t* const ptr, const uint16_t* const data, const unsigned count, const uint8_t alpha) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + if (alpha < 0xFF) + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } + else + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Start DMA2D : M2M Mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M | DMA2D_CR_START); + } +} + +void lineFromARGB8888(uint16_t* const ptr, const uint32_t* const data, const unsigned count, const uint8_t alpha) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); +} + +void lineFromL8RGB888(uint16_t* const ptr, const uint8_t* const data, const unsigned count, const uint8_t alpha) +{ + /* wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Load CLUT if not already loaded */ + if (L8ClutLoaded == 0) + { + /* Write foreground CLUT memory address */ + WRITE_REG(DMA2D->FGCMAR, reinterpret_cast(&L8CLUT->data)); + + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_L8 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((L8CLUT->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_RGB888 << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Mark CLUT loaded */ + L8ClutLoaded = 1; + + /* Wait for load to finish */ + while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U); + + /* Clear CLUT Transfer Complete flag */ + DMA2D->IFCR = (DMA2D_FLAG_CTC); + } + else + { + /* Set correct alpha for these pixels */ + MODIFY_REG(DMA2D->FGPFCCR, DMA2D_BGPFCCR_ALPHA_Msk, alpha << DMA2D_FGPFCCR_ALPHA_Pos); + } + + /* Start pixel transfer in correct mode */ + if (alpha < 0xFF) + { + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } + else + { + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_CR_START); + } +} + +void lineFromL8ARGB8888(uint16_t* const ptr, const uint8_t* const data, const unsigned count, const uint8_t alpha) +{ + /* wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Load CLUT if not already loaded */ + if (L8ClutLoaded == 0) + { + /* Write foreground CLUT memory address */ + WRITE_REG(DMA2D->FGCMAR, reinterpret_cast(&L8CLUT->data)); + + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_L8 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((L8CLUT->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_ARGB8888 << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Mark CLUT loaded */ + L8ClutLoaded = 1; + + /* Wait for load to finish */ + while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U); + + /* Clear CLUT Transfer Complete flag */ + DMA2D->IFCR = (DMA2D_FLAG_CTC); + } + else + { + /* Set correct alpha for these pixels */ + MODIFY_REG(DMA2D->FGPFCCR, DMA2D_BGPFCCR_ALPHA_Msk, alpha << DMA2D_FGPFCCR_ALPHA_Pos); + } + + /* Start pixel transfer in blending mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); +} + +} // namespace rgb565 + +namespace argb8888 +{ +/** + * @fn void lineFromColor(); + * + * @brief Renders Canvas Widget chunks using DMA. + * This function will not generate an interrupt, and will not affect the DMA queue. + */ +void lineFromColor(uint32_t* const ptr, const int16_t count, const uint32_t painterColor, const uint8_t alpha) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration (set output image color format) */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_ARGB8888); + + /* Configure DMA2D data size (pixels per line (PL)) */ + WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + if (alpha < 0xFF) + { + /* Write DMA2D BGPFCCR (background control) register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_OUTPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Write DMA2D FGPFCCR (foreground control) register */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A8 | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* DMA2D FGCOLR register configuration */ + WRITE_REG(DMA2D->FGCOLR, painterColor & (DMA2D_FGCOLR_BLUE | DMA2D_FGCOLR_GREEN | DMA2D_FGCOLR_RED)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, (uint32_t)ptr); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, (uint32_t)ptr); + + /* Enable the Peripheral and Enable the transfer complete interrupt */ + WRITE_REG(DMA2D->CR, (DMA2D_CR_START | DMA2D_M2M_BLEND)); + } + else + { + /* Write DMA2D FGPFCCR register */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_OUTPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos)); + + /* Set Output Color */ + WRITE_REG(DMA2D->OCOLR, painterColor); + + /* Start DMA2D */ + WRITE_REG(DMA2D->CR, (DMA2D_CR_START | DMA2D_R2M)); + } +} + +void lineFromRGB888(uint8_t* const ptr, const uint8_t* const data, const int16_t length, const uint8_t alpha) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_ARGB8888); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (length << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + if (alpha < 0xFF) + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB888 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } + else + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos)); + + /* Start DMA2D : M2M Mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } +} + +void lineFromRGB565(uint8_t* const ptr, const uint16_t* const data, const int16_t length, const uint8_t alpha) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_ARGB8888); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (length << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + if (alpha < 0xFF) + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } + else + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos)); + + /* Start DMA2D : M2M Mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } +} + +void lineFromARGB8888(uint8_t* const ptr, const uint32_t* const data, const int16_t length, const uint8_t alpha) +{ + /* Wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* Clear transfer flags */ + WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_ARGB8888); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (length << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + if (alpha < 0xFF) + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + } + else + { + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos)); + } + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Start DMA2D */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); +} + +void lineFromL8RGB888(uint8_t* const ptr, const uint8_t* const data, const int16_t length, const uint8_t alpha) +{ + /* wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_ARGB8888); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (length << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Load CLUT if not already loaded */ + if (L8ClutLoaded == 0) + { + /* Write foreground CLUT memory address */ + WRITE_REG(DMA2D->FGCMAR, reinterpret_cast(&L8CLUT->data)); + + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_L8 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((L8CLUT->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_RGB888 << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Mark CLUT loaded */ + L8ClutLoaded = 1; + + /* Wait for load to finish */ + while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U); + + /* Clear CLUT Transfer Complete flag */ + DMA2D->IFCR = (DMA2D_FLAG_CTC); + } + else + { + /* Set correct alpha for these pixels */ + MODIFY_REG(DMA2D->FGPFCCR, DMA2D_BGPFCCR_ALPHA_Msk, alpha << DMA2D_FGPFCCR_ALPHA_Pos); + } + + /* Start pixel transfer in correct mode */ + if (alpha < 0xFF) + { + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); + } + else + { + /* Set DMA2D mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_CR_START); + } +} + +void lineFromL8ARGB8888(uint8_t* const ptr, const uint8_t* const data, const int16_t length, const uint8_t alpha) +{ + /* wait for DMA2D to finish last run */ + while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U); + + /* DMA2D OPFCCR register configuration */ + WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_ARGB8888); + + /* Configure DMA2D data size */ + WRITE_REG(DMA2D->NLR, (1 | (length << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(DMA2D->OMAR, reinterpret_cast(ptr)); + + /* Configure DMA2D source address */ + WRITE_REG(DMA2D->FGMAR, reinterpret_cast(data)); + + /* Configure DMA2D Stream source2 address */ + WRITE_REG(DMA2D->BGMAR, reinterpret_cast(ptr)); + + /* Load CLUT if not already loaded */ + if (L8ClutLoaded == 0) + { + /* Write foreground CLUT memory address */ + WRITE_REG(DMA2D->FGCMAR, reinterpret_cast(&L8CLUT->data)); + + /* Set DMA2D color mode and alpha mode */ + WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_L8 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << DMA2D_FGPFCCR_ALPHA_Pos)); + + MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((L8CLUT->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_ARGB8888 << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START); + + /* Write DMA2D BGPFCCR register */ + WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos)); + + /* Mark CLUT loaded */ + L8ClutLoaded = 1; + + /* Wait for load to finish */ + while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U); + + /* Clear CLUT Transfer Complete flag */ + DMA2D->IFCR = (DMA2D_FLAG_CTC); + } + else + { + /* Set correct alpha for these pixels */ + MODIFY_REG(DMA2D->FGPFCCR, DMA2D_BGPFCCR_ALPHA_Msk, alpha << DMA2D_FGPFCCR_ALPHA_Pos); + } + + /* Start pixel transfer in blending mode */ + WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START); +} + +} // namespace argb8888 +} // namespace paint +} // namespace touchgfx +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/STM32DMA.hpp b/Appli/TouchGFX/target/generated/STM32DMA.hpp new file mode 100644 index 0000000..4677d01 --- /dev/null +++ b/Appli/TouchGFX/target/generated/STM32DMA.hpp @@ -0,0 +1,263 @@ +/** + ****************************************************************************** + * File Name : STM32DMA.hpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef STM32DMA_HPP +#define STM32DMA_HPP + +#include +#include + +#define JPEG_BUFFER_EMPTY 0 +#define JPEG_BUFFER_FULL 1 +#define NB_OUTPUT_DATA_BUFFERS 2 + +extern volatile uint32_t JPEG_OUT_Read_BufferIndex; +extern volatile uint32_t DMA2D_CopyBufferEnd; + +typedef struct +{ + uint8_t State; + uint8_t* DataBuffer; + uint32_t DataBufferSize; + uint32_t MCU_index; + uint8_t* OutputBuffer; + bool FirstJob; + bool LastJob; + uint32_t MCU_drawn; + bool DoCropping; +} JPEG_Data_BufferTypeDef; + +extern JPEG_Data_BufferTypeDef Jpeg_OUT_BufferTab[NB_OUTPUT_DATA_BUFFERS]; + +extern "C" void DMA2D_CropBuffer(JPEG_Data_BufferTypeDef& job); +extern "C" void DMA2D_CopyBuffer(JPEG_Data_BufferTypeDef& job); +extern "C" void DMA2D_ExternalJobCompleted(JPEG_Data_BufferTypeDef& job); + +/** + * @class STM32DMA + * + * @brief This class specializes DMA_Interface for the STM32 processors. + * + * @sa touchgfx::DMA_Interface + */ +class STM32DMA : public touchgfx::DMA_Interface +{ + /** + * @typedef touchgfx::DMA_Interface Base + * + * @brief Defines an alias representing the base. + * + Defines an alias representing the base. + */ + typedef touchgfx::DMA_Interface Base; + +public: + /** + * @fn STM32DMA::STM32DMA(); + * + * @brief Default constructor. + * + * Default constructor. + */ + STM32DMA(); + + /** + * @fn STM32DMA::~STM32DMA(); + * + * @brief Destructor. + * + * Destructor. + */ + virtual ~STM32DMA(); + + /** + * @fn DMAType touchgfx::STM32DMA::getDMAType() + * + * @brief Function for obtaining the DMA type of the concrete DMA_Interface implementation. + * + * Function for obtaining the DMA type of the concrete DMA_Interface implementation. + * As default, will return DMA_TYPE_CHROMART type value. + * + * @return a DMAType value of the concrete DMA_Interface implementation. + */ + virtual touchgfx::DMAType getDMAType(void) + { + return touchgfx::DMA_TYPE_CHROMART; + } + + /** + * @fn touchgfx::BlitOperations STM32DMA::getBlitCaps(); + * + * @brief Gets the blit capabilities. + * + * Gets the blit capabilities. + * + * This DMA supports a range of blit caps: BLIT_OP_COPY, BLIT_OP_COPY_ARGB8888, + * BLIT_OP_COPY_ARGB8888_WITH_ALPHA, BLIT_OP_COPY_A4, BLIT_OP_COPY_A8. + * + * + * @return Currently supported blitcaps. + */ + virtual touchgfx::BlitOperations getBlitCaps(); + + /** + * @fn void STM32DMA::initialize(); + * + * @brief Perform hardware specific initialization. + * + * Perform hardware specific initialization. + */ + virtual void initialize(); + + /** + * @fn void STM32DMA::signalDMAInterrupt() + * + * @brief Raises a DMA interrupt signal. + * + * Raises a DMA interrupt signal. + */ + virtual void signalDMAInterrupt() + { + if (!started_by_external_job) + { + executeCompleted(); + + /* Start new external job if next buffer is full */ + if (Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].State == JPEG_BUFFER_FULL && !DMA2D_CopyBufferEnd && !isRunning) + { + started_by_external_job = true; + externalJobExecute(); + } + } + else + { + externalJobCompleted(); + + /* Prioritize BlitOps if there are any pending */ + if (!queue.isEmpty() && isAllowed) + { + started_by_external_job = false; + execute(); + } + } + } + + virtual void start() + { + if (!queue.isEmpty() && isAllowed && !isRunning) + { + started_by_external_job = false; + execute(); + } + else if ((Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].State == JPEG_BUFFER_FULL) && !isRunning) + { + started_by_external_job = true; + externalJobExecute(); + } + } + +protected: + /** + * @fn virtual void STM32DMA::setupDataCopy(const touchgfx::BlitOp& blitOp); + * + * @brief Configures the DMA for copying data to the frame buffer. + * + * Configures the DMA for copying data to the frame buffer. + * + * @param blitOp Details on the copy to perform. + */ + virtual void setupDataCopy(const touchgfx::BlitOp& blitOp); + + /** + * @fn virtual void STM32DMA::setupDataFill(const touchgfx::BlitOp& blitOp); + * + * @brief Configures the DMA for "filling" the frame-buffer with a single color. + * + * Configures the DMA for "filling" the frame-buffer with a single color. + * + * @param blitOp Details on the "fill" to perform. + */ + virtual void setupDataFill(const touchgfx::BlitOp& blitOp); + + /** + * @fn void STM32DMA::externalJobCompleted(); + * + * @brief Handle DMA2D when an external job has been executed + * + * @param None + */ + void externalJobCompleted() + { + if (isRunning) + { + isRunning = false; + DMA2D_ExternalJobCompleted(Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex]); + } + } + + /** + * @fn void STM32DMA::externalJobExecute(); + * + * @brief Executes an external DMA2D job + * + * @param None + */ + void externalJobExecute() + { + isRunning = true; + if (Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].DoCropping) + { + DMA2D_CropBuffer(Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex]); + } + else + { + DMA2D_CopyBuffer(Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex]); + } + } + +private: + touchgfx::LockFreeDMA_Queue dma_queue; + touchgfx::BlitOp queue_storage[96]; + bool started_by_external_job; + + /** + * @fn void STM32DMA::getChromARTInputFormat() + * + * @brief Convert Bitmap format to ChromART Input format. + * + * @param format Bitmap format. + * + * @return ChromART Input format. + */ + + inline uint32_t getChromARTInputFormat(touchgfx::Bitmap::BitmapFormat format); + + /** + * @fn void STM32DMA::getChromARTOutputFormat() + * + * @brief Convert Bitmap format to ChromART Output format. + * + * @param format Bitmap format. + * + * @return ChromART Output format. + */ + inline uint32_t getChromARTOutputFormat(touchgfx::Bitmap::BitmapFormat format); +}; + +#endif // STM32DMA_HPP +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp b/Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp new file mode 100644 index 0000000..0cceae6 --- /dev/null +++ b/Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * File Name : TouchGFXConfiguration.cpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +extern "C" +{ +#include +#include +} +#include +#include +#include +#include + +extern "C" void touchgfx_init(); +extern "C" void touchgfx_taskEntry(); +extern "C" void touchgfx_components_init(); + +static STM32TouchController tc; +static STM32DMA dma; +static LCDGPU2D_AXI display; +static VectorFontRendererImpl vectorFontRenderer; + +static ApplicationFontProvider fontProvider; +static Texts texts; +static TouchGFXHAL hal(dma, display, tc, 800, 480); + +void touchgfx_init() +{ + Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize()); + TypedText::registerTexts(&texts); + Texts::setLanguage(0); + + display.setFrameBufferFormat(Bitmap::RGB565); + + display.setVectorFontRenderer(&vectorFontRenderer); + + FontManager::setFontProvider(&fontProvider); + + FrontendHeap& heap = FrontendHeap::getInstance(); + /* + * we need to obtain the reference above to initialize the frontend heap. + */ + (void)heap; + + /* + * Initialize TouchGFX + */ + hal.initialize(); +} + +void touchgfx_components_init() +{ + nema_init(); + nema_reg_write(0xFFC, 0x7E); /* Enable bus error interrupts */ + nema_vg_init_stencil_pool(800, 480, 1); + nema_vg_handle_large_coords(1, 1); + nema_ext_hold_enable(2); + nema_ext_hold_irq_enable(2); + nema_ext_hold_enable(3); + nema_ext_hold_irq_enable(3); +} + +void touchgfx_taskEntry() +{ + /* + * Main event loop. Will wait for VSYNC signal, and then process next frame. Call + * this function from your GUI task. + * + * Note This function never returns + */ + hal.taskEntry(); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp b/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp new file mode 100644 index 0000000..d53c924 --- /dev/null +++ b/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp @@ -0,0 +1,222 @@ +/** + ****************************************************************************** + * File Name : TouchGFXGeneratedHAL.cpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +HardwareMJPEGDecoder mjpegdecoder1; + +namespace +{ +DirectFrameBufferVideoController<1, Bitmap::RGB565> videoController; +} + +//Singleton Factory +VideoController& VideoController::getInstance() +{ + return videoController; +} + +namespace touchgfx +{ +VectorRenderer* VectorRenderer::getInstance() +{ + static GPU2DVectorRenderer renderer; + + return &renderer; +} +} // namespace touchgfx + +#include "stm32h7rsxx.h" +#include "stm32h7rsxx_hal_ltdc.h" + +using namespace touchgfx; + +namespace +{ +// Use the section "TouchGFX_Framebuffer" in the linker script to specify the placement of the buffer +LOCATION_PRAGMA_NOLOAD("TouchGFX_Framebuffer") +uint32_t frameBuf[(800 * 480 * 2 + 3) / 4 * 2] LOCATION_ATTRIBUTE_NOLOAD("TouchGFX_Framebuffer"); +static uint16_t lcd_int_active_line; +static uint16_t lcd_int_porch_line; +} + +void TouchGFXGeneratedHAL::initialize() +{ + HALGPU2D::initialize(16384); + registerEventListener(*(Application::getInstance())); + setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf) / (sizeof(uint32_t) * 2)), (void*)0); + + /* + * Add DMA2D to hardware decoder + */ + mjpegdecoder1.addDMA(dma); + + /* + * Add hardware decoder to video controller + */ + videoController.addDecoder(mjpegdecoder1, 0); +} + +void TouchGFXGeneratedHAL::configureInterrupts() +{ + NVIC_SetPriority(DMA2D_IRQn, 9); + NVIC_SetPriority(LTDC_IRQn, 9); + NVIC_SetPriority(GPU2D_IRQn, 9); +} + +void TouchGFXGeneratedHAL::enableInterrupts() +{ + NVIC_EnableIRQ(DMA2D_IRQn); + NVIC_EnableIRQ(LTDC_IRQn); + NVIC_EnableIRQ(GPU2D_IRQn); +} + +void TouchGFXGeneratedHAL::disableInterrupts() +{ + NVIC_DisableIRQ(DMA2D_IRQn); + NVIC_DisableIRQ(LTDC_IRQn); + NVIC_DisableIRQ(GPU2D_IRQn); +} + +void TouchGFXGeneratedHAL::enableLCDControllerInterrupt() +{ + lcd_int_active_line = (LTDC->BPCR & LTDC_BPCR_AVBP_Msk) - 1; + lcd_int_porch_line = (LTDC->AWCR & LTDC_AWCR_AAH_Msk) - 1; + + /* Sets the Line Interrupt position */ + LTDC->LIPCR = lcd_int_active_line; + /* Line Interrupt Enable */ + LTDC->IER |= LTDC_IER_LIE; +} + +bool TouchGFXGeneratedHAL::beginFrame() +{ + return HALGPU2D::beginFrame(); +} + +void TouchGFXGeneratedHAL::endFrame() +{ + HALGPU2D::endFrame(); +} + +void TouchGFXGeneratedHAL::submitGPU2D() +{ + HALGPU2D::submitExecBuffer(); +} + +uint16_t* TouchGFXGeneratedHAL::getTFTFrameBuffer() const +{ + return (uint16_t*)LTDC_Layer1->CFBAR; +} + +void TouchGFXGeneratedHAL::setTFTFrameBuffer(uint16_t* adr) +{ + LTDC_Layer1->CFBAR = (uint32_t)adr; + + /* Reload immediate */ + LTDC->SRCR = (uint32_t)LTDC_SRCR_IMR; +} + +void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect) +{ + HALGPU2D::flushFrameBuffer(rect); +} + +bool TouchGFXGeneratedHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes) +{ + return HALGPU2D::blockCopy(dest, src, numBytes); +} + +void TouchGFXGeneratedHAL::InvalidateCache() +{ + // Because DMA2D access main memory directly, the DCache must be invalidated + // becuase it could hold a wrong image of the framebuffer. That's done + // using the function SCB_CleanInvalidateDCache(). Remember to enable + // "CPU Cache" in the "System Core" settings for "Cortex M7" in CubeMX + // in order for this function call to work. + if (SCB->CCR & SCB_CCR_DC_Msk) + { + SCB_CleanInvalidateDCache(); + } +} + +void TouchGFXGeneratedHAL::FlushCache() +{ + // If the framebuffer is placed in Write-Back cached memory (e.g. SRAM) then + // the DCache must be flushed prior to DMA2D accessing it. That's done + // using the function SCB_CleanInvalidateDCache(). Remember to enable + // "CPU Cache" in the "System Core" settings for "Cortex M7" in CubeMX in + // order for this function call to work. + if (SCB->CCR & SCB_CCR_DC_Msk) + { + SCB_CleanInvalidateDCache(); + } +} + +void TouchGFXGeneratedHAL::InvalidateTextureCache() +{ + // Hook to invalidate texture cache(s) prior to drawing to a framebuffer. + // + // When drawing into other buffers in RAM (e.g., dynamic bitmaps), the GPU2D + // texture cache may be incoherent with the main memory. + HAL_ICACHE_Invalidate(); +} + +extern "C" +{ + void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef* hltdc) + { + if (!HAL::getInstance()) + { + return; + } + + if (LTDC->LIPCR == lcd_int_active_line) + { + //entering active area + HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_porch_line); + HAL::getInstance()->vSync(); + OSWrappers::signalVSync(); + + // Swap frame buffers immediately instead of waiting for the task to be scheduled in. + // Note: task will also swap when it wakes up, but that operation is guarded and will not have + // any effect if already swapped. + HAL::getInstance()->swapFrameBuffers(); + GPIO::set(GPIO::VSYNC_FREQ); + } + else + { + //exiting active area + HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_active_line); + + // Signal to the framework that display update has finished. + HAL::getInstance()->frontPorchEntered(); + GPIO::clear(GPIO::VSYNC_FREQ); + } + } +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.hpp b/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.hpp new file mode 100644 index 0000000..76a1470 --- /dev/null +++ b/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.hpp @@ -0,0 +1,211 @@ +/** + ****************************************************************************** + * File Name : TouchGFXGeneratedHAL.hpp + ****************************************************************************** + * This file is generated by TouchGFX Generator 4.26.1. Please, do not edit! + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#ifndef TouchGFXGeneratedHAL_HPP +#define TouchGFXGeneratedHAL_HPP + +#include + +/** + * @class TouchGFXGeneratedHAL + * + * @brief HAL implementation for TouchGFXGenerated. + * + * @sa HAL + */ +class TouchGFXGeneratedHAL : public touchgfx::HALGPU2D +{ +public: + /** + * @fn TouchGFXGeneratedHAL::TouchGFXGeneratedHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : touchgfx::HALGPU2D(dma, display, tc, width, height) + * + * @brief Constructor. + * + * Constructor. Initializes members. + * + * @param [in,out] dma Reference to DMA interface. + * @param [in,out] display Reference to LCD interface. + * @param [in,out] tc Reference to Touch Controller driver. + * @param width Width of the display. + * @param height Height of the display. + */ + TouchGFXGeneratedHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : + touchgfx::HALGPU2D(dma, display, tc, width, height) + { + } + + /** + * @fn void TouchGFXGeneratedHAL::initialize(); + * + * @brief This function is responsible for initializing the entire framework. + * + * This function is responsible for initializing the entire framework. + */ + virtual void initialize(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::configureInterrupts(); + * + * @brief Sets the DMA, LCD, and GPU2D (if enabled) interrupt priorities. + * + * Sets the DMA, LCD, and GPU2D (if enabled) interrupt priorities. + */ + virtual void configureInterrupts(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::enableInterrupts(); + * + * @brief Enables the DMA, LCD, and GPU2D (if enabled) interrupts. + * + * Enables the DMA, LCD, and GPU2D (if enabled) interrupts. + */ + virtual void enableInterrupts(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::disableInterrupts(); + * + * @brief Disables the DMA, LDC, and GPU2D (if enabled) interrupts. + * + * Disables the DMA, LDC, and GPU2D (if enabled) interrupts. + */ + virtual void disableInterrupts(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::enableLCDControllerInterrupt(); + * + * @brief Configure the LCD controller to fire interrupts at VSYNC. + * + * Configure the LCD controller to fire interrupts at VSYNC. Called automatically + * once TouchGFX initialization has completed. + */ + virtual void enableLCDControllerInterrupt(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::flushFrameBuffer(); + * + * @brief This function is called whenever the framework has performed a complete draw. + * + * This specialization is only in place to keep compilers happy. Base impl. will call the + * Rect version. + * @see HAL::flushFrameBuffer + */ + virtual void flushFrameBuffer() + { + HAL::flushFrameBuffer(); + } + + /** + * @fn virtual void TouchGFXGeneratedHAL::unlockFrameBuffer(); + * + * @brief Unlocks the framebuffer. + * + * This specialization is marks DMA2D as un-reserved by the framwork. + * @see HAL::unlockFrameBuffer + */ + virtual void unlockFrameBuffer() + { + HAL::unlockFrameBuffer(); + } + + /** + * @fn virtual void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect); + * + * @brief This function is called whenever the framework has performed a partial draw. + * + * This function is called whenever the framework has performed a partial draw. + * + * @param rect The area of the screen that has been drawn, expressed in absolute coordinates. + * + * @see flushFrameBuffer(). + */ + virtual void flushFrameBuffer(const touchgfx::Rect& rect); + + /** + * + * @fn virtual void TouchGFXGeneratedHAL::blockCopy(); + * + * This function performs a platform-specific memcpy, if supported by the hardware. + * + * @param [out] dest Pointer to destination memory. + * @param [in] src Pointer to source memory. + * @param numBytes Number of bytes to copy. + * + * @return true if the copy succeeded, false if copy was not performed. + */ + virtual bool blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes); + + /** + * @fn virtual void TouchGFXGeneratedHAL::beginFrame(); + * + * @brief Called when beginning to rendering a frame. + * + * Called when beginning to rendering a frame. + * + * @return true if rendering can begin, false otherwise. + */ + virtual bool beginFrame(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::endFrame(); + * + * @brief Called when a rendering pass is completed. + * + * Called when a rendering pass is completed. + */ + virtual void endFrame(); + + /** + * @fn virtual void TouchGFXGeneratedHAL::submitGPU2D(); + * + * @brief This function can be used to explicitly submit any GPU2D operations that + * might be queued in the command list. Can be called if e.g. the task is + * about to sleep, to ensure GPU2D operations are running in the background. + */ + virtual void submitGPU2D(); + +protected: + /** + * @fn virtual uint16_t* TouchGFXGeneratedHAL::getTFTFrameBuffer() const; + * + * @brief Gets the frame buffer address used by the TFT controller. + * + * Gets the frame buffer address used by the TFT controller. + * + * @return The address of the frame buffer currently being displayed on the TFT. + */ + virtual uint16_t* getTFTFrameBuffer() const; + + /** + * @fn virtual void TouchGFXGeneratedHAL::setTFTFrameBuffer(uint16_t* adr); + * + * @brief Sets the frame buffer address used by the TFT controller. + * + * Sets the frame buffer address used by the TFT controller. + * + * @param [in,out] adr New frame buffer address. + */ + virtual void setTFTFrameBuffer(uint16_t* adr); + + virtual void InvalidateCache(); + + virtual void FlushCache(); + + virtual void InvalidateTextureCache(); +}; +#endif // TouchGFXGeneratedHAL_HPP + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/TouchGFX/target/generated/nema_hal.c b/Appli/TouchGFX/target/generated/nema_hal.c new file mode 100644 index 0000000..02b7e91 --- /dev/null +++ b/Appli/TouchGFX/target/generated/nema_hal.c @@ -0,0 +1,275 @@ + +/** + ****************************************************************************** + * @file nema_hal.c + * @author MCD Application Team + * @brief NemaGFX Interfaces and Platform Specific APIs with FreeRTOS CMSISV2 + * support. + * This file provides NemaGFX functions to manage the following + * functionalities of the NemaGFX library: + * + Initialization and de-initialization functions + * + GPU2D Registers access operation functions + * + Buffer Creation, Destruction, MMAP and Flusing functions + * + Interrupt management functions + * + Memory management functions + * + Locking/Unlocking resources functions + ****************************************************************************** + * @attention + * + *

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

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include +#include +#include + +#include +#include + +#include + +#include + +#include "tsi_malloc.h" + +#define RING_SIZE 1024 /* Ring Buffer Size in byte */ +#define NEMAGFX_MEM_POOL_SIZE 24320 /* NemaGFX byte pool size in byte */ +#define NEMAGFX_STENCIL_POOL_SIZE 389120 /* NemaGFX stencil buffer pool size in byte */ + +LOCATION_PRAGMA_NOLOAD("Nemagfx_Memory_Pool_Buffer") +static uint8_t nemagfx_pool_mem[NEMAGFX_MEM_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Memory_Pool_Buffer"); /* NemaGFX memory pool */ + +LOCATION_PRAGMA_NOLOAD("Nemagfx_Stencil_Buffer") +static uint8_t nemagfx_stencil_buffer_mem[NEMAGFX_STENCIL_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Stencil_Buffer"); /* NemaGFX stencil buffer memory */ + +static nema_ringbuffer_t ring_buffer_str; +volatile static int last_cl_id = -1; +extern GPU2D_HandleTypeDef hgpu2d; + +static osSemaphoreId_t nema_irq_sem = NULL; // Declare CL IRQ semaphore + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +static void GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef* hgpu2d, uint32_t CmdListID) +#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */ +void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef* hgpu2d, uint32_t CmdListID) +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hgpu2d); + + last_cl_id = CmdListID; + + /* Return a token back to a semaphore */ + osSemaphoreRelease(nema_irq_sem); +} + +void HAL_GPU2D_ErrorCallback(GPU2D_HandleTypeDef *hgpu2d) +{ + uint32_t val = nema_reg_read(GPU2D_SYS_INTERRUPT); /* clear the ER interrupt */ + nema_reg_write(GPU2D_SYS_INTERRUPT, val); + + /* external GPU2D cache maintenance */ + if (val & (1UL << 2)) + { + HAL_ICACHE_Disable(); + nema_ext_hold_deassert_imm(2); + } + if (val & (1UL << 3)) + { + HAL_ICACHE_Enable(); + HAL_ICACHE_Invalidate(); + nema_ext_hold_deassert_imm(3); + } + + return; +} + +void platform_disable_cache(void) +{ + nema_ext_hold_assert(2, 1); +} + +void platform_invalidate_cache(void) +{ + nema_ext_hold_assert(3, 1); +} + +int32_t nema_sys_init(void) +{ + int error_code = 0; + + /* Setup GPU2D Callback */ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + /* Register Command List Comlete Callback */ + HAL_GPU2D_RegisterCommandListCpltCallback(&hgpu2d, GPU2D_CommandListCpltCallback); +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + + /* Create IRQ semaphore */ + nema_irq_sem = osSemaphoreNew(1, 1, NULL); + assert(nema_irq_sem != NULL); + + /* Initialise Mem Space */ + error_code = tsi_malloc_init_pool_aligned(0, (void*)nemagfx_pool_mem, (uintptr_t)nemagfx_pool_mem, NEMAGFX_MEM_POOL_SIZE, 1, 8); + assert(error_code == 0); + error_code = tsi_malloc_init_pool_aligned(1, (void*)nemagfx_stencil_buffer_mem, (uintptr_t)nemagfx_stencil_buffer_mem, NEMAGFX_STENCIL_POOL_SIZE, 1, 8); + assert(error_code == 0); + + /* Allocate ring_buffer memory */ + ring_buffer_str.bo = nema_buffer_create(RING_SIZE); + assert(ring_buffer_str.bo.base_virt); + + /* Initialize Ring Buffer */ + error_code = nema_rb_init(&ring_buffer_str, 1); + if (error_code < 0) + { + return error_code; + } + + /* Reset last_cl_id counter */ + last_cl_id = 0; + + return error_code; +} + +uint32_t nema_reg_read(uint32_t reg) +{ + return HAL_GPU2D_ReadRegister(&hgpu2d, reg); +} + +void nema_reg_write(uint32_t reg, uint32_t value) +{ + HAL_GPU2D_WriteRegister(&hgpu2d, reg, value); +} + +int nema_wait_irq(void) +{ + /* Wait indefinitely for a free semaphore */ + osSemaphoreAcquire(nema_irq_sem, osWaitForever); + + return 0; +} + +int nema_wait_irq_cl(int cl_id) +{ + while (last_cl_id < cl_id) + { + (void)nema_wait_irq(); + } + + return 0; +} + +int nema_wait_irq_brk(int brk_id) +{ + while (nema_reg_read(GPU2D_BREAKPOINT) == 0U) + { + (void)nema_wait_irq(); + } + + return 0; +} + +void nema_host_free(void* ptr) +{ + tsi_free(ptr); +} + +void* nema_host_malloc(unsigned size) +{ + return tsi_malloc(size); +} + +nema_buffer_t nema_buffer_create(int size) +{ + nema_buffer_t bo; + memset(&bo, 0, sizeof(bo)); + bo.base_virt = tsi_malloc(size); + bo.base_phys = (uint32_t)bo.base_virt; + bo.size = size; + assert(bo.base_virt != 0 && "Unable to allocate memory in nema_buffer_create"); + + return bo; +} + +nema_buffer_t nema_buffer_create_pool(int pool, int size) +{ + nema_buffer_t bo; + memset(&bo, 0, sizeof(bo)); + bo.base_virt = tsi_malloc_pool(pool, size); + bo.base_phys = (uint32_t)bo.base_virt; + bo.size = size; + bo.fd = 0; + assert(bo.base_virt != 0 && "Unable to allocate memory in nema_buffer_create_pool"); + + return bo; +} + +void* nema_buffer_map(nema_buffer_t* bo) +{ + return bo->base_virt; +} + +void nema_buffer_unmap(nema_buffer_t* bo) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(bo); +} + +void nema_buffer_destroy(nema_buffer_t* bo) +{ + if (bo->fd == -1) + { + return; /* Buffer weren't allocated! */ + } + + tsi_free(bo->base_virt); + + bo->base_virt = (void*)0; + bo->base_phys = 0; + bo->size = 0; + bo->fd = -1; /* Buffer not allocated */ +} + +uintptr_t nema_buffer_phys(nema_buffer_t* bo) +{ + return bo->base_phys; +} + +void nema_buffer_flush(nema_buffer_t* bo) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(bo); +} + +int nema_mutex_lock(int mutex_id) +{ + int retval = 0; + + /* USER CODE BEGIN nema_mutex_lock */ + /* Prevent unused argument(s) compilation warning */ + UNUSED(mutex_id); + /* USER CODE END nema_mutex_lock */ + + return retval; +} + +int nema_mutex_unlock(int mutex_id) +{ + int retval = 0; + + /* USER CODE BEGIN nema_mutex_unlock */ + /* Prevent unused argument(s) compilation warning */ + UNUSED(mutex_id); + /* USER CODE END nema_mutex_unlock */ + + return retval; +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld b/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld new file mode 100644 index 0000000..e611708 --- /dev/null +++ b/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld @@ -0,0 +1,304 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Rxx8 Device +** 64Kbytes FLASH +** 456Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @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. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + + +/* Memories definition */ +MEMORY +{ + RAM (rw) : ORIGIN = 0x24000000, LENGTH = 0x00060000 + RAM_CMD (rw) : ORIGIN = 0x24060000, LENGTH = 0x00010000 + + ITCM (rw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00003000 + DTCM_RTOS (rw) : ORIGIN = 0x20003000, LENGTH = 0x0000D000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xr) : ORIGIN = 0x70000000, LENGTH = 0x00200000 + FLASH_GFX (r) : ORIGIN = 0x70200000, LENGTH = 0x07e00000 + EXTRAM (rw) : ORIGIN = 0x90000000, LENGTH = 0x02000000 +} +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +/* Link ISR vectors */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH +} + +/* Define specific placement of memory areas */ +SECTIONS +{ + BufferSection (NOLOAD) : + { + *(TouchGFX_Framebuffer TouchGFX_Framebuffer.*) + *(.gnu.linkonce.r.*) + . = ALIGN(0x8); + + *(Nemagfx_Stencil_Buffer Nemagfx_Stencil_Buffer.*) + *(.gnu.linkonce.r.*) + . = ALIGN(0x8); + } >EXTRAM + + UncachedSection (NOLOAD) : + { + . = ALIGN(32); + KEEP(*(noncacheable_buffer)) + KEEP(*(.noncacheable_buffer*)) + . = ALIGN(32); + + *(Nemagfx_Memory_Pool_Buffer Nemagfx_Memory_Pool_Buffer.*) + *(.gnu.linkonce.r.*) + . = ALIGN(0x8); + } >RAM_CMD + + + FontFlashSection : + { + *(FontFlashSection FontFlashSection.*) + *(.gnu.linkonce.r.*) + . = ALIGN(0x4); + } >FLASH_GFX + + TextFlashSection : + { + *(TextFlashSection TextFlashSection.*) + *(.gnu.linkonce.r.*) + . = ALIGN(0x4); + } >FLASH_GFX + + ExtFlashSection : + { + *(ExtFlashSection ExtFlashSection.*) + *(.gnu.linkonce.r.*) + . = ALIGN(0x4); + } >FLASH_GFX +} + +/* Sections */ +SECTIONS +{ + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM (READONLY) : + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + FreeRtosHeapSection : + { + *(.bss.ucHeap) + . = ALIGN(0x8); + } >DTCM_RTOS + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + + } >RAM AT> FLASH + + /* Initialized TLS data section */ + .tdata : ALIGN(4) + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + PROVIDE(__data_end = .); + PROVIDE(__tdata_end = .); + } >RAM AT> FLASH + + PROVIDE( __tdata_start = ADDR(.tdata) ); + PROVIDE( __tdata_size = __tdata_end - __tdata_start ); + + PROVIDE( __data_start = ADDR(.data) ); + PROVIDE( __data_size = __data_end - __data_start ); + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) ); + PROVIDE( __tdata_source_size = __tdata_source_end - __tdata_source ); + + PROVIDE( __data_source = LOADADDR(.data) ); + PROVIDE( __data_source_end = __tdata_source_end ); + PROVIDE( __data_source_size = __data_source_end - __data_source ); + + + /* Uninitialized data section into "RAM" Ram type memory */ + /* Uninitialized TLS data section */ + .tbss (NOLOAD) : ALIGN(4) + { + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.tbss .tbss.*) + . = ALIGN(4); + PROVIDE( __tbss_end = . ); + } >RAM + + PROVIDE( __tbss_start = ADDR(.tbss) ); + PROVIDE( __tbss_size = __tbss_end - __tbss_start ); + PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) ); + + PROVIDE( __tls_base = __tdata_start ); + PROVIDE( __tls_end = __tbss_end ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) ); + + .bss (NOLOAD) : ALIGN(4) + { + /* This is used by the startup in order to initialize the .bss section */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + PROVIDE( __bss_end = .); + } >RAM + PROVIDE( __non_tls_bss_start = ADDR(.bss) ); + + PROVIDE( __bss_start = __tbss_start ); + PROVIDE( __bss_size = __bss_end - __bss_start ); + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack (NOLOAD) : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a:* ( * ) + libm.a:* ( * ) + libgcc.a:* ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/Boot/Core/Inc/extmem_manager.h b/Boot/Core/Inc/extmem_manager.h new file mode 100644 index 0000000..1b36478 --- /dev/null +++ b/Boot/Core/Inc/extmem_manager.h @@ -0,0 +1,67 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : mx_extmem.h + * @version : 1.0.0 + * @brief : Header for secure_manager_api.c 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MX_EXTMEM__H__ +#define __MX_EXTMEM__H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem_conf.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN VARIABLES */ + +/* USER CODE END VARIABLES */ + +void MX_EXTMEM_MANAGER_Init(void); + +/* + * -- Insert functions declaration here -- + */ +/* USER CODE BEGIN FD */ + +/* USER CODE END FD */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MX_EXTMEM__H__ */ + diff --git a/Boot/Core/Inc/main.h b/Boot/Core/Inc/main.h new file mode 100644 index 0000000..5908d05 --- /dev/null +++ b/Boot/Core/Inc/main.h @@ -0,0 +1,90 @@ +/* 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 "stm32h7rsxx_hal.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 FRAME_RATE_Pin GPIO_PIN_3 +#define FRAME_RATE_GPIO_Port GPIOF +#define RENDER_TIME_Pin GPIO_PIN_2 +#define RENDER_TIME_GPIO_Port GPIOF +#define ADF1_CK_Pin GPIO_PIN_2 +#define ADF1_CK_GPIO_Port GPIOE +#define MCU_ACTIVE_Pin GPIO_PIN_4 +#define MCU_ACTIVE_GPIO_Port GPIOF +#define VSYNC_FREQ_Pin GPIO_PIN_1 +#define VSYNC_FREQ_GPIO_Port GPIOF +#define LCD_EN_Pin GPIO_PIN_15 +#define LCD_EN_GPIO_Port GPIOE +#define ADF1_D_Pin GPIO_PIN_6 +#define ADF1_D_GPIO_Port GPIOD +#define TP_IRQ_Pin GPIO_PIN_3 +#define TP_IRQ_GPIO_Port GPIOE +#define TP_IRQ_EXTI_IRQn EXTI3_IRQn +#define LCD_BL_CTRL_Pin GPIO_PIN_15 +#define LCD_BL_CTRL_GPIO_Port GPIOG +#define MIC_DET_Pin GPIO_PIN_1 +#define MIC_DET_GPIO_Port GPIOH + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Boot/Core/Inc/stm32_extmem_conf.h b/Boot/Core/Inc/stm32_extmem_conf.h new file mode 100644 index 0000000..d72215f --- /dev/null +++ b/Boot/Core/Inc/stm32_extmem_conf.h @@ -0,0 +1,118 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : stm32_extmem_conf.h + * @version : 1.0.0 + * @brief : Header for extmem.c 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_EXTMEM_CONF__H__ +#define __STM32_EXTMEM_CONF__H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/* + @brief management of the driver layer enable +*/ + +#define EXTMEM_DRIVER_NOR_SFDP 1 +#define EXTMEM_DRIVER_PSRAM 1 +#define EXTMEM_DRIVER_SDCARD 0 +#define EXTMEM_DRIVER_USER 0 + +/* + @brief management of the sal layer enable +*/ +#define EXTMEM_SAL_XSPI 1 +#define EXTMEM_SAL_SD 0 + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" +#include "stm32_extmem.h" +#include "stm32_extmem_type.h" +#include "boot/stm32_boot_xip.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ +/* Private variables ---------------------------------------------------------*/ +extern XSPI_HandleTypeDef hxspi2; +extern XSPI_HandleTypeDef hxspi1; + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXTMEM_CONF_Exported_constants EXTMEM_CONF exported constants + * @{ + */ +enum { + EXTMEMORY_1 = 0, /*!< ID=0 for the first external memory */ + EXTMEMORY_2 = 1, /*!< ID=1 for the second external memory */ +}; + +/* + @brief management of the boot layer +*/ +#define EXTMEM_MEMORY_BOOTXIP EXTMEMORY_1 + +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported configuration --------------------------------------------------------*/ +/** @defgroup EXTMEM_CONF_Exported_configuration EXTMEM_CONF exported configuration definition + * @{ + */ + +extern EXTMEM_DefinitionTypeDef extmem_list_config[2]; +#if defined(EXTMEM_C) +EXTMEM_DefinitionTypeDef extmem_list_config[2]; +#endif /* EXTMEM_C */ + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN VARIABLES */ + +/* USER CODE END VARIABLES */ + +/* + * -- Insert functions declaration here -- + */ +/* USER CODE BEGIN FD */ + +/* USER CODE END FD */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_EXTMEM_CONF__H__ */ diff --git a/Boot/Core/Inc/stm32h7rsxx_hal_conf.h b/Boot/Core/Inc/stm32h7rsxx_hal_conf.h new file mode 100644 index 0000000..f71bc0e --- /dev/null +++ b/Boot/Core/Inc/stm32h7rsxx_hal_conf.h @@ -0,0 +1,520 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32h7rsxx_hal_conf.h. + * + ****************************************************************************** + * @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 STM32H7RSxx_HAL_CONF_H +#define STM32H7RSxx_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_CORDIC_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DCMIPP_MODULE_ENABLED */ +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_DTS_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +/* #define HAL_FDCAN_MODULE_ENABLED */ +/* #define HAL_GFXMMU_MODULE_ENABLED */ +/* #define HAL_GFXTIM_MODULE_ENABLED */ +/* #define HAL_GPU2D_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_JPEG_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_MCE_MODULE_ENABLED */ +/* #define HAL_MDF_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_PKA_MODULE_ENABLED */ +/* #define HAL_PSSI_MODULE_ENABLED */ +/* #define HAL_RAMECC_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_SDIO_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_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 +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_EXTI_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 24000000UL /*!< 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 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 Low-power 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 (HSI48) value for USB OTG FS 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 OTG FS/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. + Value of the Internal Low Speed oscillator in Hz. + The real value may vary depending on the variations + in voltage and temperature.*/ +#endif /* LSI_VALUE */ + +/** +* @brief External Low Speed oscillator (LSE) value. +*/ +#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 digital audio interfaces: SPI/I2S, SAI and ADF + * This value is used by the RCC HAL module to provide the digital audio interfaces + * frequency. This clock source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 48000UL /*!< Value of the external clock source 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 + +/* ########################## 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 stm32h7rsxx_hal_ppp.h file +* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef +* for each PPP peripheral). +*/ +#define USE_HAL_ADC_REGISTER_CALLBACKS 1U +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DCMIPP_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 1U +#define USE_HAL_I2S_REGISTER_CALLBACKS 1U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_MDF_REGISTER_CALLBACKS 1U +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U +#define USE_HAL_PSSI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 1U +#define USE_HAL_SD_REGISTER_CALLBACKS 0U +#define USE_HAL_SDIO_REGISTER_CALLBACKS 0U +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 1U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_XSPI_REGISTER_CALLBACKS 1U + +/* ################## 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 + +/* ################## CRYP peripheral configuration ########################## */ + +/** + * @brief For code optimization purpose, uncomment and set to "1U" the USE_HAL_CRYP_ONLY or USE_HAL_SAES_ONLY, + * to use only one peripheral. Both defines cannot be set to "1U" at the same time. + */ + +/* #define USE_HAL_CRYP_ONLY 1U */ +/* #define USE_HAL_SAES_ONLY 0U */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 0U + +/* ################## HASH peripheral configuration ########################## */ + +#define USE_HAL_HASH_SUSPEND_RESUME 0U + +/* ################## SDMMC peripheral configuration ######################### */ + +#define USE_SD_TRANSCEIVER 0U + +/* ################## SDIO peripheral configuration ######################### */ + +#define USE_SDIO_TRANSCEIVER 0U +#define SDIO_MAX_IO_NUMBER 7U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32h7rsxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32h7rsxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32h7rsxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32h7rsxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32h7rsxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32h7rsxx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED + #include "stm32h7rsxx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32h7rsxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32h7rsxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DCMIPP_MODULE_ENABLED + #include "stm32h7rsxx_hal_dcmipp.h" +#endif /* HAL_DCMIPP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32h7rsxx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DTS_MODULE_ENABLED + #include "stm32h7rsxx_hal_dts.h" +#endif /* HAL_DTS_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32h7rsxx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32h7rsxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED + #include "stm32h7rsxx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32h7rsxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GFXMMU_MODULE_ENABLED + #include "stm32h7rsxx_hal_gfxmmu.h" +#endif /* HAL_GFXMMU_MODULE_ENABLED */ + +#ifdef HAL_GFXTIM_MODULE_ENABLED + #include "stm32h7rsxx_hal_gfxtim.h" +#endif /* HAL_GFXTIM_MODULE_ENABLED */ + +#ifdef HAL_GPU2D_MODULE_ENABLED + #include "stm32h7rsxx_hal_gpu2d.h" +#endif /* HAL_GPU2D_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32h7rsxx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32h7rsxx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32h7rsxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32h7rsxx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_I3C_MODULE_ENABLED + #include "stm32h7rsxx_hal_i3c.h" +#endif /* HAL_I3C_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED + #include "stm32h7rsxx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32h7rsxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32h7rsxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_JPEG_MODULE_ENABLED + #include "stm32h7rsxx_hal_jpeg.h" +#endif /* HAL_JPEG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32h7rsxx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32h7rsxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MCE_MODULE_ENABLED + #include "stm32h7rsxx_hal_mce.h" +#endif /* HAL_MCE_MODULE_ENABLED */ + +#ifdef HAL_MDF_MODULE_ENABLED + #include "stm32h7rsxx_hal_mdf.h" +#endif /* HAL_MDF_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32h7rsxx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32h7rsxx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32h7rsxx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32h7rsxx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32h7rsxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED + #include "stm32h7rsxx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32h7rsxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RAMECC_MODULE_ENABLED + #include "stm32h7rsxx_hal_ramecc.h" +#endif /* HAL_RAMECC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32h7rsxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32h7rsxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32h7rsxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32h7rsxx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SDIO_MODULE_ENABLED +#include "stm32h7rsxx_hal_sdio.h" +#endif /* HAL_SDIO_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32h7rsxx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32h7rsxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32h7rsxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32h7rsxx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32h7rsxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32h7rsxx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32h7rsxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32h7rsxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32h7rsxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32h7rsxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED + #include "stm32h7rsxx_hal_xspi.h" +#endif /* HAL_XSPI_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 /* STM32H7RSxx_HAL_CONF_H */ + diff --git a/Boot/Core/Inc/stm32h7rsxx_it.h b/Boot/Core/Inc/stm32h7rsxx_it.h new file mode 100644 index 0000000..455e5ab --- /dev/null +++ b/Boot/Core/Inc/stm32h7rsxx_it.h @@ -0,0 +1,66 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 __STM32H7RSxx_IT_H +#define __STM32H7RSxx_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 /* __STM32H7RSxx_IT_H */ diff --git a/Boot/Core/Src/extmem_manager.c b/Boot/Core/Src/extmem_manager.c new file mode 100644 index 0000000..ccb0a00 --- /dev/null +++ b/Boot/Core/Src/extmem_manager.c @@ -0,0 +1,104 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : mx_extmem.c + * @version : 1.0.0 + * @brief : This file implements the extmem 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "extmem_manager.h" +#include + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* + * -- Insert your external function declaration here -- + */ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Init External memory manager + * @retval None + */ +void MX_EXTMEM_MANAGER_Init(void) +{ + + /* USER CODE BEGIN MX_EXTMEM_Init_PreTreatment */ + + /* USER CODE END MX_EXTMEM_Init_PreTreatment */ + HAL_RCCEx_EnableClockProtection(RCC_CLOCKPROTECT_XSPI); + + /* Initialization of the memory parameters */ + memset(extmem_list_config, 0x0, sizeof(extmem_list_config)); + + /* EXTMEMORY_1 */ + extmem_list_config[0].MemType = EXTMEM_NOR_SFDP; + extmem_list_config[0].Handle = (void*)&hxspi2; + extmem_list_config[0].ConfigType = EXTMEM_LINK_CONFIG_8LINES; + + /* EXTMEMORY_2 */ + extmem_list_config[1].MemType = EXTMEM_PSRAM; + extmem_list_config[1].Handle = (void*)&hxspi1; + extmem_list_config[1].ConfigType = EXTMEM_LINK_CONFIG_16LINES; + + extmem_list_config[1].PsramObject.psram_public.MemorySize = HAL_XSPI_SIZE_256MB; + extmem_list_config[1].PsramObject.psram_public.FreqMax = 133 * 1000000u; + extmem_list_config[1].PsramObject.psram_public.NumberOfConfig = 1u; + + /* Config */ + extmem_list_config[1].PsramObject.psram_public.config[0].WriteMask = 0x40u; + extmem_list_config[1].PsramObject.psram_public.config[0].WriteValue = 0x40u; + extmem_list_config[1].PsramObject.psram_public.config[0].REGAddress = 0x08u; + + /* Memory command configuration */ + extmem_list_config[1].PsramObject.psram_public.ReadREG = 0x40u; + extmem_list_config[1].PsramObject.psram_public.WriteREG = 0xC0u; + extmem_list_config[1].PsramObject.psram_public.ReadREGSize = 2u; + extmem_list_config[1].PsramObject.psram_public.REG_DummyCycle = 4u; + extmem_list_config[1].PsramObject.psram_public.Write_command = 0xA0u; + extmem_list_config[1].PsramObject.psram_public.Write_DummyCycle = 4u; + extmem_list_config[1].PsramObject.psram_public.Read_command = 0x20u; + extmem_list_config[1].PsramObject.psram_public.WrapRead_command = 0x00u; + extmem_list_config[1].PsramObject.psram_public.Read_DummyCycle = 4u; + + EXTMEM_Init(EXTMEMORY_1, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI2)); + EXTMEM_Init(EXTMEMORY_2, HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI1)); + + /* USER CODE BEGIN MX_EXTMEM_Init_PostTreatment */ + + /* USER CODE END MX_EXTMEM_Init_PostTreatment */ +} diff --git a/Boot/Core/Src/main.c b/Boot/Core/Src/main.c new file mode 100644 index 0000000..cce698c --- /dev/null +++ b/Boot/Core/Src/main.c @@ -0,0 +1,491 @@ +/* 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 "extmem_manager.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 ---------------------------------------------------------*/ + +XSPI_HandleTypeDef hxspi1; +XSPI_HandleTypeDef hxspi2; + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_HPDMA1_Init(void); +static void MX_GPDMA1_Init(void); +static void MX_XSPI1_Init(void); +static void MX_XSPI2_Init(void); +static void MX_FLASH_Init(void); +static void MX_SBS_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 */ + + /* Enable the CPU Cache */ + + /* Enable I-Cache---------------------------------------------------------*/ + SCB_EnableICache(); + + /* Enable D-Cache---------------------------------------------------------*/ + SCB_EnableDCache(); + + /* 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_HPDMA1_Init(); + MX_GPDMA1_Init(); + MX_XSPI1_Init(); + MX_XSPI2_Init(); + MX_FLASH_Init(); + MX_SBS_Init(); + MX_EXTMEM_MANAGER_Init(); + /* USER CODE BEGIN 2 */ + + /* USER CODE END 2 */ + + /* Launch the application */ + if (BOOT_OK != BOOT_Application()) + { + Error_Handler(); + } + /* 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 + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0) != HAL_OK) + { + Error_Handler(); + } + + /** Configure LSE Drive Capability + */ + HAL_PWR_EnableBkUpAccess(); + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL1.PLLM = 4; + RCC_OscInitStruct.PLL1.PLLN = 200; + RCC_OscInitStruct.PLL1.PLLP = 2; + RCC_OscInitStruct.PLL1.PLLQ = 2; + RCC_OscInitStruct.PLL1.PLLR = 2; + RCC_OscInitStruct.PLL1.PLLS = 2; + RCC_OscInitStruct.PLL1.PLLT = 2; + RCC_OscInitStruct.PLL1.PLLFractional = 0; + RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL2.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL2.PLLM = 5; + RCC_OscInitStruct.PLL2.PLLN = 128; + RCC_OscInitStruct.PLL2.PLLP = 25; + RCC_OscInitStruct.PLL2.PLLQ = 10; + RCC_OscInitStruct.PLL2.PLLR = 2; + RCC_OscInitStruct.PLL2.PLLS = 2; + RCC_OscInitStruct.PLL2.PLLT = 2; + RCC_OscInitStruct.PLL2.PLLFractional = 0; + RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL3.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL3.PLLM = 2; + RCC_OscInitStruct.PLL3.PLLN = 50; + RCC_OscInitStruct.PLL3.PLLP = 2; + RCC_OscInitStruct.PLL3.PLLQ = 2; + RCC_OscInitStruct.PLL3.PLLR = 24; + RCC_OscInitStruct.PLL3.PLLS = 2; + RCC_OscInitStruct.PLL3.PLLT = 2; + RCC_OscInitStruct.PLL3.PLLFractional = 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_PCLK4|RCC_CLOCKTYPE_PCLK5; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; + RCC_ClkInitStruct.APB5CLKDivider = RCC_APB5_DIV2; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief FLASH Initialization Function + * @param None + * @retval None + */ +static void MX_FLASH_Init(void) +{ + + /* USER CODE BEGIN FLASH_Init 0 */ + + /* USER CODE END FLASH_Init 0 */ + + FLASH_OBProgramInitTypeDef pOBInit = {0}; + + /* USER CODE BEGIN FLASH_Init 1 */ + + /* USER CODE END FLASH_Init 1 */ + HAL_FLASHEx_OBGetConfig(&pOBInit); + if ((pOBInit.USERConfig1 & OB_IWDG_SW) != OB_IWDG_SW|| +(pOBInit.USERConfig1 & OB_XSPI1_HSLV_ENABLE) != OB_XSPI1_HSLV_ENABLE|| +(pOBInit.USERConfig1 & OB_XSPI2_HSLV_ENABLE) != OB_XSPI2_HSLV_ENABLE|| +(pOBInit.USERConfig2 & OB_I2C_NI3C_I2C) != OB_I2C_NI3C_I2C) + { + if (HAL_FLASH_Unlock() != HAL_OK) + { + Error_Handler(); + } + if (HAL_FLASH_OB_Unlock() != HAL_OK) + { + Error_Handler(); + } + pOBInit.OptionType = OPTIONBYTE_USER; + pOBInit.USERType = OB_USER_IWDG_SW|OB_USER_XSPI1_HSLV + |OB_USER_XSPI2_HSLV|OB_USER_I2C_NI3C; + pOBInit.USERConfig1 = OB_IWDG_SW|OB_XSPI1_HSLV_ENABLE + |OB_XSPI2_HSLV_ENABLE; + pOBInit.USERConfig2 = OB_I2C_NI3C_I2C; + if (HAL_FLASHEx_OBProgram(&pOBInit) != HAL_OK) + { + Error_Handler(); + } + if (HAL_FLASH_OB_Lock() != HAL_OK) + { + Error_Handler(); + } + if (HAL_FLASH_Lock() != HAL_OK) + { + Error_Handler(); + } + } + /* USER CODE BEGIN FLASH_Init 2 */ + + /* USER CODE END FLASH_Init 2 */ + +} + +/** + * @brief GPDMA1 Initialization Function + * @param None + * @retval None + */ +static void MX_GPDMA1_Init(void) +{ + + /* USER CODE BEGIN GPDMA1_Init 0 */ + + /* USER CODE END GPDMA1_Init 0 */ + + /* Peripheral clock enable */ + __HAL_RCC_GPDMA1_CLK_ENABLE(); + + /* USER CODE BEGIN GPDMA1_Init 1 */ + + /* USER CODE END GPDMA1_Init 1 */ + /* USER CODE BEGIN GPDMA1_Init 2 */ + + /* USER CODE END GPDMA1_Init 2 */ + +} + +/** + * @brief HPDMA1 Initialization Function + * @param None + * @retval None + */ +static void MX_HPDMA1_Init(void) +{ + + /* USER CODE BEGIN HPDMA1_Init 0 */ + + /* USER CODE END HPDMA1_Init 0 */ + + /* Peripheral clock enable */ + __HAL_RCC_HPDMA1_CLK_ENABLE(); + + /* USER CODE BEGIN HPDMA1_Init 1 */ + + /* USER CODE END HPDMA1_Init 1 */ + /* USER CODE BEGIN HPDMA1_Init 2 */ + + /* USER CODE END HPDMA1_Init 2 */ + +} + +/** + * @brief SBS Initialization Function + * @param None + * @retval None + */ +static void MX_SBS_Init(void) +{ + + /* USER CODE BEGIN SBS_Init 0 */ + + /* USER CODE END SBS_Init 0 */ + + /* USER CODE BEGIN SBS_Init 1 */ + + /* USER CODE END SBS_Init 1 */ + /* USER CODE BEGIN SBS_Init 2 */ + + /* USER CODE END SBS_Init 2 */ + +} + +/** + * @brief XSPI1 Initialization Function + * @param None + * @retval None + */ +static void MX_XSPI1_Init(void) +{ + + /* USER CODE BEGIN XSPI1_Init 0 */ + + /* USER CODE END XSPI1_Init 0 */ + + XSPIM_CfgTypeDef sXspiManagerCfg = {0}; + + /* USER CODE BEGIN XSPI1_Init 1 */ + + /* USER CODE END XSPI1_Init 1 */ + /* XSPI1 parameter configuration*/ + hxspi1.Instance = XSPI1; + hxspi1.Init.FifoThresholdByte = 2; + hxspi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM; + hxspi1.Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM_16BITS; + hxspi1.Init.MemorySize = HAL_XSPI_SIZE_256MB; + hxspi1.Init.ChipSelectHighTimeCycle = 5; + hxspi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE; + hxspi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0; + hxspi1.Init.WrapSize = HAL_XSPI_WRAP_32_BYTES; + hxspi1.Init.ClockPrescaler = 0; + hxspi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE; + hxspi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_16KB; + hxspi1.Init.MaxTran = 0; + hxspi1.Init.Refresh = 400; + hxspi1.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1; + if (HAL_XSPI_Init(&hxspi1) != HAL_OK) + { + Error_Handler(); + } + sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1; + sXspiManagerCfg.IOPort = HAL_XSPIM_IOPORT_1; + sXspiManagerCfg.Req2AckTime = 1; + if (HAL_XSPIM_Config(&hxspi1, &sXspiManagerCfg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN XSPI1_Init 2 */ + + /* USER CODE END XSPI1_Init 2 */ + +} + +/** + * @brief XSPI2 Initialization Function + * @param None + * @retval None + */ +static void MX_XSPI2_Init(void) +{ + + /* USER CODE BEGIN XSPI2_Init 0 */ + + /* USER CODE END XSPI2_Init 0 */ + + XSPIM_CfgTypeDef sXspiManagerCfg = {0}; + + /* USER CODE BEGIN XSPI2_Init 1 */ + + /* USER CODE END XSPI2_Init 1 */ + /* XSPI2 parameter configuration*/ + hxspi2.Instance = XSPI2; + hxspi2.Init.FifoThresholdByte = 4; + hxspi2.Init.MemoryMode = HAL_XSPI_SINGLE_MEM; + hxspi2.Init.MemoryType = HAL_XSPI_MEMTYPE_MACRONIX; + hxspi2.Init.MemorySize = HAL_XSPI_SIZE_1GB; + hxspi2.Init.ChipSelectHighTimeCycle = 2; + hxspi2.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE; + hxspi2.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0; + hxspi2.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED; + hxspi2.Init.ClockPrescaler = 0; + hxspi2.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE; + hxspi2.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE; + hxspi2.Init.MaxTran = 0; + hxspi2.Init.Refresh = 0; + hxspi2.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1; + if (HAL_XSPI_Init(&hxspi2) != HAL_OK) + { + Error_Handler(); + } + sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1; + sXspiManagerCfg.IOPort = HAL_XSPIM_IOPORT_2; + sXspiManagerCfg.Req2AckTime = 1; + if (HAL_XSPIM_Config(&hxspi2, &sXspiManagerCfg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN XSPI2_Init 2 */ + + /* USER CODE END XSPI2_Init 2 */ + +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + /* USER CODE BEGIN MX_GPIO_Init_1 */ + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPION_CLK_ENABLE(); + __HAL_RCC_GPIOO_CLK_ENABLE(); + __HAL_RCC_GPIOP_CLK_ENABLE(); + + /* 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/Boot/Core/Src/stm32h7rsxx_hal_msp.c b/Boot/Core/Src/stm32h7rsxx_hal_msp.c new file mode 100644 index 0000000..9a9185e --- /dev/null +++ b/Boot/Core/Src/stm32h7rsxx_hal_msp.c @@ -0,0 +1,316 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 */ + +/* 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) +{ + + /* Configure the system Power Supply */ + + if (HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY) != HAL_OK) + { + /* Initialization error */ + Error_Handler(); + } + + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SBS_CLK_ENABLE(); + + /* System interrupt init*/ + + /* Enable the XSPIM_P1 interface */ + HAL_PWREx_EnableXSPIM1(); + + /* Enable the XSPIM_P2 interface */ + HAL_PWREx_EnableXSPIM2(); + + /* USER CODE BEGIN MspInit 1 */ + /* high speed low voltage config */ + HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI1_HSLV); + HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI2_HSLV); + /* USER CODE END MspInit 1 */ +} + +static uint32_t HAL_RCC_XSPIM_CLK_ENABLED=0; + +/** + * @brief XSPI MSP Initialization + * This function configures the hardware resources used in this example + * @param hxspi: XSPI handle pointer + * @retval None + */ +void HAL_XSPI_MspInit(XSPI_HandleTypeDef* hxspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(hxspi->Instance==XSPI1) + { + /* USER CODE BEGIN XSPI1_MspInit 0 */ + + /* USER CODE END XSPI1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_XSPI1; + PeriphClkInit.Xspi1ClockSelection = RCC_XSPI1CLKSOURCE_PLL2S; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + HAL_RCC_XSPIM_CLK_ENABLED++; + if(HAL_RCC_XSPIM_CLK_ENABLED==1){ + __HAL_RCC_XSPIM_CLK_ENABLE(); + } + __HAL_RCC_XSPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOO_CLK_ENABLE(); + __HAL_RCC_GPIOP_CLK_ENABLE(); + /**XSPI1 GPIO Configuration + PO3 ------> XSPIM_P1_DQS1 + PP10 ------> XSPIM_P1_IO10 + PP12 ------> XSPIM_P1_IO12 + PP14 ------> XSPIM_P1_IO14 + PP2 ------> XSPIM_P1_IO2 + PP5 ------> XSPIM_P1_IO5 + PO2 ------> XSPIM_P1_DQS0 + PP1 ------> XSPIM_P1_IO1 + PP11 ------> XSPIM_P1_IO11 + PP15 ------> XSPIM_P1_IO15 + PP3 ------> XSPIM_P1_IO3 + PP0 ------> XSPIM_P1_IO0 + PP7 ------> XSPIM_P1_IO7 + PP8 ------> XSPIM_P1_IO8 + PP13 ------> XSPIM_P1_IO13 + PP4 ------> XSPIM_P1_IO4 + PO4 ------> XSPIM_P1_CLK + PP6 ------> XSPIM_P1_IO6 + PO0 ------> XSPIM_P1_NCS1 + PP9 ------> XSPIM_P1_IO9 + */ + GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_XSPIM_P1; + HAL_GPIO_Init(GPIOO, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_2 + |GPIO_PIN_5|GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_15 + |GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_8 + |GPIO_PIN_13|GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_XSPIM_P1; + HAL_GPIO_Init(GPIOP, &GPIO_InitStruct); + + /* USER CODE BEGIN XSPI1_MspInit 1 */ + + /* USER CODE END XSPI1_MspInit 1 */ + } + else if(hxspi->Instance==XSPI2) + { + /* USER CODE BEGIN XSPI2_MspInit 0 */ + + /* USER CODE END XSPI2_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_XSPI2; + PeriphClkInit.Xspi2ClockSelection = RCC_XSPI2CLKSOURCE_PLL2S; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + HAL_RCC_XSPIM_CLK_ENABLED++; + if(HAL_RCC_XSPIM_CLK_ENABLED==1){ + __HAL_RCC_XSPIM_CLK_ENABLE(); + } + __HAL_RCC_XSPI2_CLK_ENABLE(); + + __HAL_RCC_GPION_CLK_ENABLE(); + /**XSPI2 GPIO Configuration + PN1 ------> XSPIM_P2_NCS1 + PN3 ------> XSPIM_P2_IO1 + PN0 ------> XSPIM_P2_DQS0 + PN11 ------> XSPIM_P2_IO7 + PN10 ------> XSPIM_P2_IO6 + PN9 ------> XSPIM_P2_IO5 + PN2 ------> XSPIM_P2_IO0 + PN6 ------> XSPIM_P2_CLK + PN8 ------> XSPIM_P2_IO4 + PN4 ------> XSPIM_P2_IO2 + PN5 ------> XSPIM_P2_IO3 + */ + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_11 + |GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_2|GPIO_PIN_6 + |GPIO_PIN_8|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_XSPIM_P2; + HAL_GPIO_Init(GPION, &GPIO_InitStruct); + + /* USER CODE BEGIN XSPI2_MspInit 1 */ + + /* USER CODE END XSPI2_MspInit 1 */ + } + +} + +/** + * @brief XSPI MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hxspi: XSPI handle pointer + * @retval None + */ +void HAL_XSPI_MspDeInit(XSPI_HandleTypeDef* hxspi) +{ + if(hxspi->Instance==XSPI1) + { + /* USER CODE BEGIN XSPI1_MspDeInit 0 */ + + /* USER CODE END XSPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + HAL_RCC_XSPIM_CLK_ENABLED--; + if(HAL_RCC_XSPIM_CLK_ENABLED==0){ + __HAL_RCC_XSPIM_CLK_DISABLE(); + } + __HAL_RCC_XSPI1_CLK_DISABLE(); + + /**XSPI1 GPIO Configuration + PO3 ------> XSPIM_P1_DQS1 + PP10 ------> XSPIM_P1_IO10 + PP12 ------> XSPIM_P1_IO12 + PP14 ------> XSPIM_P1_IO14 + PP2 ------> XSPIM_P1_IO2 + PP5 ------> XSPIM_P1_IO5 + PO2 ------> XSPIM_P1_DQS0 + PP1 ------> XSPIM_P1_IO1 + PP11 ------> XSPIM_P1_IO11 + PP15 ------> XSPIM_P1_IO15 + PP3 ------> XSPIM_P1_IO3 + PP0 ------> XSPIM_P1_IO0 + PP7 ------> XSPIM_P1_IO7 + PP8 ------> XSPIM_P1_IO8 + PP13 ------> XSPIM_P1_IO13 + PP4 ------> XSPIM_P1_IO4 + PO4 ------> XSPIM_P1_CLK + PP6 ------> XSPIM_P1_IO6 + PO0 ------> XSPIM_P1_NCS1 + PP9 ------> XSPIM_P1_IO9 + */ + HAL_GPIO_DeInit(GPIOO, GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_0); + + HAL_GPIO_DeInit(GPIOP, GPIO_PIN_10|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_2 + |GPIO_PIN_5|GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_15 + |GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_8 + |GPIO_PIN_13|GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9); + + /* USER CODE BEGIN XSPI1_MspDeInit 1 */ + + /* USER CODE END XSPI1_MspDeInit 1 */ + } + else if(hxspi->Instance==XSPI2) + { + /* USER CODE BEGIN XSPI2_MspDeInit 0 */ + + /* USER CODE END XSPI2_MspDeInit 0 */ + /* Peripheral clock disable */ + HAL_RCC_XSPIM_CLK_ENABLED--; + if(HAL_RCC_XSPIM_CLK_ENABLED==0){ + __HAL_RCC_XSPIM_CLK_DISABLE(); + } + __HAL_RCC_XSPI2_CLK_DISABLE(); + + /**XSPI2 GPIO Configuration + PN1 ------> XSPIM_P2_NCS1 + PN3 ------> XSPIM_P2_IO1 + PN0 ------> XSPIM_P2_DQS0 + PN11 ------> XSPIM_P2_IO7 + PN10 ------> XSPIM_P2_IO6 + PN9 ------> XSPIM_P2_IO5 + PN2 ------> XSPIM_P2_IO0 + PN6 ------> XSPIM_P2_CLK + PN8 ------> XSPIM_P2_IO4 + PN4 ------> XSPIM_P2_IO2 + PN5 ------> XSPIM_P2_IO3 + */ + HAL_GPIO_DeInit(GPION, GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_0|GPIO_PIN_11 + |GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_2|GPIO_PIN_6 + |GPIO_PIN_8|GPIO_PIN_4|GPIO_PIN_5); + + /* USER CODE BEGIN XSPI2_MspDeInit 1 */ + + /* USER CODE END XSPI2_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Boot/Core/Src/stm32h7rsxx_it.c b/Boot/Core/Src/stm32h7rsxx_it.c new file mode 100644 index 0000000..2caf5d0 --- /dev/null +++ b/Boot/Core/Src/stm32h7rsxx_it.c @@ -0,0 +1,203 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 "stm32h7rsxx_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 Pre-fetch 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 */ +} + +/******************************************************************************/ +/* STM32H7RSxx 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_stm32h7rsxx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Boot/Core/Src/system_stm32h7rsxx.c b/Boot/Core/Src/system_stm32h7rsxx.c new file mode 100644 index 0000000..bc2429f --- /dev/null +++ b/Boot/Core/Src/system_stm32h7rsxx.c @@ -0,0 +1,304 @@ +/** + ****************************************************************************** + * @file system_stm32h7rsxx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M7 Device Peripheral Access Layer System Source 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. + * + ****************************************************************************** + * + * 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_stm32h7rsxx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (sys_cpu_ck), 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_stm32h7rsxx.s" file, to + * optionally configure the system clock before to branch to main program. + * + *============================================================================= + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32H7RSxx_System + * @{ + */ + +/** @addtogroup STM32H7RSxx_System_Private_Includes + * @{ + */ + +#include "stm32h7rsxx.h" +#include + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 24000000UL /*!< Value of the High-Speed External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE 64000000UL /*!< Value of the High-Speed Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE 4000000UL /*!< Value of the Low-power Internal oscillator in Hz */ +#endif /* CSI_VALUE */ + +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line or define USER_VECT_TAB_ADDRESS at compiler level if you need + to relocate the vector table anywhere in Flash or Sram, else the vector table is kept at + the automatic remap of the selected boot address */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line or define VECT_TAB_SRAM at compiler level if you need + to relocate your vector Table in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ + +#if defined(VECT_TAB_SRAM) +#if !defined(VECT_TAB_BASE_ADDRESS) +#define VECT_TAB_BASE_ADDRESS ITCM_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x400. */ +#endif +#if !defined(VECT_TAB_OFFSET) +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x400. */ +#endif +#else +#if !defined(VECT_TAB_BASE_ADDRESS) +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. + This value must be a multiple of 0x400. */ +#endif +#if !defined(VECT_TAB_OFFSET) +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. + This value must be a multiple of 0x400. */ +#endif +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ + +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in two ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) 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 first function listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = HSI_VALUE; + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @retval None + */ + +void SystemInit(void) +{ + /* Configure the Vector Table location -------------------------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; +#endif + + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to RCC registers values. + * The SystemCoreClock variable contains the core clock (sys_cpu_ck), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock 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 HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSI_VALUE(*) + * or CSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) CSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal.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. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc; + float_t pllfracn, pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* HSI used as system clock source (default after reset) */ + sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + break; + + case 0x08: /* CSI used as system clock source */ + sysclk = CSI_VALUE; + break; + + case 0x10: /* HSE used as system clock source */ + sysclk = HSE_VALUE; + break; + + case 0x18: /* PLL1 used as system clock source */ + /* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL1_VCO / PLL1R + */ + pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC); + pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ; + if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U) + { + pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)>> RCC_PLL1FRACR_FRACN_Pos)); + } + else + { + pllfracn = (float_t)0U; + } + + if (pllm != 0U) + { + switch (pllsource) + { + case 0x02: /* HSE used as PLL1 clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x01: /* CSI used as PLL1 clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x00: /* HSI used as PLL1 clock source */ + default: + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 ); + break; + } + pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U ) ; + sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp); + } + else + { + sysclk = 0U; + } + break; + + default: /* Unexpected, default to HSI used as system clock source (default after reset) */ + sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos)); + break; + } + + /* system clock frequency : CM7 CPU frequency */ + core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE); + if (core_presc >= 8U) + { + SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U)); + } + else + { + SystemCoreClock = sysclk; + } +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Boot/stm32h7s7xx_flash.ld b/Boot/stm32h7s7xx_flash.ld new file mode 100644 index 0000000..7b72de4 --- /dev/null +++ b/Boot/stm32h7s7xx_flash.ld @@ -0,0 +1,258 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** @brief : Linker script for STM32H7S7xx Device from STM32H7RS series +** 64Kbytes FLASH +** 456Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @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. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE +} +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x08000000; +__FLASH_SIZE = 0x00010000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x4FC00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + + } >RAM AT> FLASH + + /* Initialized TLS data section */ + .tdata : ALIGN(4) + { + *(.tdata .tdata.* .gnu.linkonce.td.*) + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + PROVIDE(__data_end = .); + PROVIDE(__tdata_end = .); + } >RAM AT> FLASH + + PROVIDE( __tdata_start = ADDR(.tdata) ); + PROVIDE( __tdata_size = __tdata_end - __tdata_start ); + + PROVIDE( __data_start = ADDR(.data) ); + PROVIDE( __data_size = __data_end - __data_start ); + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) ); + PROVIDE( __tdata_source_size = __tdata_source_end - __tdata_source ); + + PROVIDE( __data_source = LOADADDR(.data) ); + PROVIDE( __data_source_end = __tdata_source_end ); + PROVIDE( __data_source_size = __data_source_end - __data_source ); + + + /* Uninitialized data section into "RAM" Ram type memory */ + /* Uninitialized TLS data section */ + .tbss (NOLOAD) : ALIGN(4) + { + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.tbss .tbss.*) + . = ALIGN(4); + PROVIDE( __tbss_end = . ); + } >RAM + + PROVIDE( __tbss_start = ADDR(.tbss) ); + PROVIDE( __tbss_size = __tbss_end - __tbss_start ); + PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) ); + + PROVIDE( __tls_base = __tdata_start ); + PROVIDE( __tls_end = __tbss_end ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); + PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1) ); + PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); + PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) ); + + .bss (NOLOAD) : ALIGN(4) + { + /* This is used by the startup in order to initialize the .bss section */ + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + PROVIDE( __bss_end = .); + } >RAM + PROVIDE( __non_tls_bss_start = ADDR(.bss) ); + + PROVIDE( __bss_start = __tbss_start ); + PROVIDE( __bss_size = __bss_end - __bss_start ); + + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "DTCM" Ram type memory left */ + ._user_heap_stack (NOLOAD) : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a:* ( * ) + libm.a:* ( * ) + libgcc.a:* ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/Drivers/.DS_Store b/Drivers/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..10d0300a67822d3578bfba30a3247c004c25c7cf GIT binary patch literal 8196 zcmeHMTWl0n82AJ7;R^#P5S#6r_+LZt`t+89?*A1|A>LYo%9iIPBiY*X+ecMpl}EDXGZ^og5K=p7xByi zknJl}5dp31>WG+8GM) zc4pi(9JjIY6iOwf3l^5iWpcTESK@#@k#N&)-f2ze_HZsqp9V6;aXK?#=o2Znq|LV6 zv|;Hv&%w}iGTA$5SeiZ2YUeG@@q80PA&2Bpiq#xG9BXQ-kF4Jmo2ri--V|%Bk8EhV zeQGKsS4SJR^ra4(W0rkXtQY-v1}vJj{>O-)W0eW+0-eQ{Em}C`B zHfNh=uk9GFVOzsPu0H7&16`sT8gcBL+vWvJF_w4qKAmD21-+djQm86EThBNT;|%CI zhiEk3DDVj#U%V`Q!%ep|Y}mA|bw_v4Oa-f~x?ZVPM(7b(uCd?HbHiyTt6Q33jrLC% zntNcdU^qs`)RR_vOb=CJeQ2hll2z3#SJk0>#<(|cxc9NBEPJt5sy)HJAjm8&3~yD|D#?SCBO&GpNuv@|`^|JlH$zMl z^W3I1tAhoxx)AFY!p%yxI+V4?#%L){NXYI`!Ah1#KZ$?Pk6#5s`8={*yayfeQ1PFePzE6I7Z?V91*7nFTm$qcJtP+bt_ zqCDhi`~iV|G+rm3LG**secng_%J}}c64t;*+7FYkA8a@RkHax|6HdT;@Hw1<@8B2s z70$tV_zNX0K?SRE8P?!(T#XIbh%s!!t=NH`*o6rk!eQKldr`-G@F0$%g%dc1_v17k z!K3&DK8a7`Gk6SN!k6(Cd;>qikMR@y6u-dJcm}`5AMq#r8PDQx_y_)p=OrdBmsDwm zv`%V}HcBm0m((Nmils=!@*5F+v6uR2Ghxl-ik4I_ zT^8Y`wQ*a^g)9_lTg=pp^WRJQOG?E{dM_zvCF~5<+KRBUsm=;r8tm<|LEnPV;|E@-N{Gd<$pccQ}U&u^buJVjU&+W{l$w+)1h3jk|FG2PwHn zywu*0qi9fiyO_rUPU0ba5Ff&a@ezE~OYx_?6n_q%#~1KLJdUs8Yxp|8gYV)Ad>=og zr2hbwfdGMdi2#~ r>bMD)d&hC27ye;L> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#ifndef __SCB_DCACHE_LINE_SIZE +#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +#ifndef __SCB_ICACHE_LINE_SIZE +#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief I-Cache Invalidate by address + \details Invalidates I-Cache for the given address. + I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + I-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] isize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if ( isize > 0 ) { + int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_ICACHE_LINE_SIZE; + op_size -= __SCB_ICACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ + +#endif /* ARM_CACHEL1_ARMV7_H */ diff --git a/Drivers/CMSIS/Core/Include/cmsis_armcc.h b/Drivers/CMSIS/Core/Include/cmsis_armcc.h new file mode 100644 index 0000000..a2ad65f --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_armcc.h @@ -0,0 +1,888 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.3.2 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + /* __ARM_ARCH_8_1M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; + __ISB(); +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/Drivers/CMSIS/Core/Include/cmsis_armclang.h b/Drivers/CMSIS/Core/Include/cmsis_armclang.h new file mode 100644 index 0000000..74bc4a2 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_armclang.h @@ -0,0 +1,1503 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.4.3 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/Drivers/CMSIS/Core/Include/cmsis_armclang_ltm.h b/Drivers/CMSIS/Core/Include/cmsis_armclang_ltm.h new file mode 100644 index 0000000..6edd509 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_armclang_ltm.h @@ -0,0 +1,1928 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.5.3 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/Drivers/CMSIS/Core/Include/cmsis_compiler.h b/Drivers/CMSIS/Core/Include/cmsis_compiler.h new file mode 100644 index 0000000..21a2c71 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/Drivers/CMSIS/Core/Include/cmsis_gcc.h b/Drivers/CMSIS/Core/Include/cmsis_gcc.h new file mode 100644 index 0000000..045aaf1 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_gcc.h @@ -0,0 +1,2211 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.4.1 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL __StackSeal +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + } else { + result = __SXTB16(__ROR(op1, rotate)) ; + } + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate)); + } else { + result = __SXTAB16(op1, __ROR(op2, rotate)); + } + return result; +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +#define __PKHBT(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/Drivers/CMSIS/Core/Include/cmsis_iccarm.h b/Drivers/CMSIS/Core/Include/cmsis_iccarm.h new file mode 100644 index 0000000..407b94b --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_iccarm.h @@ -0,0 +1,1002 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.3.0 + * @date 14. April 2021 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2021 IAR Systems +// Copyright (c) 2017-2021 Arm Limited. All rights reserved. +// +// SPDX-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. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#undef __WEAK /* undo the definition from DLib_Defaults.h */ +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + +#ifndef __PROGRAM_START +#define __PROGRAM_START __iar_program_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP CSTACK$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT CSTACK$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __vector_table +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE @".intvec" +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL STACKSEAL$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __arm_wsr("CONTROL", control); + __iar_builtin_ISB(); +} + + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __arm_wsr("CONTROL_NS", control); + __iar_builtin_ISB(); +} + + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM volatile("RRX %0, %1" : "=r"(result) : "r" (value)); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + __iar_builtin_ISB(); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM volatile ("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM volatile ("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM volatile ("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM volatile ("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM volatile ("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM volatile ("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/Drivers/CMSIS/Core/Include/cmsis_version.h b/Drivers/CMSIS/Core/Include/cmsis_version.h new file mode 100644 index 0000000..6addcbb --- /dev/null +++ b/Drivers/CMSIS/Core/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.5 + * @date 02. February 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/Drivers/CMSIS/Core/Include/core_armv81mml.h b/Drivers/CMSIS/Core/Include/core_armv81mml.h new file mode 100644 index 0000000..7408a58 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_armv81mml.h @@ -0,0 +1,4228 @@ +/**************************************************************************//** + * @file core_armv81mml.h + * @brief CMSIS Armv8.1-M Mainline Core Peripheral Access Layer Header File + * @version V1.4.2 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_ARMV81MML_H_GENERIC +#define __CORE_ARMV81MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMV81MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS ARMV81MML definitions */ +#define __ARMv81MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv81MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv81MML_CMSIS_VERSION ((__ARMv81MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv81MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +#if defined ( __CC_ARM ) + #error Legacy Arm Compiler does not support Armv8.1-M target architecture. +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV81MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV81MML_H_DEPENDANT +#define __CORE_ARMV81MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv81MML_REV + #define __ARMv81MML_REV 0x0000U + #warning "__ARMv81MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #if __FPU_PRESENT != 0U + #ifndef __FPU_DP + #define __FPU_DP 0U + #warning "__FPU_DP not defined in device header file; using default!" + #endif + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __PMU_PRESENT + #define __PMU_PRESENT 0U + #warning "__PMU_PRESENT not defined in device header file; using default!" + #endif + + #if __PMU_PRESENT != 0U + #ifndef __PMU_NUM_EVENTCNT + #define __PMU_NUM_EVENTCNT 2U + #warning "__PMU_NUM_EVENTCNT not defined in device header file; using default!" + #elif (__PMU_NUM_EVENTCNT > 31 || __PMU_NUM_EVENTCNT < 2) + #error "__PMU_NUM_EVENTCNT is out of range in device header file!" */ + #endif + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv81MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + __IOM uint32_t RFSR; /*!< Offset: 0x204 (R/W) RAS Fault Status Register */ + uint32_t RESERVED4[14U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_IESB_Pos 5U /*!< SCB AIRCR: Implicit ESB Enable Position */ +#define SCB_AIRCR_IESB_Msk (1UL << SCB_AIRCR_IESB_Pos) /*!< SCB AIRCR: Implicit ESB Enable Mask */ + +#define SCB_AIRCR_DIT_Pos 4U /*!< SCB AIRCR: Data Independent Timing Position */ +#define SCB_AIRCR_DIT_Msk (1UL << SCB_AIRCR_DIT_Pos) /*!< SCB AIRCR: Data Independent Timing Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_TRD_Pos 20U /*!< SCB CCR: TRD Position */ +#define SCB_CCR_TRD_Msk (1UL << SCB_CCR_TRD_Pos) /*!< SCB CCR: TRD Mask */ + +#define SCB_CCR_LOB_Pos 19U /*!< SCB CCR: LOB Position */ +#define SCB_CCR_LOB_Msk (1UL << SCB_CCR_LOB_Pos) /*!< SCB CCR: LOB Mask */ + +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_PMU_Pos 5U /*!< SCB DFSR: PMU Position */ +#define SCB_DFSR_PMU_Msk (1UL << SCB_DFSR_PMU_Pos) /*!< SCB DFSR: PMU Mask */ + +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CP7_Pos 7U /*!< SCB NSACR: CP7 Position */ +#define SCB_NSACR_CP7_Msk (1UL << SCB_NSACR_CP7_Pos) /*!< SCB NSACR: CP7 Mask */ + +#define SCB_NSACR_CP6_Pos 6U /*!< SCB NSACR: CP6 Position */ +#define SCB_NSACR_CP6_Msk (1UL << SCB_NSACR_CP6_Pos) /*!< SCB NSACR: CP6 Mask */ + +#define SCB_NSACR_CP5_Pos 5U /*!< SCB NSACR: CP5 Position */ +#define SCB_NSACR_CP5_Msk (1UL << SCB_NSACR_CP5_Pos) /*!< SCB NSACR: CP5 Mask */ + +#define SCB_NSACR_CP4_Pos 4U /*!< SCB NSACR: CP4 Position */ +#define SCB_NSACR_CP4_Msk (1UL << SCB_NSACR_CP4_Pos) /*!< SCB NSACR: CP4 Mask */ + +#define SCB_NSACR_CP3_Pos 3U /*!< SCB NSACR: CP3 Position */ +#define SCB_NSACR_CP3_Msk (1UL << SCB_NSACR_CP3_Pos) /*!< SCB NSACR: CP3 Mask */ + +#define SCB_NSACR_CP2_Pos 2U /*!< SCB NSACR: CP2 Position */ +#define SCB_NSACR_CP2_Msk (1UL << SCB_NSACR_CP2_Pos) /*!< SCB NSACR: CP2 Mask */ + +#define SCB_NSACR_CP1_Pos 1U /*!< SCB NSACR: CP1 Position */ +#define SCB_NSACR_CP1_Msk (1UL << SCB_NSACR_CP1_Pos) /*!< SCB NSACR: CP1 Mask */ + +#define SCB_NSACR_CP0_Pos 0U /*!< SCB NSACR: CP0 Position */ +#define SCB_NSACR_CP0_Msk (1UL /*<< SCB_NSACR_CP0_Pos*/) /*!< SCB NSACR: CP0 Mask */ + +/* SCB Debug Feature Register 0 Definitions */ +#define SCB_ID_DFR_UDE_Pos 28U /*!< SCB ID_DFR: UDE Position */ +#define SCB_ID_DFR_UDE_Msk (0xFUL << SCB_ID_DFR_UDE_Pos) /*!< SCB ID_DFR: UDE Mask */ + +#define SCB_ID_DFR_MProfDbg_Pos 20U /*!< SCB ID_DFR: MProfDbg Position */ +#define SCB_ID_DFR_MProfDbg_Msk (0xFUL << SCB_ID_DFR_MProfDbg_Pos) /*!< SCB ID_DFR: MProfDbg Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB RAS Fault Status Register Definitions */ +#define SCB_RFSR_V_Pos 31U /*!< SCB RFSR: V Position */ +#define SCB_RFSR_V_Msk (1UL << SCB_RFSR_V_Pos) /*!< SCB RFSR: V Mask */ + +#define SCB_RFSR_IS_Pos 16U /*!< SCB RFSR: IS Position */ +#define SCB_RFSR_IS_Msk (0x7FFFUL << SCB_RFSR_IS_Pos) /*!< SCB RFSR: IS Mask */ + +#define SCB_RFSR_UET_Pos 0U /*!< SCB RFSR: UET Position */ +#define SCB_RFSR_UET_Msk (3UL /*<< SCB_RFSR_UET_Pos*/) /*!< SCB RFSR: UET Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[3U]; + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) ITM Device Type Register */ + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFmt_Pos 0U /*!< TPI FFCR: EnFmt Position */ +#define TPI_FFCR_EnFmt_Msk (0x3UL << /*TPI_FFCR_EnFmt_Pos*/) /*!< TPI FFCR: EnFmt Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_PMU Performance Monitoring Unit (PMU) + \brief Type definitions for the Performance Monitoring Unit (PMU) + @{ + */ + +/** + \brief Structure type to access the Performance Monitoring Unit (PMU). + */ +typedef struct +{ + __IOM uint32_t EVCNTR[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x0 (R/W) PMU Event Counter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED0[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCNTR; /*!< Offset: 0x7C (R/W) PMU Cycle Counter Register */ + uint32_t RESERVED1[224]; + __IOM uint32_t EVTYPER[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x400 (R/W) PMU Event Type and Filter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED2[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCFILTR; /*!< Offset: 0x47C (R/W) PMU Cycle Counter Filter Register */ + uint32_t RESERVED3[480]; + __IOM uint32_t CNTENSET; /*!< Offset: 0xC00 (R/W) PMU Count Enable Set Register */ + uint32_t RESERVED4[7]; + __IOM uint32_t CNTENCLR; /*!< Offset: 0xC20 (R/W) PMU Count Enable Clear Register */ + uint32_t RESERVED5[7]; + __IOM uint32_t INTENSET; /*!< Offset: 0xC40 (R/W) PMU Interrupt Enable Set Register */ + uint32_t RESERVED6[7]; + __IOM uint32_t INTENCLR; /*!< Offset: 0xC60 (R/W) PMU Interrupt Enable Clear Register */ + uint32_t RESERVED7[7]; + __IOM uint32_t OVSCLR; /*!< Offset: 0xC80 (R/W) PMU Overflow Flag Status Clear Register */ + uint32_t RESERVED8[7]; + __IOM uint32_t SWINC; /*!< Offset: 0xCA0 (R/W) PMU Software Increment Register */ + uint32_t RESERVED9[7]; + __IOM uint32_t OVSSET; /*!< Offset: 0xCC0 (R/W) PMU Overflow Flag Status Set Register */ + uint32_t RESERVED10[79]; + __IOM uint32_t TYPE; /*!< Offset: 0xE00 (R/W) PMU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0xE04 (R/W) PMU Control Register */ + uint32_t RESERVED11[108]; + __IOM uint32_t AUTHSTATUS; /*!< Offset: 0xFB8 (R/W) PMU Authentication Status Register */ + __IOM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/W) PMU Device Architecture Register */ + uint32_t RESERVED12[3]; + __IOM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/W) PMU Device Type Register */ + __IOM uint32_t PIDR4; /*!< Offset: 0xFD0 (R/W) PMU Peripheral Identification Register 4 */ + uint32_t RESERVED13[3]; + __IOM uint32_t PIDR0; /*!< Offset: 0xFE0 (R/W) PMU Peripheral Identification Register 0 */ + __IOM uint32_t PIDR1; /*!< Offset: 0xFE4 (R/W) PMU Peripheral Identification Register 1 */ + __IOM uint32_t PIDR2; /*!< Offset: 0xFE8 (R/W) PMU Peripheral Identification Register 2 */ + __IOM uint32_t PIDR3; /*!< Offset: 0xFEC (R/W) PMU Peripheral Identification Register 3 */ + __IOM uint32_t CIDR0; /*!< Offset: 0xFF0 (R/W) PMU Component Identification Register 0 */ + __IOM uint32_t CIDR1; /*!< Offset: 0xFF4 (R/W) PMU Component Identification Register 1 */ + __IOM uint32_t CIDR2; /*!< Offset: 0xFF8 (R/W) PMU Component Identification Register 2 */ + __IOM uint32_t CIDR3; /*!< Offset: 0xFFC (R/W) PMU Component Identification Register 3 */ +} PMU_Type; + +/** \brief PMU Event Counter Registers (0-30) Definitions */ + +#define PMU_EVCNTR_CNT_Pos 0U /*!< PMU EVCNTR: Counter Position */ +#define PMU_EVCNTR_CNT_Msk (0xFFFFUL /*<< PMU_EVCNTRx_CNT_Pos*/) /*!< PMU EVCNTR: Counter Mask */ + +/** \brief PMU Event Type and Filter Registers (0-30) Definitions */ + +#define PMU_EVTYPER_EVENTTOCNT_Pos 0U /*!< PMU EVTYPER: Event to Count Position */ +#define PMU_EVTYPER_EVENTTOCNT_Msk (0xFFFFUL /*<< EVTYPERx_EVENTTOCNT_Pos*/) /*!< PMU EVTYPER: Event to Count Mask */ + +/** \brief PMU Count Enable Set Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENSET: Event Counter 0 Enable Set Position */ +#define PMU_CNTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENSET_CNT0_ENABLE_Pos*/) /*!< PMU CNTENSET: Event Counter 0 Enable Set Mask */ + +#define PMU_CNTENSET_CNT1_ENABLE_Pos 1U /*!< PMU CNTENSET: Event Counter 1 Enable Set Position */ +#define PMU_CNTENSET_CNT1_ENABLE_Msk (1UL << PMU_CNTENSET_CNT1_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 1 Enable Set Mask */ + +#define PMU_CNTENSET_CNT2_ENABLE_Pos 2U /*!< PMU CNTENSET: Event Counter 2 Enable Set Position */ +#define PMU_CNTENSET_CNT2_ENABLE_Msk (1UL << PMU_CNTENSET_CNT2_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 2 Enable Set Mask */ + +#define PMU_CNTENSET_CNT3_ENABLE_Pos 3U /*!< PMU CNTENSET: Event Counter 3 Enable Set Position */ +#define PMU_CNTENSET_CNT3_ENABLE_Msk (1UL << PMU_CNTENSET_CNT3_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 3 Enable Set Mask */ + +#define PMU_CNTENSET_CNT4_ENABLE_Pos 4U /*!< PMU CNTENSET: Event Counter 4 Enable Set Position */ +#define PMU_CNTENSET_CNT4_ENABLE_Msk (1UL << PMU_CNTENSET_CNT4_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 4 Enable Set Mask */ + +#define PMU_CNTENSET_CNT5_ENABLE_Pos 5U /*!< PMU CNTENSET: Event Counter 5 Enable Set Position */ +#define PMU_CNTENSET_CNT5_ENABLE_Msk (1UL << PMU_CNTENSET_CNT5_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 5 Enable Set Mask */ + +#define PMU_CNTENSET_CNT6_ENABLE_Pos 6U /*!< PMU CNTENSET: Event Counter 6 Enable Set Position */ +#define PMU_CNTENSET_CNT6_ENABLE_Msk (1UL << PMU_CNTENSET_CNT6_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 6 Enable Set Mask */ + +#define PMU_CNTENSET_CNT7_ENABLE_Pos 7U /*!< PMU CNTENSET: Event Counter 7 Enable Set Position */ +#define PMU_CNTENSET_CNT7_ENABLE_Msk (1UL << PMU_CNTENSET_CNT7_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 7 Enable Set Mask */ + +#define PMU_CNTENSET_CNT8_ENABLE_Pos 8U /*!< PMU CNTENSET: Event Counter 8 Enable Set Position */ +#define PMU_CNTENSET_CNT8_ENABLE_Msk (1UL << PMU_CNTENSET_CNT8_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 8 Enable Set Mask */ + +#define PMU_CNTENSET_CNT9_ENABLE_Pos 9U /*!< PMU CNTENSET: Event Counter 9 Enable Set Position */ +#define PMU_CNTENSET_CNT9_ENABLE_Msk (1UL << PMU_CNTENSET_CNT9_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 9 Enable Set Mask */ + +#define PMU_CNTENSET_CNT10_ENABLE_Pos 10U /*!< PMU CNTENSET: Event Counter 10 Enable Set Position */ +#define PMU_CNTENSET_CNT10_ENABLE_Msk (1UL << PMU_CNTENSET_CNT10_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 10 Enable Set Mask */ + +#define PMU_CNTENSET_CNT11_ENABLE_Pos 11U /*!< PMU CNTENSET: Event Counter 11 Enable Set Position */ +#define PMU_CNTENSET_CNT11_ENABLE_Msk (1UL << PMU_CNTENSET_CNT11_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 11 Enable Set Mask */ + +#define PMU_CNTENSET_CNT12_ENABLE_Pos 12U /*!< PMU CNTENSET: Event Counter 12 Enable Set Position */ +#define PMU_CNTENSET_CNT12_ENABLE_Msk (1UL << PMU_CNTENSET_CNT12_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 12 Enable Set Mask */ + +#define PMU_CNTENSET_CNT13_ENABLE_Pos 13U /*!< PMU CNTENSET: Event Counter 13 Enable Set Position */ +#define PMU_CNTENSET_CNT13_ENABLE_Msk (1UL << PMU_CNTENSET_CNT13_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 13 Enable Set Mask */ + +#define PMU_CNTENSET_CNT14_ENABLE_Pos 14U /*!< PMU CNTENSET: Event Counter 14 Enable Set Position */ +#define PMU_CNTENSET_CNT14_ENABLE_Msk (1UL << PMU_CNTENSET_CNT14_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 14 Enable Set Mask */ + +#define PMU_CNTENSET_CNT15_ENABLE_Pos 15U /*!< PMU CNTENSET: Event Counter 15 Enable Set Position */ +#define PMU_CNTENSET_CNT15_ENABLE_Msk (1UL << PMU_CNTENSET_CNT15_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 15 Enable Set Mask */ + +#define PMU_CNTENSET_CNT16_ENABLE_Pos 16U /*!< PMU CNTENSET: Event Counter 16 Enable Set Position */ +#define PMU_CNTENSET_CNT16_ENABLE_Msk (1UL << PMU_CNTENSET_CNT16_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 16 Enable Set Mask */ + +#define PMU_CNTENSET_CNT17_ENABLE_Pos 17U /*!< PMU CNTENSET: Event Counter 17 Enable Set Position */ +#define PMU_CNTENSET_CNT17_ENABLE_Msk (1UL << PMU_CNTENSET_CNT17_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 17 Enable Set Mask */ + +#define PMU_CNTENSET_CNT18_ENABLE_Pos 18U /*!< PMU CNTENSET: Event Counter 18 Enable Set Position */ +#define PMU_CNTENSET_CNT18_ENABLE_Msk (1UL << PMU_CNTENSET_CNT18_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 18 Enable Set Mask */ + +#define PMU_CNTENSET_CNT19_ENABLE_Pos 19U /*!< PMU CNTENSET: Event Counter 19 Enable Set Position */ +#define PMU_CNTENSET_CNT19_ENABLE_Msk (1UL << PMU_CNTENSET_CNT19_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 19 Enable Set Mask */ + +#define PMU_CNTENSET_CNT20_ENABLE_Pos 20U /*!< PMU CNTENSET: Event Counter 20 Enable Set Position */ +#define PMU_CNTENSET_CNT20_ENABLE_Msk (1UL << PMU_CNTENSET_CNT20_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 20 Enable Set Mask */ + +#define PMU_CNTENSET_CNT21_ENABLE_Pos 21U /*!< PMU CNTENSET: Event Counter 21 Enable Set Position */ +#define PMU_CNTENSET_CNT21_ENABLE_Msk (1UL << PMU_CNTENSET_CNT21_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 21 Enable Set Mask */ + +#define PMU_CNTENSET_CNT22_ENABLE_Pos 22U /*!< PMU CNTENSET: Event Counter 22 Enable Set Position */ +#define PMU_CNTENSET_CNT22_ENABLE_Msk (1UL << PMU_CNTENSET_CNT22_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 22 Enable Set Mask */ + +#define PMU_CNTENSET_CNT23_ENABLE_Pos 23U /*!< PMU CNTENSET: Event Counter 23 Enable Set Position */ +#define PMU_CNTENSET_CNT23_ENABLE_Msk (1UL << PMU_CNTENSET_CNT23_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 23 Enable Set Mask */ + +#define PMU_CNTENSET_CNT24_ENABLE_Pos 24U /*!< PMU CNTENSET: Event Counter 24 Enable Set Position */ +#define PMU_CNTENSET_CNT24_ENABLE_Msk (1UL << PMU_CNTENSET_CNT24_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 24 Enable Set Mask */ + +#define PMU_CNTENSET_CNT25_ENABLE_Pos 25U /*!< PMU CNTENSET: Event Counter 25 Enable Set Position */ +#define PMU_CNTENSET_CNT25_ENABLE_Msk (1UL << PMU_CNTENSET_CNT25_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 25 Enable Set Mask */ + +#define PMU_CNTENSET_CNT26_ENABLE_Pos 26U /*!< PMU CNTENSET: Event Counter 26 Enable Set Position */ +#define PMU_CNTENSET_CNT26_ENABLE_Msk (1UL << PMU_CNTENSET_CNT26_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 26 Enable Set Mask */ + +#define PMU_CNTENSET_CNT27_ENABLE_Pos 27U /*!< PMU CNTENSET: Event Counter 27 Enable Set Position */ +#define PMU_CNTENSET_CNT27_ENABLE_Msk (1UL << PMU_CNTENSET_CNT27_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 27 Enable Set Mask */ + +#define PMU_CNTENSET_CNT28_ENABLE_Pos 28U /*!< PMU CNTENSET: Event Counter 28 Enable Set Position */ +#define PMU_CNTENSET_CNT28_ENABLE_Msk (1UL << PMU_CNTENSET_CNT28_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 28 Enable Set Mask */ + +#define PMU_CNTENSET_CNT29_ENABLE_Pos 29U /*!< PMU CNTENSET: Event Counter 29 Enable Set Position */ +#define PMU_CNTENSET_CNT29_ENABLE_Msk (1UL << PMU_CNTENSET_CNT29_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 29 Enable Set Mask */ + +#define PMU_CNTENSET_CNT30_ENABLE_Pos 30U /*!< PMU CNTENSET: Event Counter 30 Enable Set Position */ +#define PMU_CNTENSET_CNT30_ENABLE_Msk (1UL << PMU_CNTENSET_CNT30_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 30 Enable Set Mask */ + +#define PMU_CNTENSET_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENSET: Cycle Counter Enable Set Position */ +#define PMU_CNTENSET_CCNTR_ENABLE_Msk (1UL << PMU_CNTENSET_CCNTR_ENABLE_Pos) /*!< PMU CNTENSET: Cycle Counter Enable Set Mask */ + +/** \brief PMU Count Enable Clear Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Position */ +#define PMU_CNTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU CNTENCLR: Event Counter 1 Enable Clear Position */ +#define PMU_CNTENCLR_CNT1_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT1_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 1 Enable Clear */ + +#define PMU_CNTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Position */ +#define PMU_CNTENCLR_CNT2_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT2_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Position */ +#define PMU_CNTENCLR_CNT3_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT3_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Position */ +#define PMU_CNTENCLR_CNT4_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT4_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Position */ +#define PMU_CNTENCLR_CNT5_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT5_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Position */ +#define PMU_CNTENCLR_CNT6_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT6_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Position */ +#define PMU_CNTENCLR_CNT7_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT7_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Position */ +#define PMU_CNTENCLR_CNT8_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT8_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Position */ +#define PMU_CNTENCLR_CNT9_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT9_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Position */ +#define PMU_CNTENCLR_CNT10_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT10_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Position */ +#define PMU_CNTENCLR_CNT11_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT11_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Position */ +#define PMU_CNTENCLR_CNT12_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT12_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Position */ +#define PMU_CNTENCLR_CNT13_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT13_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Position */ +#define PMU_CNTENCLR_CNT14_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT14_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Position */ +#define PMU_CNTENCLR_CNT15_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT15_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Position */ +#define PMU_CNTENCLR_CNT16_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT16_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Position */ +#define PMU_CNTENCLR_CNT17_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT17_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Position */ +#define PMU_CNTENCLR_CNT18_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT18_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Position */ +#define PMU_CNTENCLR_CNT19_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT19_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Position */ +#define PMU_CNTENCLR_CNT20_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT20_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Position */ +#define PMU_CNTENCLR_CNT21_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT21_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Position */ +#define PMU_CNTENCLR_CNT22_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT22_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Position */ +#define PMU_CNTENCLR_CNT23_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT23_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Position */ +#define PMU_CNTENCLR_CNT24_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT24_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Position */ +#define PMU_CNTENCLR_CNT25_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT25_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Position */ +#define PMU_CNTENCLR_CNT26_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT26_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Position */ +#define PMU_CNTENCLR_CNT27_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT27_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Position */ +#define PMU_CNTENCLR_CNT28_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT28_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Position */ +#define PMU_CNTENCLR_CNT29_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT29_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Position */ +#define PMU_CNTENCLR_CNT30_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT30_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Mask */ + +#define PMU_CNTENCLR_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENCLR: Cycle Counter Enable Clear Position */ +#define PMU_CNTENCLR_CCNTR_ENABLE_Msk (1UL << PMU_CNTENCLR_CCNTR_ENABLE_Pos) /*!< PMU CNTENCLR: Cycle Counter Enable Clear Mask */ + +/** \brief PMU Interrupt Enable Set Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENSET_CNT0_ENABLE_Pos*/) /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT1_ENABLE_Pos 1U /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT1_ENABLE_Msk (1UL << PMU_INTENSET_CNT1_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT2_ENABLE_Pos 2U /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT2_ENABLE_Msk (1UL << PMU_INTENSET_CNT2_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT3_ENABLE_Pos 3U /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT3_ENABLE_Msk (1UL << PMU_INTENSET_CNT3_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT4_ENABLE_Pos 4U /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT4_ENABLE_Msk (1UL << PMU_INTENSET_CNT4_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT5_ENABLE_Pos 5U /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT5_ENABLE_Msk (1UL << PMU_INTENSET_CNT5_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT6_ENABLE_Pos 6U /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT6_ENABLE_Msk (1UL << PMU_INTENSET_CNT6_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT7_ENABLE_Pos 7U /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT7_ENABLE_Msk (1UL << PMU_INTENSET_CNT7_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT8_ENABLE_Pos 8U /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT8_ENABLE_Msk (1UL << PMU_INTENSET_CNT8_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT9_ENABLE_Pos 9U /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT9_ENABLE_Msk (1UL << PMU_INTENSET_CNT9_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT10_ENABLE_Pos 10U /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT10_ENABLE_Msk (1UL << PMU_INTENSET_CNT10_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT11_ENABLE_Pos 11U /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT11_ENABLE_Msk (1UL << PMU_INTENSET_CNT11_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT12_ENABLE_Pos 12U /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT12_ENABLE_Msk (1UL << PMU_INTENSET_CNT12_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT13_ENABLE_Pos 13U /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT13_ENABLE_Msk (1UL << PMU_INTENSET_CNT13_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT14_ENABLE_Pos 14U /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT14_ENABLE_Msk (1UL << PMU_INTENSET_CNT14_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT15_ENABLE_Pos 15U /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT15_ENABLE_Msk (1UL << PMU_INTENSET_CNT15_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT16_ENABLE_Pos 16U /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT16_ENABLE_Msk (1UL << PMU_INTENSET_CNT16_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT17_ENABLE_Pos 17U /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT17_ENABLE_Msk (1UL << PMU_INTENSET_CNT17_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT18_ENABLE_Pos 18U /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT18_ENABLE_Msk (1UL << PMU_INTENSET_CNT18_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT19_ENABLE_Pos 19U /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT19_ENABLE_Msk (1UL << PMU_INTENSET_CNT19_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT20_ENABLE_Pos 20U /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT20_ENABLE_Msk (1UL << PMU_INTENSET_CNT20_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT21_ENABLE_Pos 21U /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT21_ENABLE_Msk (1UL << PMU_INTENSET_CNT21_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT22_ENABLE_Pos 22U /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT22_ENABLE_Msk (1UL << PMU_INTENSET_CNT22_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT23_ENABLE_Pos 23U /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT23_ENABLE_Msk (1UL << PMU_INTENSET_CNT23_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT24_ENABLE_Pos 24U /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT24_ENABLE_Msk (1UL << PMU_INTENSET_CNT24_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT25_ENABLE_Pos 25U /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT25_ENABLE_Msk (1UL << PMU_INTENSET_CNT25_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT26_ENABLE_Pos 26U /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT26_ENABLE_Msk (1UL << PMU_INTENSET_CNT26_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT27_ENABLE_Pos 27U /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT27_ENABLE_Msk (1UL << PMU_INTENSET_CNT27_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT28_ENABLE_Pos 28U /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT28_ENABLE_Msk (1UL << PMU_INTENSET_CNT28_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT29_ENABLE_Pos 29U /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT29_ENABLE_Msk (1UL << PMU_INTENSET_CNT29_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT30_ENABLE_Pos 30U /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT30_ENABLE_Msk (1UL << PMU_INTENSET_CNT30_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Position */ +#define PMU_INTENSET_CCYCNT_ENABLE_Msk (1UL << PMU_INTENSET_CYCCNT_ENABLE_Pos) /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Mask */ + +/** \brief PMU Interrupt Enable Clear Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT1_ENABLE_Msk (1UL << PMU_INTENCLR_CNT1_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear */ + +#define PMU_INTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT2_ENABLE_Msk (1UL << PMU_INTENCLR_CNT2_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT3_ENABLE_Msk (1UL << PMU_INTENCLR_CNT3_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT4_ENABLE_Msk (1UL << PMU_INTENCLR_CNT4_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT5_ENABLE_Msk (1UL << PMU_INTENCLR_CNT5_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT6_ENABLE_Msk (1UL << PMU_INTENCLR_CNT6_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT7_ENABLE_Msk (1UL << PMU_INTENCLR_CNT7_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT8_ENABLE_Msk (1UL << PMU_INTENCLR_CNT8_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT9_ENABLE_Msk (1UL << PMU_INTENCLR_CNT9_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT10_ENABLE_Msk (1UL << PMU_INTENCLR_CNT10_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT11_ENABLE_Msk (1UL << PMU_INTENCLR_CNT11_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT12_ENABLE_Msk (1UL << PMU_INTENCLR_CNT12_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT13_ENABLE_Msk (1UL << PMU_INTENCLR_CNT13_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT14_ENABLE_Msk (1UL << PMU_INTENCLR_CNT14_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT15_ENABLE_Msk (1UL << PMU_INTENCLR_CNT15_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT16_ENABLE_Msk (1UL << PMU_INTENCLR_CNT16_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT17_ENABLE_Msk (1UL << PMU_INTENCLR_CNT17_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT18_ENABLE_Msk (1UL << PMU_INTENCLR_CNT18_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT19_ENABLE_Msk (1UL << PMU_INTENCLR_CNT19_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT20_ENABLE_Msk (1UL << PMU_INTENCLR_CNT20_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT21_ENABLE_Msk (1UL << PMU_INTENCLR_CNT21_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT22_ENABLE_Msk (1UL << PMU_INTENCLR_CNT22_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT23_ENABLE_Msk (1UL << PMU_INTENCLR_CNT23_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT24_ENABLE_Msk (1UL << PMU_INTENCLR_CNT24_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT25_ENABLE_Msk (1UL << PMU_INTENCLR_CNT25_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT26_ENABLE_Msk (1UL << PMU_INTENCLR_CNT26_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT27_ENABLE_Msk (1UL << PMU_INTENCLR_CNT27_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT28_ENABLE_Msk (1UL << PMU_INTENCLR_CNT28_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT29_ENABLE_Msk (1UL << PMU_INTENCLR_CNT29_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT30_ENABLE_Msk (1UL << PMU_INTENCLR_CNT30_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CYCCNT_ENABLE_Msk (1UL << PMU_INTENCLR_CYCCNT_ENABLE_Pos) /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Mask */ + +/** \brief PMU Overflow Flag Status Set Register Definitions */ + +#define PMU_OVSSET_CNT0_STATUS_Pos 0U /*!< PMU OVSSET: Event Counter 0 Overflow Set Position */ +#define PMU_OVSSET_CNT0_STATUS_Msk (1UL /*<< PMU_OVSSET_CNT0_STATUS_Pos*/) /*!< PMU OVSSET: Event Counter 0 Overflow Set Mask */ + +#define PMU_OVSSET_CNT1_STATUS_Pos 1U /*!< PMU OVSSET: Event Counter 1 Overflow Set Position */ +#define PMU_OVSSET_CNT1_STATUS_Msk (1UL << PMU_OVSSET_CNT1_STATUS_Pos) /*!< PMU OVSSET: Event Counter 1 Overflow Set Mask */ + +#define PMU_OVSSET_CNT2_STATUS_Pos 2U /*!< PMU OVSSET: Event Counter 2 Overflow Set Position */ +#define PMU_OVSSET_CNT2_STATUS_Msk (1UL << PMU_OVSSET_CNT2_STATUS_Pos) /*!< PMU OVSSET: Event Counter 2 Overflow Set Mask */ + +#define PMU_OVSSET_CNT3_STATUS_Pos 3U /*!< PMU OVSSET: Event Counter 3 Overflow Set Position */ +#define PMU_OVSSET_CNT3_STATUS_Msk (1UL << PMU_OVSSET_CNT3_STATUS_Pos) /*!< PMU OVSSET: Event Counter 3 Overflow Set Mask */ + +#define PMU_OVSSET_CNT4_STATUS_Pos 4U /*!< PMU OVSSET: Event Counter 4 Overflow Set Position */ +#define PMU_OVSSET_CNT4_STATUS_Msk (1UL << PMU_OVSSET_CNT4_STATUS_Pos) /*!< PMU OVSSET: Event Counter 4 Overflow Set Mask */ + +#define PMU_OVSSET_CNT5_STATUS_Pos 5U /*!< PMU OVSSET: Event Counter 5 Overflow Set Position */ +#define PMU_OVSSET_CNT5_STATUS_Msk (1UL << PMU_OVSSET_CNT5_STATUS_Pos) /*!< PMU OVSSET: Event Counter 5 Overflow Set Mask */ + +#define PMU_OVSSET_CNT6_STATUS_Pos 6U /*!< PMU OVSSET: Event Counter 6 Overflow Set Position */ +#define PMU_OVSSET_CNT6_STATUS_Msk (1UL << PMU_OVSSET_CNT6_STATUS_Pos) /*!< PMU OVSSET: Event Counter 6 Overflow Set Mask */ + +#define PMU_OVSSET_CNT7_STATUS_Pos 7U /*!< PMU OVSSET: Event Counter 7 Overflow Set Position */ +#define PMU_OVSSET_CNT7_STATUS_Msk (1UL << PMU_OVSSET_CNT7_STATUS_Pos) /*!< PMU OVSSET: Event Counter 7 Overflow Set Mask */ + +#define PMU_OVSSET_CNT8_STATUS_Pos 8U /*!< PMU OVSSET: Event Counter 8 Overflow Set Position */ +#define PMU_OVSSET_CNT8_STATUS_Msk (1UL << PMU_OVSSET_CNT8_STATUS_Pos) /*!< PMU OVSSET: Event Counter 8 Overflow Set Mask */ + +#define PMU_OVSSET_CNT9_STATUS_Pos 9U /*!< PMU OVSSET: Event Counter 9 Overflow Set Position */ +#define PMU_OVSSET_CNT9_STATUS_Msk (1UL << PMU_OVSSET_CNT9_STATUS_Pos) /*!< PMU OVSSET: Event Counter 9 Overflow Set Mask */ + +#define PMU_OVSSET_CNT10_STATUS_Pos 10U /*!< PMU OVSSET: Event Counter 10 Overflow Set Position */ +#define PMU_OVSSET_CNT10_STATUS_Msk (1UL << PMU_OVSSET_CNT10_STATUS_Pos) /*!< PMU OVSSET: Event Counter 10 Overflow Set Mask */ + +#define PMU_OVSSET_CNT11_STATUS_Pos 11U /*!< PMU OVSSET: Event Counter 11 Overflow Set Position */ +#define PMU_OVSSET_CNT11_STATUS_Msk (1UL << PMU_OVSSET_CNT11_STATUS_Pos) /*!< PMU OVSSET: Event Counter 11 Overflow Set Mask */ + +#define PMU_OVSSET_CNT12_STATUS_Pos 12U /*!< PMU OVSSET: Event Counter 12 Overflow Set Position */ +#define PMU_OVSSET_CNT12_STATUS_Msk (1UL << PMU_OVSSET_CNT12_STATUS_Pos) /*!< PMU OVSSET: Event Counter 12 Overflow Set Mask */ + +#define PMU_OVSSET_CNT13_STATUS_Pos 13U /*!< PMU OVSSET: Event Counter 13 Overflow Set Position */ +#define PMU_OVSSET_CNT13_STATUS_Msk (1UL << PMU_OVSSET_CNT13_STATUS_Pos) /*!< PMU OVSSET: Event Counter 13 Overflow Set Mask */ + +#define PMU_OVSSET_CNT14_STATUS_Pos 14U /*!< PMU OVSSET: Event Counter 14 Overflow Set Position */ +#define PMU_OVSSET_CNT14_STATUS_Msk (1UL << PMU_OVSSET_CNT14_STATUS_Pos) /*!< PMU OVSSET: Event Counter 14 Overflow Set Mask */ + +#define PMU_OVSSET_CNT15_STATUS_Pos 15U /*!< PMU OVSSET: Event Counter 15 Overflow Set Position */ +#define PMU_OVSSET_CNT15_STATUS_Msk (1UL << PMU_OVSSET_CNT15_STATUS_Pos) /*!< PMU OVSSET: Event Counter 15 Overflow Set Mask */ + +#define PMU_OVSSET_CNT16_STATUS_Pos 16U /*!< PMU OVSSET: Event Counter 16 Overflow Set Position */ +#define PMU_OVSSET_CNT16_STATUS_Msk (1UL << PMU_OVSSET_CNT16_STATUS_Pos) /*!< PMU OVSSET: Event Counter 16 Overflow Set Mask */ + +#define PMU_OVSSET_CNT17_STATUS_Pos 17U /*!< PMU OVSSET: Event Counter 17 Overflow Set Position */ +#define PMU_OVSSET_CNT17_STATUS_Msk (1UL << PMU_OVSSET_CNT17_STATUS_Pos) /*!< PMU OVSSET: Event Counter 17 Overflow Set Mask */ + +#define PMU_OVSSET_CNT18_STATUS_Pos 18U /*!< PMU OVSSET: Event Counter 18 Overflow Set Position */ +#define PMU_OVSSET_CNT18_STATUS_Msk (1UL << PMU_OVSSET_CNT18_STATUS_Pos) /*!< PMU OVSSET: Event Counter 18 Overflow Set Mask */ + +#define PMU_OVSSET_CNT19_STATUS_Pos 19U /*!< PMU OVSSET: Event Counter 19 Overflow Set Position */ +#define PMU_OVSSET_CNT19_STATUS_Msk (1UL << PMU_OVSSET_CNT19_STATUS_Pos) /*!< PMU OVSSET: Event Counter 19 Overflow Set Mask */ + +#define PMU_OVSSET_CNT20_STATUS_Pos 20U /*!< PMU OVSSET: Event Counter 20 Overflow Set Position */ +#define PMU_OVSSET_CNT20_STATUS_Msk (1UL << PMU_OVSSET_CNT20_STATUS_Pos) /*!< PMU OVSSET: Event Counter 20 Overflow Set Mask */ + +#define PMU_OVSSET_CNT21_STATUS_Pos 21U /*!< PMU OVSSET: Event Counter 21 Overflow Set Position */ +#define PMU_OVSSET_CNT21_STATUS_Msk (1UL << PMU_OVSSET_CNT21_STATUS_Pos) /*!< PMU OVSSET: Event Counter 21 Overflow Set Mask */ + +#define PMU_OVSSET_CNT22_STATUS_Pos 22U /*!< PMU OVSSET: Event Counter 22 Overflow Set Position */ +#define PMU_OVSSET_CNT22_STATUS_Msk (1UL << PMU_OVSSET_CNT22_STATUS_Pos) /*!< PMU OVSSET: Event Counter 22 Overflow Set Mask */ + +#define PMU_OVSSET_CNT23_STATUS_Pos 23U /*!< PMU OVSSET: Event Counter 23 Overflow Set Position */ +#define PMU_OVSSET_CNT23_STATUS_Msk (1UL << PMU_OVSSET_CNT23_STATUS_Pos) /*!< PMU OVSSET: Event Counter 23 Overflow Set Mask */ + +#define PMU_OVSSET_CNT24_STATUS_Pos 24U /*!< PMU OVSSET: Event Counter 24 Overflow Set Position */ +#define PMU_OVSSET_CNT24_STATUS_Msk (1UL << PMU_OVSSET_CNT24_STATUS_Pos) /*!< PMU OVSSET: Event Counter 24 Overflow Set Mask */ + +#define PMU_OVSSET_CNT25_STATUS_Pos 25U /*!< PMU OVSSET: Event Counter 25 Overflow Set Position */ +#define PMU_OVSSET_CNT25_STATUS_Msk (1UL << PMU_OVSSET_CNT25_STATUS_Pos) /*!< PMU OVSSET: Event Counter 25 Overflow Set Mask */ + +#define PMU_OVSSET_CNT26_STATUS_Pos 26U /*!< PMU OVSSET: Event Counter 26 Overflow Set Position */ +#define PMU_OVSSET_CNT26_STATUS_Msk (1UL << PMU_OVSSET_CNT26_STATUS_Pos) /*!< PMU OVSSET: Event Counter 26 Overflow Set Mask */ + +#define PMU_OVSSET_CNT27_STATUS_Pos 27U /*!< PMU OVSSET: Event Counter 27 Overflow Set Position */ +#define PMU_OVSSET_CNT27_STATUS_Msk (1UL << PMU_OVSSET_CNT27_STATUS_Pos) /*!< PMU OVSSET: Event Counter 27 Overflow Set Mask */ + +#define PMU_OVSSET_CNT28_STATUS_Pos 28U /*!< PMU OVSSET: Event Counter 28 Overflow Set Position */ +#define PMU_OVSSET_CNT28_STATUS_Msk (1UL << PMU_OVSSET_CNT28_STATUS_Pos) /*!< PMU OVSSET: Event Counter 28 Overflow Set Mask */ + +#define PMU_OVSSET_CNT29_STATUS_Pos 29U /*!< PMU OVSSET: Event Counter 29 Overflow Set Position */ +#define PMU_OVSSET_CNT29_STATUS_Msk (1UL << PMU_OVSSET_CNT29_STATUS_Pos) /*!< PMU OVSSET: Event Counter 29 Overflow Set Mask */ + +#define PMU_OVSSET_CNT30_STATUS_Pos 30U /*!< PMU OVSSET: Event Counter 30 Overflow Set Position */ +#define PMU_OVSSET_CNT30_STATUS_Msk (1UL << PMU_OVSSET_CNT30_STATUS_Pos) /*!< PMU OVSSET: Event Counter 30 Overflow Set Mask */ + +#define PMU_OVSSET_CYCCNT_STATUS_Pos 31U /*!< PMU OVSSET: Cycle Counter Overflow Set Position */ +#define PMU_OVSSET_CYCCNT_STATUS_Msk (1UL << PMU_OVSSET_CYCCNT_STATUS_Pos) /*!< PMU OVSSET: Cycle Counter Overflow Set Mask */ + +/** \brief PMU Overflow Flag Status Clear Register Definitions */ + +#define PMU_OVSCLR_CNT0_STATUS_Pos 0U /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Position */ +#define PMU_OVSCLR_CNT0_STATUS_Msk (1UL /*<< PMU_OVSCLR_CNT0_STATUS_Pos*/) /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT1_STATUS_Pos 1U /*!< PMU OVSCLR: Event Counter 1 Overflow Clear Position */ +#define PMU_OVSCLR_CNT1_STATUS_Msk (1UL << PMU_OVSCLR_CNT1_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 1 Overflow Clear */ + +#define PMU_OVSCLR_CNT2_STATUS_Pos 2U /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Position */ +#define PMU_OVSCLR_CNT2_STATUS_Msk (1UL << PMU_OVSCLR_CNT2_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT3_STATUS_Pos 3U /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Position */ +#define PMU_OVSCLR_CNT3_STATUS_Msk (1UL << PMU_OVSCLR_CNT3_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT4_STATUS_Pos 4U /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Position */ +#define PMU_OVSCLR_CNT4_STATUS_Msk (1UL << PMU_OVSCLR_CNT4_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT5_STATUS_Pos 5U /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Position */ +#define PMU_OVSCLR_CNT5_STATUS_Msk (1UL << PMU_OVSCLR_CNT5_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT6_STATUS_Pos 6U /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Position */ +#define PMU_OVSCLR_CNT6_STATUS_Msk (1UL << PMU_OVSCLR_CNT6_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT7_STATUS_Pos 7U /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Position */ +#define PMU_OVSCLR_CNT7_STATUS_Msk (1UL << PMU_OVSCLR_CNT7_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT8_STATUS_Pos 8U /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Position */ +#define PMU_OVSCLR_CNT8_STATUS_Msk (1UL << PMU_OVSCLR_CNT8_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT9_STATUS_Pos 9U /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Position */ +#define PMU_OVSCLR_CNT9_STATUS_Msk (1UL << PMU_OVSCLR_CNT9_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT10_STATUS_Pos 10U /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Position */ +#define PMU_OVSCLR_CNT10_STATUS_Msk (1UL << PMU_OVSCLR_CNT10_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT11_STATUS_Pos 11U /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Position */ +#define PMU_OVSCLR_CNT11_STATUS_Msk (1UL << PMU_OVSCLR_CNT11_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT12_STATUS_Pos 12U /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Position */ +#define PMU_OVSCLR_CNT12_STATUS_Msk (1UL << PMU_OVSCLR_CNT12_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT13_STATUS_Pos 13U /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Position */ +#define PMU_OVSCLR_CNT13_STATUS_Msk (1UL << PMU_OVSCLR_CNT13_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT14_STATUS_Pos 14U /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Position */ +#define PMU_OVSCLR_CNT14_STATUS_Msk (1UL << PMU_OVSCLR_CNT14_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT15_STATUS_Pos 15U /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Position */ +#define PMU_OVSCLR_CNT15_STATUS_Msk (1UL << PMU_OVSCLR_CNT15_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT16_STATUS_Pos 16U /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Position */ +#define PMU_OVSCLR_CNT16_STATUS_Msk (1UL << PMU_OVSCLR_CNT16_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT17_STATUS_Pos 17U /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Position */ +#define PMU_OVSCLR_CNT17_STATUS_Msk (1UL << PMU_OVSCLR_CNT17_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT18_STATUS_Pos 18U /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Position */ +#define PMU_OVSCLR_CNT18_STATUS_Msk (1UL << PMU_OVSCLR_CNT18_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT19_STATUS_Pos 19U /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Position */ +#define PMU_OVSCLR_CNT19_STATUS_Msk (1UL << PMU_OVSCLR_CNT19_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT20_STATUS_Pos 20U /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Position */ +#define PMU_OVSCLR_CNT20_STATUS_Msk (1UL << PMU_OVSCLR_CNT20_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT21_STATUS_Pos 21U /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Position */ +#define PMU_OVSCLR_CNT21_STATUS_Msk (1UL << PMU_OVSCLR_CNT21_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT22_STATUS_Pos 22U /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Position */ +#define PMU_OVSCLR_CNT22_STATUS_Msk (1UL << PMU_OVSCLR_CNT22_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT23_STATUS_Pos 23U /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Position */ +#define PMU_OVSCLR_CNT23_STATUS_Msk (1UL << PMU_OVSCLR_CNT23_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT24_STATUS_Pos 24U /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Position */ +#define PMU_OVSCLR_CNT24_STATUS_Msk (1UL << PMU_OVSCLR_CNT24_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT25_STATUS_Pos 25U /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Position */ +#define PMU_OVSCLR_CNT25_STATUS_Msk (1UL << PMU_OVSCLR_CNT25_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT26_STATUS_Pos 26U /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Position */ +#define PMU_OVSCLR_CNT26_STATUS_Msk (1UL << PMU_OVSCLR_CNT26_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT27_STATUS_Pos 27U /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Position */ +#define PMU_OVSCLR_CNT27_STATUS_Msk (1UL << PMU_OVSCLR_CNT27_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT28_STATUS_Pos 28U /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Position */ +#define PMU_OVSCLR_CNT28_STATUS_Msk (1UL << PMU_OVSCLR_CNT28_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT29_STATUS_Pos 29U /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Position */ +#define PMU_OVSCLR_CNT29_STATUS_Msk (1UL << PMU_OVSCLR_CNT29_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT30_STATUS_Pos 30U /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Position */ +#define PMU_OVSCLR_CNT30_STATUS_Msk (1UL << PMU_OVSCLR_CNT30_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Mask */ + +#define PMU_OVSCLR_CYCCNT_STATUS_Pos 31U /*!< PMU OVSCLR: Cycle Counter Overflow Clear Position */ +#define PMU_OVSCLR_CYCCNT_STATUS_Msk (1UL << PMU_OVSCLR_CYCCNT_STATUS_Pos) /*!< PMU OVSCLR: Cycle Counter Overflow Clear Mask */ + +/** \brief PMU Software Increment Counter */ + +#define PMU_SWINC_CNT0_Pos 0U /*!< PMU SWINC: Event Counter 0 Software Increment Position */ +#define PMU_SWINC_CNT0_Msk (1UL /*<< PMU_SWINC_CNT0_Pos */) /*!< PMU SWINC: Event Counter 0 Software Increment Mask */ + +#define PMU_SWINC_CNT1_Pos 1U /*!< PMU SWINC: Event Counter 1 Software Increment Position */ +#define PMU_SWINC_CNT1_Msk (1UL << PMU_SWINC_CNT1_Pos) /*!< PMU SWINC: Event Counter 1 Software Increment Mask */ + +#define PMU_SWINC_CNT2_Pos 2U /*!< PMU SWINC: Event Counter 2 Software Increment Position */ +#define PMU_SWINC_CNT2_Msk (1UL << PMU_SWINC_CNT2_Pos) /*!< PMU SWINC: Event Counter 2 Software Increment Mask */ + +#define PMU_SWINC_CNT3_Pos 3U /*!< PMU SWINC: Event Counter 3 Software Increment Position */ +#define PMU_SWINC_CNT3_Msk (1UL << PMU_SWINC_CNT3_Pos) /*!< PMU SWINC: Event Counter 3 Software Increment Mask */ + +#define PMU_SWINC_CNT4_Pos 4U /*!< PMU SWINC: Event Counter 4 Software Increment Position */ +#define PMU_SWINC_CNT4_Msk (1UL << PMU_SWINC_CNT4_Pos) /*!< PMU SWINC: Event Counter 4 Software Increment Mask */ + +#define PMU_SWINC_CNT5_Pos 5U /*!< PMU SWINC: Event Counter 5 Software Increment Position */ +#define PMU_SWINC_CNT5_Msk (1UL << PMU_SWINC_CNT5_Pos) /*!< PMU SWINC: Event Counter 5 Software Increment Mask */ + +#define PMU_SWINC_CNT6_Pos 6U /*!< PMU SWINC: Event Counter 6 Software Increment Position */ +#define PMU_SWINC_CNT6_Msk (1UL << PMU_SWINC_CNT6_Pos) /*!< PMU SWINC: Event Counter 6 Software Increment Mask */ + +#define PMU_SWINC_CNT7_Pos 7U /*!< PMU SWINC: Event Counter 7 Software Increment Position */ +#define PMU_SWINC_CNT7_Msk (1UL << PMU_SWINC_CNT7_Pos) /*!< PMU SWINC: Event Counter 7 Software Increment Mask */ + +#define PMU_SWINC_CNT8_Pos 8U /*!< PMU SWINC: Event Counter 8 Software Increment Position */ +#define PMU_SWINC_CNT8_Msk (1UL << PMU_SWINC_CNT8_Pos) /*!< PMU SWINC: Event Counter 8 Software Increment Mask */ + +#define PMU_SWINC_CNT9_Pos 9U /*!< PMU SWINC: Event Counter 9 Software Increment Position */ +#define PMU_SWINC_CNT9_Msk (1UL << PMU_SWINC_CNT9_Pos) /*!< PMU SWINC: Event Counter 9 Software Increment Mask */ + +#define PMU_SWINC_CNT10_Pos 10U /*!< PMU SWINC: Event Counter 10 Software Increment Position */ +#define PMU_SWINC_CNT10_Msk (1UL << PMU_SWINC_CNT10_Pos) /*!< PMU SWINC: Event Counter 10 Software Increment Mask */ + +#define PMU_SWINC_CNT11_Pos 11U /*!< PMU SWINC: Event Counter 11 Software Increment Position */ +#define PMU_SWINC_CNT11_Msk (1UL << PMU_SWINC_CNT11_Pos) /*!< PMU SWINC: Event Counter 11 Software Increment Mask */ + +#define PMU_SWINC_CNT12_Pos 12U /*!< PMU SWINC: Event Counter 12 Software Increment Position */ +#define PMU_SWINC_CNT12_Msk (1UL << PMU_SWINC_CNT12_Pos) /*!< PMU SWINC: Event Counter 12 Software Increment Mask */ + +#define PMU_SWINC_CNT13_Pos 13U /*!< PMU SWINC: Event Counter 13 Software Increment Position */ +#define PMU_SWINC_CNT13_Msk (1UL << PMU_SWINC_CNT13_Pos) /*!< PMU SWINC: Event Counter 13 Software Increment Mask */ + +#define PMU_SWINC_CNT14_Pos 14U /*!< PMU SWINC: Event Counter 14 Software Increment Position */ +#define PMU_SWINC_CNT14_Msk (1UL << PMU_SWINC_CNT14_Pos) /*!< PMU SWINC: Event Counter 14 Software Increment Mask */ + +#define PMU_SWINC_CNT15_Pos 15U /*!< PMU SWINC: Event Counter 15 Software Increment Position */ +#define PMU_SWINC_CNT15_Msk (1UL << PMU_SWINC_CNT15_Pos) /*!< PMU SWINC: Event Counter 15 Software Increment Mask */ + +#define PMU_SWINC_CNT16_Pos 16U /*!< PMU SWINC: Event Counter 16 Software Increment Position */ +#define PMU_SWINC_CNT16_Msk (1UL << PMU_SWINC_CNT16_Pos) /*!< PMU SWINC: Event Counter 16 Software Increment Mask */ + +#define PMU_SWINC_CNT17_Pos 17U /*!< PMU SWINC: Event Counter 17 Software Increment Position */ +#define PMU_SWINC_CNT17_Msk (1UL << PMU_SWINC_CNT17_Pos) /*!< PMU SWINC: Event Counter 17 Software Increment Mask */ + +#define PMU_SWINC_CNT18_Pos 18U /*!< PMU SWINC: Event Counter 18 Software Increment Position */ +#define PMU_SWINC_CNT18_Msk (1UL << PMU_SWINC_CNT18_Pos) /*!< PMU SWINC: Event Counter 18 Software Increment Mask */ + +#define PMU_SWINC_CNT19_Pos 19U /*!< PMU SWINC: Event Counter 19 Software Increment Position */ +#define PMU_SWINC_CNT19_Msk (1UL << PMU_SWINC_CNT19_Pos) /*!< PMU SWINC: Event Counter 19 Software Increment Mask */ + +#define PMU_SWINC_CNT20_Pos 20U /*!< PMU SWINC: Event Counter 20 Software Increment Position */ +#define PMU_SWINC_CNT20_Msk (1UL << PMU_SWINC_CNT20_Pos) /*!< PMU SWINC: Event Counter 20 Software Increment Mask */ + +#define PMU_SWINC_CNT21_Pos 21U /*!< PMU SWINC: Event Counter 21 Software Increment Position */ +#define PMU_SWINC_CNT21_Msk (1UL << PMU_SWINC_CNT21_Pos) /*!< PMU SWINC: Event Counter 21 Software Increment Mask */ + +#define PMU_SWINC_CNT22_Pos 22U /*!< PMU SWINC: Event Counter 22 Software Increment Position */ +#define PMU_SWINC_CNT22_Msk (1UL << PMU_SWINC_CNT22_Pos) /*!< PMU SWINC: Event Counter 22 Software Increment Mask */ + +#define PMU_SWINC_CNT23_Pos 23U /*!< PMU SWINC: Event Counter 23 Software Increment Position */ +#define PMU_SWINC_CNT23_Msk (1UL << PMU_SWINC_CNT23_Pos) /*!< PMU SWINC: Event Counter 23 Software Increment Mask */ + +#define PMU_SWINC_CNT24_Pos 24U /*!< PMU SWINC: Event Counter 24 Software Increment Position */ +#define PMU_SWINC_CNT24_Msk (1UL << PMU_SWINC_CNT24_Pos) /*!< PMU SWINC: Event Counter 24 Software Increment Mask */ + +#define PMU_SWINC_CNT25_Pos 25U /*!< PMU SWINC: Event Counter 25 Software Increment Position */ +#define PMU_SWINC_CNT25_Msk (1UL << PMU_SWINC_CNT25_Pos) /*!< PMU SWINC: Event Counter 25 Software Increment Mask */ + +#define PMU_SWINC_CNT26_Pos 26U /*!< PMU SWINC: Event Counter 26 Software Increment Position */ +#define PMU_SWINC_CNT26_Msk (1UL << PMU_SWINC_CNT26_Pos) /*!< PMU SWINC: Event Counter 26 Software Increment Mask */ + +#define PMU_SWINC_CNT27_Pos 27U /*!< PMU SWINC: Event Counter 27 Software Increment Position */ +#define PMU_SWINC_CNT27_Msk (1UL << PMU_SWINC_CNT27_Pos) /*!< PMU SWINC: Event Counter 27 Software Increment Mask */ + +#define PMU_SWINC_CNT28_Pos 28U /*!< PMU SWINC: Event Counter 28 Software Increment Position */ +#define PMU_SWINC_CNT28_Msk (1UL << PMU_SWINC_CNT28_Pos) /*!< PMU SWINC: Event Counter 28 Software Increment Mask */ + +#define PMU_SWINC_CNT29_Pos 29U /*!< PMU SWINC: Event Counter 29 Software Increment Position */ +#define PMU_SWINC_CNT29_Msk (1UL << PMU_SWINC_CNT29_Pos) /*!< PMU SWINC: Event Counter 29 Software Increment Mask */ + +#define PMU_SWINC_CNT30_Pos 30U /*!< PMU SWINC: Event Counter 30 Software Increment Position */ +#define PMU_SWINC_CNT30_Msk (1UL << PMU_SWINC_CNT30_Pos) /*!< PMU SWINC: Event Counter 30 Software Increment Mask */ + +/** \brief PMU Control Register Definitions */ + +#define PMU_CTRL_ENABLE_Pos 0U /*!< PMU CTRL: ENABLE Position */ +#define PMU_CTRL_ENABLE_Msk (1UL /*<< PMU_CTRL_ENABLE_Pos*/) /*!< PMU CTRL: ENABLE Mask */ + +#define PMU_CTRL_EVENTCNT_RESET_Pos 1U /*!< PMU CTRL: Event Counter Reset Position */ +#define PMU_CTRL_EVENTCNT_RESET_Msk (1UL << PMU_CTRL_EVENTCNT_RESET_Pos) /*!< PMU CTRL: Event Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_RESET_Pos 2U /*!< PMU CTRL: Cycle Counter Reset Position */ +#define PMU_CTRL_CYCCNT_RESET_Msk (1UL << PMU_CTRL_CYCCNT_RESET_Pos) /*!< PMU CTRL: Cycle Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_DISABLE_Pos 5U /*!< PMU CTRL: Disable Cycle Counter Position */ +#define PMU_CTRL_CYCCNT_DISABLE_Msk (1UL << PMU_CTRL_CYCCNT_DISABLE_Pos) /*!< PMU CTRL: Disable Cycle Counter Mask */ + +#define PMU_CTRL_FRZ_ON_OV_Pos 9U /*!< PMU CTRL: Freeze-on-overflow Position */ +#define PMU_CTRL_FRZ_ON_OV_Msk (1UL << PMU_CTRL_FRZ_ON_OVERFLOW_Pos) /*!< PMU CTRL: Freeze-on-overflow Mask */ + +#define PMU_CTRL_TRACE_ON_OV_Pos 11U /*!< PMU CTRL: Trace-on-overflow Position */ +#define PMU_CTRL_TRACE_ON_OV_Msk (1UL << PMU_CTRL_TRACE_ON_OVERFLOW_Pos) /*!< PMU CTRL: Trace-on-overflow Mask */ + +/** \brief PMU Type Register Definitions */ + +#define PMU_TYPE_NUM_CNTS_Pos 0U /*!< PMU TYPE: Number of Counters Position */ +#define PMU_TYPE_NUM_CNTS_Msk (0xFFUL /*<< PMU_TYPE_NUM_CNTS_Pos*/) /*!< PMU TYPE: Number of Counters Mask */ + +#define PMU_TYPE_SIZE_CNTS_Pos 8U /*!< PMU TYPE: Size of Counters Position */ +#define PMU_TYPE_SIZE_CNTS_Msk (0x3FUL << PMU_TYPE_SIZE_CNTS_Pos) /*!< PMU TYPE: Size of Counters Mask */ + +#define PMU_TYPE_CYCCNT_PRESENT_Pos 14U /*!< PMU TYPE: Cycle Counter Present Position */ +#define PMU_TYPE_CYCCNT_PRESENT_Msk (1UL << PMU_TYPE_CYCCNT_PRESENT_Pos) /*!< PMU TYPE: Cycle Counter Present Mask */ + +#define PMU_TYPE_FRZ_OV_SUPPORT_Pos 21U /*!< PMU TYPE: Freeze-on-overflow Support Position */ +#define PMU_TYPE_FRZ_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Freeze-on-overflow Support Mask */ + +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Pos 23U /*!< PMU TYPE: Trace-on-overflow Support Position */ +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Trace-on-overflow Support Mask */ + +/** \brief PMU Authentication Status Register Definitions */ + +#define PMU_AUTHSTATUS_NSID_Pos 0U /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSID_Msk (0x3UL /*<< PMU_AUTHSTATUS_NSID_Pos*/) /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSNID_Pos 2U /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSNID_Msk (0x3UL << PMU_AUTHSTATUS_NSNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SID_Pos 4U /*!< PMU AUTHSTATUS: Secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_SID_Msk (0x3UL << PMU_AUTHSTATUS_SID_Pos) /*!< PMU AUTHSTATUS: Secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SNID_Pos 6U /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SNID_Msk (0x3UL << PMU_AUTHSTATUS_SNID_Pos) /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUID_Pos 16U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUID_Msk (0x3UL << PMU_AUTHSTATUS_NSUID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUNID_Pos 18U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUNID_Msk (0x3UL << PMU_AUTHSTATUS_NSUNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUID_Pos 20U /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_SUID_Msk (0x3UL << PMU_AUTHSTATUS_SUID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUNID_Pos 22U /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SUNID_Msk (0x3UL << PMU_AUTHSTATUS_SUNID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Mask */ + +/*@} end of group CMSIS_PMU */ +#endif + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +#define FPU_FPDSCR_FZ16_Pos 19U /*!< FPDSCR: FZ16 bit Position */ +#define FPU_FPDSCR_FZ16_Msk (1UL << FPU_FPDSCR_FZ16_Pos) /*!< FPDSCR: FZ16 bit Mask */ + +#define FPU_FPDSCR_LTPSIZE_Pos 16U /*!< FPDSCR: LTPSIZE bit Position */ +#define FPU_FPDSCR_LTPSIZE_Msk (7UL << FPU_FPDSCR_LTPSIZE_Pos) /*!< FPDSCR: LTPSIZE bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FPRound_Pos 28U /*!< MVFR0: FPRound bits Position */ +#define FPU_MVFR0_FPRound_Msk (0xFUL << FPU_MVFR0_FPRound_Pos) /*!< MVFR0: FPRound bits Mask */ + +#define FPU_MVFR0_FPSqrt_Pos 20U /*!< MVFR0: FPSqrt bits Position */ +#define FPU_MVFR0_FPSqrt_Msk (0xFUL << FPU_MVFR0_FPSqrt_Pos) /*!< MVFR0: FPSqrt bits Mask */ + +#define FPU_MVFR0_FPDivide_Pos 16U /*!< MVFR0: FPDivide bits Position */ +#define FPU_MVFR0_FPDivide_Msk (0xFUL << FPU_MVFR0_FPDivide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FPDP_Pos 8U /*!< MVFR0: FPDP bits Position */ +#define FPU_MVFR0_FPDP_Msk (0xFUL << FPU_MVFR0_FPDP_Pos) /*!< MVFR0: FPDP bits Mask */ + +#define FPU_MVFR0_FPSP_Pos 4U /*!< MVFR0: FPSP bits Position */ +#define FPU_MVFR0_FPSP_Msk (0xFUL << FPU_MVFR0_FPSP_Pos) /*!< MVFR0: FPSP bits Mask */ + +#define FPU_MVFR0_SIMDReg_Pos 0U /*!< MVFR0: SIMDReg bits Position */ +#define FPU_MVFR0_SIMDReg_Msk (0xFUL /*<< FPU_MVFR0_SIMDReg_Pos*/) /*!< MVFR0: SIMDReg bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FMAC_Pos 28U /*!< MVFR1: FMAC bits Position */ +#define FPU_MVFR1_FMAC_Msk (0xFUL << FPU_MVFR1_FMAC_Pos) /*!< MVFR1: FMAC bits Mask */ + +#define FPU_MVFR1_FPHP_Pos 24U /*!< MVFR1: FPHP bits Position */ +#define FPU_MVFR1_FPHP_Msk (0xFUL << FPU_MVFR1_FPHP_Pos) /*!< MVFR1: FPHP bits Mask */ + +#define FPU_MVFR1_FP16_Pos 20U /*!< MVFR1: FP16 bits Position */ +#define FPU_MVFR1_FP16_Msk (0xFUL << FPU_MVFR1_FP16_Pos) /*!< MVFR1: FP16 bits Mask */ + +#define FPU_MVFR1_MVE_Pos 8U /*!< MVFR1: MVE bits Position */ +#define FPU_MVFR1_MVE_Msk (0xFUL << FPU_MVFR1_MVE_Pos) /*!< MVFR1: MVE bits Mask */ + +#define FPU_MVFR1_FPDNaN_Pos 4U /*!< MVFR1: FPDNaN bits Position */ +#define FPU_MVFR1_FPDNaN_Msk (0xFUL << FPU_MVFR1_FPDNaN_Pos) /*!< MVFR1: FPDNaN bits Mask */ + +#define FPU_MVFR1_FPFtZ_Pos 0U /*!< MVFR1: FPFtZ bits Position */ +#define FPU_MVFR1_FPFtZ_Msk (0xFUL /*<< FPU_MVFR1_FPFtZ_Pos*/) /*!< MVFR1: FPFtZ bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_FPD_Pos 23U /*!< \deprecated CoreDebug DHCSR: S_FPD Position */ +#define CoreDebug_DHCSR_S_FPD_Msk (1UL << CoreDebug_DHCSR_S_FPD_Pos) /*!< \deprecated CoreDebug DHCSR: S_FPD Mask */ + +#define CoreDebug_DHCSR_S_SUIDE_Pos 22U /*!< \deprecated CoreDebug DHCSR: S_SUIDE Position */ +#define CoreDebug_DHCSR_S_SUIDE_Msk (1UL << CoreDebug_DHCSR_S_SUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SUIDE Mask */ + +#define CoreDebug_DHCSR_S_NSUIDE_Pos 21U /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Position */ +#define CoreDebug_DHCSR_S_NSUIDE_Msk (1UL << CoreDebug_DHCSR_S_NSUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Mask */ + +#define CoreDebug_DHCSR_S_SDE_Pos 20U /*!< \deprecated CoreDebug DHCSR: S_SDE Position */ +#define CoreDebug_DHCSR_S_SDE_Msk (1UL << CoreDebug_DHCSR_S_SDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SDE Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_PMOV_Pos 6U /*!< \deprecated CoreDebug DHCSR: C_PMOV Position */ +#define CoreDebug_DHCSR_C_PMOV_Msk (1UL << CoreDebug_DHCSR_C_PMOV_Pos) /*!< \deprecated CoreDebug DHCSR: C_PMOV Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Set Clear Exception and Monitor Control Register Definitions */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_REQ_Pos 3U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_SET_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_PEND_Pos 1U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_SET_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_UIDEN_Pos 10U /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_UIDAPEN_Pos 9U /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDAPEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDAPEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Mask */ + +#define CoreDebug_DAUTHCTRL_FSDMA_Pos 8U /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Position */ +#define CoreDebug_DAUTHCTRL_FSDMA_Msk (1UL << CoreDebug_DAUTHCTRL_FSDMA_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_FPD_Pos 23U /*!< DCB DHCSR: Floating-point registers Debuggable Position */ +#define DCB_DHCSR_S_FPD_Msk (0x1UL << DCB_DHCSR_S_FPD_Pos) /*!< DCB DHCSR: Floating-point registers Debuggable Mask */ + +#define DCB_DHCSR_S_SUIDE_Pos 22U /*!< DCB DHCSR: Secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_SUIDE_Msk (0x1UL << DCB_DHCSR_S_SUIDE_Pos) /*!< DCB DHCSR: Secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_NSUIDE_Pos 21U /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_NSUIDE_Msk (0x1UL << DCB_DHCSR_S_NSUIDE_Pos) /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_PMOV_Pos 6U /*!< DCB DHCSR: Halt on PMU overflow control Position */ +#define DCB_DHCSR_C_PMOV_Msk (0x1UL << DCB_DHCSR_C_PMOV_Pos) /*!< DCB DHCSR: Halt on PMU overflow control Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DSCEMCR, Debug Set Clear Exception and Monitor Control Register Definitions */ +#define DCB_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< DCB DSCEMCR: Clear monitor request Position */ +#define DCB_DSCEMCR_CLR_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_REQ_Pos) /*!< DCB DSCEMCR: Clear monitor request Mask */ + +#define DCB_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< DCB DSCEMCR: Clear monitor pend Position */ +#define DCB_DSCEMCR_CLR_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_PEND_Pos) /*!< DCB DSCEMCR: Clear monitor pend Mask */ + +#define DCB_DSCEMCR_SET_MON_REQ_Pos 3U /*!< DCB DSCEMCR: Set monitor request Position */ +#define DCB_DSCEMCR_SET_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_SET_MON_REQ_Pos) /*!< DCB DSCEMCR: Set monitor request Mask */ + +#define DCB_DSCEMCR_SET_MON_PEND_Pos 1U /*!< DCB DSCEMCR: Set monitor pend Position */ +#define DCB_DSCEMCR_SET_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_SET_MON_PEND_Pos) /*!< DCB DSCEMCR: Set monitor pend Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_UIDEN_Pos 10U /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Position */ +#define DCB_DAUTHCTRL_UIDEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Mask */ + +#define DCB_DAUTHCTRL_UIDAPEN_Pos 9U /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Position */ +#define DCB_DAUTHCTRL_UIDAPEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDAPEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Mask */ + +#define DCB_DAUTHCTRL_FSDMA_Pos 8U /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Position */ +#define DCB_DAUTHCTRL_FSDMA_Msk (0x1UL << DCB_DAUTHCTRL_FSDMA_Pos) /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Mask */ + +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SUNID_Pos 22U /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUNID_Msk (0x3UL << DIB_DAUTHSTATUS_SUNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SUID_Pos 20U /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUID_Msk (0x3UL << DIB_DAUTHSTATUS_SUID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_NSUNID_Pos 18U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Position */ +#define DIB_DAUTHSTATUS_NSUNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Mask */ + +#define DIB_DAUTHSTATUS_NSUID_Pos 16U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_NSUID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + #define PMU_BASE (0xE0003000UL) /*!< PMU Base Address */ + #define PMU ((PMU_Type *) PMU_BASE ) /*!< PMU configuration struct */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## PMU functions and events #################################### */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + +#include "pmu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + +/* ########################## MVE functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_MveFunctions MVE Functions + \brief Function that provides MVE type. + @{ + */ + +/** + \brief get MVE type + \details returns the MVE type + \returns + - \b 0: No Vector Extension (MVE) + - \b 1: Integer Vector Extension (MVE-I) + - \b 2: Floating-point Vector Extension (MVE-F) + */ +__STATIC_INLINE uint32_t SCB_GetMVEType(void) +{ + const uint32_t mvfr1 = FPU->MVFR1; + if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x2U << FPU_MVFR1_MVE_Pos)) + { + return 2U; + } + else if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x1U << FPU_MVFR1_MVE_Pos)) + { + return 1U; + } + else + { + return 0U; + } +} + + +/*@} end of CMSIS_Core_MveFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV81MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_armv8mbl.h b/Drivers/CMSIS/Core/Include/core_armv8mbl.h new file mode 100644 index 0000000..33970bc --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_armv8mbl.h @@ -0,0 +1,2222 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 27. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< \deprecated CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_armv8mml.h b/Drivers/CMSIS/Core/Include/core_armv8mml.h new file mode 100644 index 0000000..6e6bbb5 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_armv8mml.h @@ -0,0 +1,3209 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.2.3 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (80U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm0.h b/Drivers/CMSIS/Core/Include/core_cm0.h new file mode 100644 index 0000000..50d34a3 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm0.h @@ -0,0 +1,952 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 21. August 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + *(vectors + (int32_t)IRQn) = vector; /* use pointer arithmetic to access vector */ + /* ARM Application Note 321 states that the M0 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + return *(vectors + (int32_t)IRQn); /* use pointer arithmetic to access vector */ +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm0plus.h b/Drivers/CMSIS/Core/Include/core_cm0plus.h new file mode 100644 index 0000000..ed961aa --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm0plus.h @@ -0,0 +1,1087 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.9 + * @date 21. August 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +#else + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + *(vectors + (int32_t)IRQn) = vector; /* use pointer arithmetic to access vector */ +#endif + /* ARM Application Note 321 states that the M0+ does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +#else + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + return *(vectors + (int32_t)IRQn); /* use pointer arithmetic to access vector */ +#endif +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm1.h b/Drivers/CMSIS/Core/Include/core_cm1.h new file mode 100644 index 0000000..44c2a49 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm1.h @@ -0,0 +1,979 @@ +/**************************************************************************//** + * @file core_cm1.h + * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File + * @version V1.0.1 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM1_H_GENERIC +#define __CORE_CM1_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M1 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM1 definitions */ +#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ + __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (1U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM1_H_DEPENDANT +#define __CORE_CM1_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM1_REV + #define __CM1_REV 0x0100U + #warning "__CM1_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ + +#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M1 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M1 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm23.h b/Drivers/CMSIS/Core/Include/core_cm23.h new file mode 100644 index 0000000..54e85ea --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm23.h @@ -0,0 +1,2297 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 11. February 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM23_H_GENERIC +#define __CORE_CM23_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M23 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< \deprecated CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm3.h b/Drivers/CMSIS/Core/Include/core_cm3.h new file mode 100644 index 0000000..7beef11 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm3.h @@ -0,0 +1,1943 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ +#endif + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm33.h b/Drivers/CMSIS/Core/Include/core_cm33.h new file mode 100644 index 0000000..05d27f2 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm33.h @@ -0,0 +1,3277 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.2.3 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm35p.h b/Drivers/CMSIS/Core/Include/core_cm35p.h new file mode 100644 index 0000000..8092007 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm35p.h @@ -0,0 +1,3277 @@ +/**************************************************************************//** + * @file core_cm35p.h + * @brief CMSIS Cortex-M35P Core Peripheral Access Layer Header File + * @version V1.1.3 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM35P_H_GENERIC +#define __CORE_CM35P_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M35P + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM35P definitions */ +#define __CM35P_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM35P_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM35P_CMSIS_VERSION ((__CM35P_CMSIS_VERSION_MAIN << 16U) | \ + __CM35P_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (35U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM35P_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM35P_H_DEPENDANT +#define __CORE_CM35P_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM35P_REV + #define __CM35P_REV 0x0000U + #warning "__CM35P_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M35P */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM35P_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm4.h b/Drivers/CMSIS/Core/Include/core_cm4.h new file mode 100644 index 0000000..c63f4af --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm4.h @@ -0,0 +1,2129 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm55.h b/Drivers/CMSIS/Core/Include/core_cm55.h new file mode 100644 index 0000000..874ed4b --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm55.h @@ -0,0 +1,4817 @@ +/**************************************************************************//** + * @file core_cm55.h + * @brief CMSIS Cortex-M55 Core Peripheral Access Layer Header File + * @version V1.2.4 + * @date 21. April 2022 + ******************************************************************************/ +/* + * Copyright (c) 2018-2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM55_H_GENERIC +#define __CORE_CM55_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M55 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM55 definitions */ +#define __CM55_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM55_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM55_CMSIS_VERSION ((__CM55_CMSIS_VERSION_MAIN << 16U) | \ + __CM55_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (55U) /*!< Cortex-M Core */ + +#if defined ( __CC_ARM ) + #error Legacy Arm Compiler does not support Armv8.1-M target architecture. +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM55_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM55_H_DEPENDANT +#define __CORE_CM55_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM55_REV + #define __CM55_REV 0x0000U + #warning "__CM55_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #if __FPU_PRESENT != 0U + #ifndef __FPU_DP + #define __FPU_DP 0U + #warning "__FPU_DP not defined in device header file; using default!" + #endif + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __PMU_PRESENT + #define __PMU_PRESENT 0U + #warning "__PMU_PRESENT not defined in device header file; using default!" + #endif + + #if __PMU_PRESENT != 0U + #ifndef __PMU_NUM_EVENTCNT + #define __PMU_NUM_EVENTCNT 8U + #warning "__PMU_NUM_EVENTCNT not defined in device header file; using default!" + #elif (__PMU_NUM_EVENTCNT > 8 || __PMU_NUM_EVENTCNT < 2) + #error "__PMU_NUM_EVENTCNT is out of range in device header file!" */ + #endif + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M55 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core EWIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core PMU Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + __IOM uint32_t RFSR; /*!< Offset: 0x204 (R/W) RAS Fault Status Register */ + uint32_t RESERVED4[14U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_IESB_Pos 5U /*!< SCB AIRCR: Implicit ESB Enable Position */ +#define SCB_AIRCR_IESB_Msk (1UL << SCB_AIRCR_IESB_Pos) /*!< SCB AIRCR: Implicit ESB Enable Mask */ + +#define SCB_AIRCR_DIT_Pos 4U /*!< SCB AIRCR: Data Independent Timing Position */ +#define SCB_AIRCR_DIT_Msk (1UL << SCB_AIRCR_DIT_Pos) /*!< SCB AIRCR: Data Independent Timing Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_TRD_Pos 20U /*!< SCB CCR: TRD Position */ +#define SCB_CCR_TRD_Msk (1UL << SCB_CCR_TRD_Pos) /*!< SCB CCR: TRD Mask */ + +#define SCB_CCR_LOB_Pos 19U /*!< SCB CCR: LOB Position */ +#define SCB_CCR_LOB_Msk (1UL << SCB_CCR_LOB_Pos) /*!< SCB CCR: LOB Mask */ + +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_PMU_Pos 5U /*!< SCB DFSR: PMU Position */ +#define SCB_DFSR_PMU_Msk (1UL << SCB_DFSR_PMU_Pos) /*!< SCB DFSR: PMU Mask */ + +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CP7_Pos 7U /*!< SCB NSACR: CP7 Position */ +#define SCB_NSACR_CP7_Msk (1UL << SCB_NSACR_CP7_Pos) /*!< SCB NSACR: CP7 Mask */ + +#define SCB_NSACR_CP6_Pos 6U /*!< SCB NSACR: CP6 Position */ +#define SCB_NSACR_CP6_Msk (1UL << SCB_NSACR_CP6_Pos) /*!< SCB NSACR: CP6 Mask */ + +#define SCB_NSACR_CP5_Pos 5U /*!< SCB NSACR: CP5 Position */ +#define SCB_NSACR_CP5_Msk (1UL << SCB_NSACR_CP5_Pos) /*!< SCB NSACR: CP5 Mask */ + +#define SCB_NSACR_CP4_Pos 4U /*!< SCB NSACR: CP4 Position */ +#define SCB_NSACR_CP4_Msk (1UL << SCB_NSACR_CP4_Pos) /*!< SCB NSACR: CP4 Mask */ + +#define SCB_NSACR_CP3_Pos 3U /*!< SCB NSACR: CP3 Position */ +#define SCB_NSACR_CP3_Msk (1UL << SCB_NSACR_CP3_Pos) /*!< SCB NSACR: CP3 Mask */ + +#define SCB_NSACR_CP2_Pos 2U /*!< SCB NSACR: CP2 Position */ +#define SCB_NSACR_CP2_Msk (1UL << SCB_NSACR_CP2_Pos) /*!< SCB NSACR: CP2 Mask */ + +#define SCB_NSACR_CP1_Pos 1U /*!< SCB NSACR: CP1 Position */ +#define SCB_NSACR_CP1_Msk (1UL << SCB_NSACR_CP1_Pos) /*!< SCB NSACR: CP1 Mask */ + +#define SCB_NSACR_CP0_Pos 0U /*!< SCB NSACR: CP0 Position */ +#define SCB_NSACR_CP0_Msk (1UL /*<< SCB_NSACR_CP0_Pos*/) /*!< SCB NSACR: CP0 Mask */ + +/* SCB Debug Feature Register 0 Definitions */ +#define SCB_ID_DFR_UDE_Pos 28U /*!< SCB ID_DFR: UDE Position */ +#define SCB_ID_DFR_UDE_Msk (0xFUL << SCB_ID_DFR_UDE_Pos) /*!< SCB ID_DFR: UDE Mask */ + +#define SCB_ID_DFR_MProfDbg_Pos 20U /*!< SCB ID_DFR: MProfDbg Position */ +#define SCB_ID_DFR_MProfDbg_Msk (0xFUL << SCB_ID_DFR_MProfDbg_Pos) /*!< SCB ID_DFR: MProfDbg Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB RAS Fault Status Register Definitions */ +#define SCB_RFSR_V_Pos 31U /*!< SCB RFSR: V Position */ +#define SCB_RFSR_V_Msk (1UL << SCB_RFSR_V_Pos) /*!< SCB RFSR: V Mask */ + +#define SCB_RFSR_IS_Pos 16U /*!< SCB RFSR: IS Position */ +#define SCB_RFSR_IS_Msk (0x7FFFUL << SCB_RFSR_IS_Pos) /*!< SCB RFSR: IS Mask */ + +#define SCB_RFSR_UET_Pos 0U /*!< SCB RFSR: UET Position */ +#define SCB_RFSR_UET_Msk (3UL /*<< SCB_RFSR_UET_Pos*/) /*!< SCB RFSR: UET Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ICB Implementation Control Block register (ICB) + \brief Type definitions for the Implementation Control Block Register + @{ + */ + +/** + \brief Structure type to access the Implementation Control Block (ICB). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} ICB_Type; + +/* Auxiliary Control Register Definitions */ +#define ICB_ACTLR_DISCRITAXIRUW_Pos 27U /*!< ACTLR: DISCRITAXIRUW Position */ +#define ICB_ACTLR_DISCRITAXIRUW_Msk (1UL << ICB_ACTLR_DISCRITAXIRUW_Pos) /*!< ACTLR: DISCRITAXIRUW Mask */ + +#define ICB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define ICB_ACTLR_DISDI_Msk (3UL << ICB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define ICB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define ICB_ACTLR_DISCRITAXIRUR_Msk (1UL << ICB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define ICB_ACTLR_EVENTBUSEN_Pos 14U /*!< ACTLR: EVENTBUSEN Position */ +#define ICB_ACTLR_EVENTBUSEN_Msk (1UL << ICB_ACTLR_EVENTBUSEN_Pos) /*!< ACTLR: EVENTBUSEN Mask */ + +#define ICB_ACTLR_EVENTBUSEN_S_Pos 13U /*!< ACTLR: EVENTBUSEN_S Position */ +#define ICB_ACTLR_EVENTBUSEN_S_Msk (1UL << ICB_ACTLR_EVENTBUSEN_S_Pos) /*!< ACTLR: EVENTBUSEN_S Mask */ + +#define ICB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define ICB_ACTLR_DISITMATBFLUSH_Msk (1UL << ICB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define ICB_ACTLR_DISNWAMODE_Pos 11U /*!< ACTLR: DISNWAMODE Position */ +#define ICB_ACTLR_DISNWAMODE_Msk (1UL << ICB_ACTLR_DISNWAMODE_Pos) /*!< ACTLR: DISNWAMODE Mask */ + +#define ICB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define ICB_ACTLR_FPEXCODIS_Msk (1UL << ICB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define ICB_ACTLR_DISOLAP_Pos 7U /*!< ACTLR: DISOLAP Position */ +#define ICB_ACTLR_DISOLAP_Msk (1UL << ICB_ACTLR_DISOLAP_Pos) /*!< ACTLR: DISOLAP Mask */ + +#define ICB_ACTLR_DISOLAPS_Pos 6U /*!< ACTLR: DISOLAPS Position */ +#define ICB_ACTLR_DISOLAPS_Msk (1UL << ICB_ACTLR_DISOLAPS_Pos) /*!< ACTLR: DISOLAPS Mask */ + +#define ICB_ACTLR_DISLOBR_Pos 5U /*!< ACTLR: DISLOBR Position */ +#define ICB_ACTLR_DISLOBR_Msk (1UL << ICB_ACTLR_DISLOBR_Pos) /*!< ACTLR: DISLOBR Mask */ + +#define ICB_ACTLR_DISLO_Pos 4U /*!< ACTLR: DISLO Position */ +#define ICB_ACTLR_DISLO_Msk (1UL << ICB_ACTLR_DISLO_Pos) /*!< ACTLR: DISLO Mask */ + +#define ICB_ACTLR_DISLOLEP_Pos 3U /*!< ACTLR: DISLOLEP Position */ +#define ICB_ACTLR_DISLOLEP_Msk (1UL << ICB_ACTLR_DISLOLEP_Pos) /*!< ACTLR: DISLOLEP Mask */ + +#define ICB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define ICB_ACTLR_DISFOLD_Msk (1UL << ICB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +/* Interrupt Controller Type Register Definitions */ +#define ICB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define ICB_ICTR_INTLINESNUM_Msk (0xFUL /*<< ICB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_ICB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[3U]; + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) ITM Device Type Register */ + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup MemSysCtl_Type Memory System Control Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Memory System Control Registers (MEMSYSCTL) + @{ + */ + +/** + \brief Structure type to access the Memory System Control Registers (MEMSYSCTL). + */ +typedef struct +{ + __IOM uint32_t MSCR; /*!< Offset: 0x000 (R/W) Memory System Control Register */ + __IOM uint32_t PFCR; /*!< Offset: 0x004 (R/W) Prefetcher Control Register */ + uint32_t RESERVED1[2U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x010 (R/W) ITCM Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x014 (R/W) DTCM Control Register */ + __IOM uint32_t PAHBCR; /*!< Offset: 0x018 (R/W) P-AHB Control Register */ + uint32_t RESERVED2[313U]; + __IOM uint32_t ITGU_CTRL; /*!< Offset: 0x500 (R/W) ITGU Control Register */ + __IOM uint32_t ITGU_CFG; /*!< Offset: 0x504 (R/W) ITGU Configuration Register */ + uint32_t RESERVED3[2U]; + __IOM uint32_t ITGU_LUT[16U]; /*!< Offset: 0x510 (R/W) ITGU Look Up Table Register */ + uint32_t RESERVED4[44U]; + __IOM uint32_t DTGU_CTRL; /*!< Offset: 0x600 (R/W) DTGU Control Registers */ + __IOM uint32_t DTGU_CFG; /*!< Offset: 0x604 (R/W) DTGU Configuration Register */ + uint32_t RESERVED5[2U]; + __IOM uint32_t DTGU_LUT[16U]; /*!< Offset: 0x610 (R/W) DTGU Look Up Table Register */ +} MemSysCtl_Type; + +/* MEMSYSCTL Memory System Control Register (MSCR) Register Definitions */ +#define MEMSYSCTL_MSCR_CPWRDN_Pos 17U /*!< MEMSYSCTL MSCR: CPWRDN Position */ +#define MEMSYSCTL_MSCR_CPWRDN_Msk (0x1UL << MEMSYSCTL_MSCR_CPWRDN_Pos) /*!< MEMSYSCTL MSCR: CPWRDN Mask */ + +#define MEMSYSCTL_MSCR_DCCLEAN_Pos 16U /*!< MEMSYSCTL MSCR: DCCLEAN Position */ +#define MEMSYSCTL_MSCR_DCCLEAN_Msk (0x1UL << MEMSYSCTL_MSCR_DCCLEAN_Pos) /*!< MEMSYSCTL MSCR: DCCLEAN Mask */ + +#define MEMSYSCTL_MSCR_ICACTIVE_Pos 13U /*!< MEMSYSCTL MSCR: ICACTIVE Position */ +#define MEMSYSCTL_MSCR_ICACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_ICACTIVE_Pos) /*!< MEMSYSCTL MSCR: ICACTIVE Mask */ + +#define MEMSYSCTL_MSCR_DCACTIVE_Pos 12U /*!< MEMSYSCTL MSCR: DCACTIVE Position */ +#define MEMSYSCTL_MSCR_DCACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_DCACTIVE_Pos) /*!< MEMSYSCTL MSCR: DCACTIVE Mask */ + +#define MEMSYSCTL_MSCR_TECCCHKDIS_Pos 4U /*!< MEMSYSCTL MSCR: TECCCHKDIS Position */ +#define MEMSYSCTL_MSCR_TECCCHKDIS_Msk (0x1UL << MEMSYSCTL_MSCR_TECCCHKDIS_Pos) /*!< MEMSYSCTL MSCR: TECCCHKDIS Mask */ + +#define MEMSYSCTL_MSCR_EVECCFAULT_Pos 3U /*!< MEMSYSCTL MSCR: EVECCFAULT Position */ +#define MEMSYSCTL_MSCR_EVECCFAULT_Msk (0x1UL << MEMSYSCTL_MSCR_EVECCFAULT_Pos) /*!< MEMSYSCTL MSCR: EVECCFAULT Mask */ + +#define MEMSYSCTL_MSCR_FORCEWT_Pos 2U /*!< MEMSYSCTL MSCR: FORCEWT Position */ +#define MEMSYSCTL_MSCR_FORCEWT_Msk (0x1UL << MEMSYSCTL_MSCR_FORCEWT_Pos) /*!< MEMSYSCTL MSCR: FORCEWT Mask */ + +#define MEMSYSCTL_MSCR_ECCEN_Pos 1U /*!< MEMSYSCTL MSCR: ECCEN Position */ +#define MEMSYSCTL_MSCR_ECCEN_Msk (0x1UL << MEMSYSCTL_MSCR_ECCEN_Pos) /*!< MEMSYSCTL MSCR: ECCEN Mask */ + +/* MEMSYSCTL Prefetcher Control Register (PFCR) Register Definitions */ +#define MEMSYSCTL_PFCR_MAX_OS_Pos 7U /*!< MEMSYSCTL PFCR: MAX_OS Position */ +#define MEMSYSCTL_PFCR_MAX_OS_Msk (0x7UL << MEMSYSCTL_PFCR_MAX_OS_Pos) /*!< MEMSYSCTL PFCR: MAX_OS Mask */ + +#define MEMSYSCTL_PFCR_MAX_LA_Pos 4U /*!< MEMSYSCTL PFCR: MAX_LA Position */ +#define MEMSYSCTL_PFCR_MAX_LA_Msk (0x7UL << MEMSYSCTL_PFCR_MAX_LA_Pos) /*!< MEMSYSCTL PFCR: MAX_LA Mask */ + +#define MEMSYSCTL_PFCR_MIN_LA_Pos 1U /*!< MEMSYSCTL PFCR: MIN_LA Position */ +#define MEMSYSCTL_PFCR_MIN_LA_Msk (0x7UL << MEMSYSCTL_PFCR_MIN_LA_Pos) /*!< MEMSYSCTL PFCR: MIN_LA Mask */ + +#define MEMSYSCTL_PFCR_ENABLE_Pos 0U /*!< MEMSYSCTL PFCR: ENABLE Position */ +#define MEMSYSCTL_PFCR_ENABLE_Msk (0x1UL /*<< MEMSYSCTL_PFCR_ENABLE_Pos*/) /*!< MEMSYSCTL PFCR: ENABLE Mask */ + +/* MEMSYSCTL ITCM Control Register (ITCMCR) Register Definitions */ +#define MEMSYSCTL_ITCMCR_SZ_Pos 3U /*!< MEMSYSCTL ITCMCR: SZ Position */ +#define MEMSYSCTL_ITCMCR_SZ_Msk (0xFUL << MEMSYSCTL_ITCMCR_SZ_Pos) /*!< MEMSYSCTL ITCMCR: SZ Mask */ + +#define MEMSYSCTL_ITCMCR_EN_Pos 0U /*!< MEMSYSCTL ITCMCR: EN Position */ +#define MEMSYSCTL_ITCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_ITCMCR_EN_Pos*/) /*!< MEMSYSCTL ITCMCR: EN Mask */ + +/* MEMSYSCTL DTCM Control Register (DTCMCR) Register Definitions */ +#define MEMSYSCTL_DTCMCR_SZ_Pos 3U /*!< MEMSYSCTL DTCMCR: SZ Position */ +#define MEMSYSCTL_DTCMCR_SZ_Msk (0xFUL << MEMSYSCTL_DTCMCR_SZ_Pos) /*!< MEMSYSCTL DTCMCR: SZ Mask */ + +#define MEMSYSCTL_DTCMCR_EN_Pos 0U /*!< MEMSYSCTL DTCMCR: EN Position */ +#define MEMSYSCTL_DTCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_DTCMCR_EN_Pos*/) /*!< MEMSYSCTL DTCMCR: EN Mask */ + +/* MEMSYSCTL P-AHB Control Register (PAHBCR) Register Definitions */ +#define MEMSYSCTL_PAHBCR_SZ_Pos 1U /*!< MEMSYSCTL PAHBCR: SZ Position */ +#define MEMSYSCTL_PAHBCR_SZ_Msk (0x7UL << MEMSYSCTL_PAHBCR_SZ_Pos) /*!< MEMSYSCTL PAHBCR: SZ Mask */ + +#define MEMSYSCTL_PAHBCR_EN_Pos 0U /*!< MEMSYSCTL PAHBCR: EN Position */ +#define MEMSYSCTL_PAHBCR_EN_Msk (0x1UL /*<< MEMSYSCTL_PAHBCR_EN_Pos*/) /*!< MEMSYSCTL PAHBCR: EN Mask */ + +/* MEMSYSCTL ITGU Control Register (ITGU_CTRL) Register Definitions */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL ITGU_CTRL: DEREN Position */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_ITGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL ITGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL ITGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_ITGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL ITGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL ITGU Configuration Register (ITGU_CFG) Register Definitions */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL ITGU_CFG: PRESENT Position */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_ITGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL ITGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL ITGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_ITGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL ITGU_CFG: BLKSZ Mask */ + +/* MEMSYSCTL DTGU Control Registers (DTGU_CTRL) Register Definitions */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL DTGU_CTRL: DEREN Position */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_DTGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL DTGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL DTGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_DTGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL DTGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL DTGU Configuration Register (DTGU_CFG) Register Definitions */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL DTGU_CFG: PRESENT Position */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_DTGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL DTGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL DTGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_DTGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL DTGU_CFG: BLKSZ Mask */ + + +/*@}*/ /* end of group MemSysCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PwrModCtl_Type Power Mode Control Registers + \brief Type definitions for the Power Mode Control Registers (PWRMODCTL) + @{ + */ + +/** + \brief Structure type to access the Power Mode Control Registers (PWRMODCTL). + */ +typedef struct +{ + __IOM uint32_t CPDLPSTATE; /*!< Offset: 0x000 (R/W) Core Power Domain Low Power State Register */ + __IOM uint32_t DPDLPSTATE; /*!< Offset: 0x004 (R/W) Debug Power Domain Low Power State Register */ +} PwrModCtl_Type; + +/* PWRMODCTL Core Power Domain Low Power State (CPDLPSTATE) Register Definitions */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos 8U /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos 4U /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos 0U /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Msk (0x3UL /*<< PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos*/) /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Mask */ + +/* PWRMODCTL Debug Power Domain Low Power State (DPDLPSTATE) Register Definitions */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos 0U /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Position */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Msk (0x3UL /*<< PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos*/) /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Mask */ + +/*@}*/ /* end of group PwrModCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup EWIC_Type External Wakeup Interrupt Controller Registers + \brief Type definitions for the External Wakeup Interrupt Controller Registers (EWIC) + @{ + */ + +/** + \brief Structure type to access the External Wakeup Interrupt Controller Registers (EWIC). + */ +typedef struct +{ + __OM uint32_t EVENTSPR; /*!< Offset: 0x000 ( /W) Event Set Pending Register */ + uint32_t RESERVED0[31U]; + __IM uint32_t EVENTMASKA; /*!< Offset: 0x080 (R/W) Event Mask A Register */ + __IM uint32_t EVENTMASK[15]; /*!< Offset: 0x084 (R/W) Event Mask Register */ +} EWIC_Type; + +/* EWIC External Wakeup Interrupt Controller (EVENTSPR) Register Definitions */ +#define EWIC_EVENTSPR_EDBGREQ_Pos 2U /*!< EWIC EVENTSPR: EDBGREQ Position */ +#define EWIC_EVENTSPR_EDBGREQ_Msk (0x1UL << EWIC_EVENTSPR_EDBGREQ_Pos) /*!< EWIC EVENTSPR: EDBGREQ Mask */ + +#define EWIC_EVENTSPR_NMI_Pos 1U /*!< EWIC EVENTSPR: NMI Position */ +#define EWIC_EVENTSPR_NMI_Msk (0x1UL << EWIC_EVENTSPR_NMI_Pos) /*!< EWIC EVENTSPR: NMI Mask */ + +#define EWIC_EVENTSPR_EVENT_Pos 0U /*!< EWIC EVENTSPR: EVENT Position */ +#define EWIC_EVENTSPR_EVENT_Msk (0x1UL /*<< EWIC_EVENTSPR_EVENT_Pos*/) /*!< EWIC EVENTSPR: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASKA) Register Definitions */ +#define EWIC_EVENTMASKA_EDBGREQ_Pos 2U /*!< EWIC EVENTMASKA: EDBGREQ Position */ +#define EWIC_EVENTMASKA_EDBGREQ_Msk (0x1UL << EWIC_EVENTMASKA_EDBGREQ_Pos) /*!< EWIC EVENTMASKA: EDBGREQ Mask */ + +#define EWIC_EVENTMASKA_NMI_Pos 1U /*!< EWIC EVENTMASKA: NMI Position */ +#define EWIC_EVENTMASKA_NMI_Msk (0x1UL << EWIC_EVENTMASKA_NMI_Pos) /*!< EWIC EVENTMASKA: NMI Mask */ + +#define EWIC_EVENTMASKA_EVENT_Pos 0U /*!< EWIC EVENTMASKA: EVENT Position */ +#define EWIC_EVENTMASKA_EVENT_Msk (0x1UL /*<< EWIC_EVENTMASKA_EVENT_Pos*/) /*!< EWIC EVENTMASKA: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASK) Register Definitions */ +#define EWIC_EVENTMASK_IRQ_Pos 0U /*!< EWIC EVENTMASKA: IRQ Position */ +#define EWIC_EVENTMASK_IRQ_Msk (0xFFFFFFFFUL /*<< EWIC_EVENTMASKA_IRQ_Pos*/) /*!< EWIC EVENTMASKA: IRQ Mask */ + +/*@}*/ /* end of group EWIC_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup ErrBnk_Type Error Banking Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Error Banking Registers (ERRBNK) + @{ + */ + +/** + \brief Structure type to access the Error Banking Registers (ERRBNK). + */ +typedef struct +{ + __IOM uint32_t IEBR0; /*!< Offset: 0x000 (R/W) Instruction Cache Error Bank Register 0 */ + __IOM uint32_t IEBR1; /*!< Offset: 0x004 (R/W) Instruction Cache Error Bank Register 1 */ + uint32_t RESERVED0[2U]; + __IOM uint32_t DEBR0; /*!< Offset: 0x010 (R/W) Data Cache Error Bank Register 0 */ + __IOM uint32_t DEBR1; /*!< Offset: 0x014 (R/W) Data Cache Error Bank Register 1 */ + uint32_t RESERVED1[2U]; + __IOM uint32_t TEBR0; /*!< Offset: 0x020 (R/W) TCM Error Bank Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t TEBR1; /*!< Offset: 0x028 (R/W) TCM Error Bank Register 1 */ +} ErrBnk_Type; + +/* ERRBNK Instruction Cache Error Bank Register 0 (IEBR0) Register Definitions */ +#define ERRBNK_IEBR0_SWDEF_Pos 30U /*!< ERRBNK IEBR0: SWDEF Position */ +#define ERRBNK_IEBR0_SWDEF_Msk (0x3UL << ERRBNK_IEBR0_SWDEF_Pos) /*!< ERRBNK IEBR0: SWDEF Mask */ + +#define ERRBNK_IEBR0_BANK_Pos 16U /*!< ERRBNK IEBR0: BANK Position */ +#define ERRBNK_IEBR0_BANK_Msk (0x1UL << ERRBNK_IEBR0_BANK_Pos) /*!< ERRBNK IEBR0: BANK Mask */ + +#define ERRBNK_IEBR0_LOCATION_Pos 2U /*!< ERRBNK IEBR0: LOCATION Position */ +#define ERRBNK_IEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR0_LOCATION_Pos) /*!< ERRBNK IEBR0: LOCATION Mask */ + +#define ERRBNK_IEBR0_LOCKED_Pos 1U /*!< ERRBNK IEBR0: LOCKED Position */ +#define ERRBNK_IEBR0_LOCKED_Msk (0x1UL << ERRBNK_IEBR0_LOCKED_Pos) /*!< ERRBNK IEBR0: LOCKED Mask */ + +#define ERRBNK_IEBR0_VALID_Pos 0U /*!< ERRBNK IEBR0: VALID Position */ +#define ERRBNK_IEBR0_VALID_Msk (0x1UL << /*ERRBNK_IEBR0_VALID_Pos*/) /*!< ERRBNK IEBR0: VALID Mask */ + +/* ERRBNK Instruction Cache Error Bank Register 1 (IEBR1) Register Definitions */ +#define ERRBNK_IEBR1_SWDEF_Pos 30U /*!< ERRBNK IEBR1: SWDEF Position */ +#define ERRBNK_IEBR1_SWDEF_Msk (0x3UL << ERRBNK_IEBR1_SWDEF_Pos) /*!< ERRBNK IEBR1: SWDEF Mask */ + +#define ERRBNK_IEBR1_BANK_Pos 16U /*!< ERRBNK IEBR1: BANK Position */ +#define ERRBNK_IEBR1_BANK_Msk (0x1UL << ERRBNK_IEBR1_BANK_Pos) /*!< ERRBNK IEBR1: BANK Mask */ + +#define ERRBNK_IEBR1_LOCATION_Pos 2U /*!< ERRBNK IEBR1: LOCATION Position */ +#define ERRBNK_IEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR1_LOCATION_Pos) /*!< ERRBNK IEBR1: LOCATION Mask */ + +#define ERRBNK_IEBR1_LOCKED_Pos 1U /*!< ERRBNK IEBR1: LOCKED Position */ +#define ERRBNK_IEBR1_LOCKED_Msk (0x1UL << ERRBNK_IEBR1_LOCKED_Pos) /*!< ERRBNK IEBR1: LOCKED Mask */ + +#define ERRBNK_IEBR1_VALID_Pos 0U /*!< ERRBNK IEBR1: VALID Position */ +#define ERRBNK_IEBR1_VALID_Msk (0x1UL << /*ERRBNK_IEBR1_VALID_Pos*/) /*!< ERRBNK IEBR1: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 0 (DEBR0) Register Definitions */ +#define ERRBNK_DEBR0_SWDEF_Pos 30U /*!< ERRBNK DEBR0: SWDEF Position */ +#define ERRBNK_DEBR0_SWDEF_Msk (0x3UL << ERRBNK_DEBR0_SWDEF_Pos) /*!< ERRBNK DEBR0: SWDEF Mask */ + +#define ERRBNK_DEBR0_TYPE_Pos 17U /*!< ERRBNK DEBR0: TYPE Position */ +#define ERRBNK_DEBR0_TYPE_Msk (0x1UL << ERRBNK_DEBR0_TYPE_Pos) /*!< ERRBNK DEBR0: TYPE Mask */ + +#define ERRBNK_DEBR0_BANK_Pos 16U /*!< ERRBNK DEBR0: BANK Position */ +#define ERRBNK_DEBR0_BANK_Msk (0x1UL << ERRBNK_DEBR0_BANK_Pos) /*!< ERRBNK DEBR0: BANK Mask */ + +#define ERRBNK_DEBR0_LOCATION_Pos 2U /*!< ERRBNK DEBR0: LOCATION Position */ +#define ERRBNK_DEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR0_LOCATION_Pos) /*!< ERRBNK DEBR0: LOCATION Mask */ + +#define ERRBNK_DEBR0_LOCKED_Pos 1U /*!< ERRBNK DEBR0: LOCKED Position */ +#define ERRBNK_DEBR0_LOCKED_Msk (0x1UL << ERRBNK_DEBR0_LOCKED_Pos) /*!< ERRBNK DEBR0: LOCKED Mask */ + +#define ERRBNK_DEBR0_VALID_Pos 0U /*!< ERRBNK DEBR0: VALID Position */ +#define ERRBNK_DEBR0_VALID_Msk (0x1UL << /*ERRBNK_DEBR0_VALID_Pos*/) /*!< ERRBNK DEBR0: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 1 (DEBR1) Register Definitions */ +#define ERRBNK_DEBR1_SWDEF_Pos 30U /*!< ERRBNK DEBR1: SWDEF Position */ +#define ERRBNK_DEBR1_SWDEF_Msk (0x3UL << ERRBNK_DEBR1_SWDEF_Pos) /*!< ERRBNK DEBR1: SWDEF Mask */ + +#define ERRBNK_DEBR1_TYPE_Pos 17U /*!< ERRBNK DEBR1: TYPE Position */ +#define ERRBNK_DEBR1_TYPE_Msk (0x1UL << ERRBNK_DEBR1_TYPE_Pos) /*!< ERRBNK DEBR1: TYPE Mask */ + +#define ERRBNK_DEBR1_BANK_Pos 16U /*!< ERRBNK DEBR1: BANK Position */ +#define ERRBNK_DEBR1_BANK_Msk (0x1UL << ERRBNK_DEBR1_BANK_Pos) /*!< ERRBNK DEBR1: BANK Mask */ + +#define ERRBNK_DEBR1_LOCATION_Pos 2U /*!< ERRBNK DEBR1: LOCATION Position */ +#define ERRBNK_DEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR1_LOCATION_Pos) /*!< ERRBNK DEBR1: LOCATION Mask */ + +#define ERRBNK_DEBR1_LOCKED_Pos 1U /*!< ERRBNK DEBR1: LOCKED Position */ +#define ERRBNK_DEBR1_LOCKED_Msk (0x1UL << ERRBNK_DEBR1_LOCKED_Pos) /*!< ERRBNK DEBR1: LOCKED Mask */ + +#define ERRBNK_DEBR1_VALID_Pos 0U /*!< ERRBNK DEBR1: VALID Position */ +#define ERRBNK_DEBR1_VALID_Msk (0x1UL << /*ERRBNK_DEBR1_VALID_Pos*/) /*!< ERRBNK DEBR1: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 0 (TEBR0) Register Definitions */ +#define ERRBNK_TEBR0_SWDEF_Pos 30U /*!< ERRBNK TEBR0: SWDEF Position */ +#define ERRBNK_TEBR0_SWDEF_Msk (0x3UL << ERRBNK_TEBR0_SWDEF_Pos) /*!< ERRBNK TEBR0: SWDEF Mask */ + +#define ERRBNK_TEBR0_POISON_Pos 28U /*!< ERRBNK TEBR0: POISON Position */ +#define ERRBNK_TEBR0_POISON_Msk (0x1UL << ERRBNK_TEBR0_POISON_Pos) /*!< ERRBNK TEBR0: POISON Mask */ + +#define ERRBNK_TEBR0_TYPE_Pos 27U /*!< ERRBNK TEBR0: TYPE Position */ +#define ERRBNK_TEBR0_TYPE_Msk (0x1UL << ERRBNK_TEBR0_TYPE_Pos) /*!< ERRBNK TEBR0: TYPE Mask */ + +#define ERRBNK_TEBR0_BANK_Pos 24U /*!< ERRBNK TEBR0: BANK Position */ +#define ERRBNK_TEBR0_BANK_Msk (0x3UL << ERRBNK_TEBR0_BANK_Pos) /*!< ERRBNK TEBR0: BANK Mask */ + +#define ERRBNK_TEBR0_LOCATION_Pos 2U /*!< ERRBNK TEBR0: LOCATION Position */ +#define ERRBNK_TEBR0_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR0_LOCATION_Pos) /*!< ERRBNK TEBR0: LOCATION Mask */ + +#define ERRBNK_TEBR0_LOCKED_Pos 1U /*!< ERRBNK TEBR0: LOCKED Position */ +#define ERRBNK_TEBR0_LOCKED_Msk (0x1UL << ERRBNK_TEBR0_LOCKED_Pos) /*!< ERRBNK TEBR0: LOCKED Mask */ + +#define ERRBNK_TEBR0_VALID_Pos 0U /*!< ERRBNK TEBR0: VALID Position */ +#define ERRBNK_TEBR0_VALID_Msk (0x1UL << /*ERRBNK_TEBR0_VALID_Pos*/) /*!< ERRBNK TEBR0: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 1 (TEBR1) Register Definitions */ +#define ERRBNK_TEBR1_SWDEF_Pos 30U /*!< ERRBNK TEBR1: SWDEF Position */ +#define ERRBNK_TEBR1_SWDEF_Msk (0x3UL << ERRBNK_TEBR1_SWDEF_Pos) /*!< ERRBNK TEBR1: SWDEF Mask */ + +#define ERRBNK_TEBR1_POISON_Pos 28U /*!< ERRBNK TEBR1: POISON Position */ +#define ERRBNK_TEBR1_POISON_Msk (0x1UL << ERRBNK_TEBR1_POISON_Pos) /*!< ERRBNK TEBR1: POISON Mask */ + +#define ERRBNK_TEBR1_TYPE_Pos 27U /*!< ERRBNK TEBR1: TYPE Position */ +#define ERRBNK_TEBR1_TYPE_Msk (0x1UL << ERRBNK_TEBR1_TYPE_Pos) /*!< ERRBNK TEBR1: TYPE Mask */ + +#define ERRBNK_TEBR1_BANK_Pos 24U /*!< ERRBNK TEBR1: BANK Position */ +#define ERRBNK_TEBR1_BANK_Msk (0x3UL << ERRBNK_TEBR1_BANK_Pos) /*!< ERRBNK TEBR1: BANK Mask */ + +#define ERRBNK_TEBR1_LOCATION_Pos 2U /*!< ERRBNK TEBR1: LOCATION Position */ +#define ERRBNK_TEBR1_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR1_LOCATION_Pos) /*!< ERRBNK TEBR1: LOCATION Mask */ + +#define ERRBNK_TEBR1_LOCKED_Pos 1U /*!< ERRBNK TEBR1: LOCKED Position */ +#define ERRBNK_TEBR1_LOCKED_Msk (0x1UL << ERRBNK_TEBR1_LOCKED_Pos) /*!< ERRBNK TEBR1: LOCKED Mask */ + +#define ERRBNK_TEBR1_VALID_Pos 0U /*!< ERRBNK TEBR1: VALID Position */ +#define ERRBNK_TEBR1_VALID_Msk (0x1UL << /*ERRBNK_TEBR1_VALID_Pos*/) /*!< ERRBNK TEBR1: VALID Mask */ + +/*@}*/ /* end of group ErrBnk_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PrcCfgInf_Type Processor Configuration Information Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Processor Configuration Information Registerss (PRCCFGINF) + @{ + */ + +/** + \brief Structure type to access the Processor Configuration Information Registerss (PRCCFGINF). + */ +typedef struct +{ + __OM uint32_t CFGINFOSEL; /*!< Offset: 0x000 ( /W) Processor Configuration Information Selection Register */ + __IM uint32_t CFGINFORD; /*!< Offset: 0x004 (R/ ) Processor Configuration Information Read Data Register */ +} PrcCfgInf_Type; + +/* PRCCFGINF Processor Configuration Information Selection Register (CFGINFOSEL) Definitions */ + +/* PRCCFGINF Processor Configuration Information Read Data Register (CFGINFORD) Definitions */ + +/*@}*/ /* end of group PrcCfgInf_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup STL_Type Software Test Library Observation Registers + \brief Type definitions for the Software Test Library Observation Registerss (STL) + @{ + */ + +/** + \brief Structure type to access the Software Test Library Observation Registerss (STL). + */ +typedef struct +{ + __IM uint32_t STLNVICPENDOR; /*!< Offset: 0x000 (R/ ) NVIC Pending Priority Tree Register */ + __IM uint32_t STLNVICACTVOR; /*!< Offset: 0x004 (R/ ) NVIC Active Priority Tree Register */ + uint32_t RESERVED0[2U]; + __OM uint32_t STLIDMPUSR; /*!< Offset: 0x010 ( /W) MPU Sanple Register */ + __IM uint32_t STLIMPUOR; /*!< Offset: 0x014 (R/ ) MPU Region Hit Register */ + __IM uint32_t STLD0MPUOR; /*!< Offset: 0x018 (R/ ) MPU Memory Attributes Register 0 */ + __IM uint32_t STLD1MPUOR; /*!< Offset: 0x01C (R/ ) MPU Memory Attributes Register 1 */ + +} STL_Type; + +/* STL Software Test Library Observation Register (STLNVICPENDOR) Definitions */ +#define STL_STLNVICPENDOR_VALID_Pos 18U /*!< STL STLNVICPENDOR: VALID Position */ +#define STL_STLNVICPENDOR_VALID_Msk (0x1UL << STL_STLNVICPENDOR_VALID_Pos) /*!< STL STLNVICPENDOR: VALID Mask */ + +#define STL_STLNVICPENDOR_TARGET_Pos 17U /*!< STL STLNVICPENDOR: TARGET Position */ +#define STL_STLNVICPENDOR_TARGET_Msk (0x1UL << STL_STLNVICPENDOR_TARGET_Pos) /*!< STL STLNVICPENDOR: TARGET Mask */ + +#define STL_STLNVICPENDOR_PRIORITY_Pos 9U /*!< STL STLNVICPENDOR: PRIORITY Position */ +#define STL_STLNVICPENDOR_PRIORITY_Msk (0xFFUL << STL_STLNVICPENDOR_PRIORITY_Pos) /*!< STL STLNVICPENDOR: PRIORITY Mask */ + +#define STL_STLNVICPENDOR_INTNUM_Pos 0U /*!< STL STLNVICPENDOR: INTNUM Position */ +#define STL_STLNVICPENDOR_INTNUM_Msk (0x1FFUL /*<< STL_STLNVICPENDOR_INTNUM_Pos*/) /*!< STL STLNVICPENDOR: INTNUM Mask */ + +/* STL Software Test Library Observation Register (STLNVICACTVOR) Definitions */ +#define STL_STLNVICACTVOR_VALID_Pos 18U /*!< STL STLNVICACTVOR: VALID Position */ +#define STL_STLNVICACTVOR_VALID_Msk (0x1UL << STL_STLNVICACTVOR_VALID_Pos) /*!< STL STLNVICACTVOR: VALID Mask */ + +#define STL_STLNVICACTVOR_TARGET_Pos 17U /*!< STL STLNVICACTVOR: TARGET Position */ +#define STL_STLNVICACTVOR_TARGET_Msk (0x1UL << STL_STLNVICACTVOR_TARGET_Pos) /*!< STL STLNVICACTVOR: TARGET Mask */ + +#define STL_STLNVICACTVOR_PRIORITY_Pos 9U /*!< STL STLNVICACTVOR: PRIORITY Position */ +#define STL_STLNVICACTVOR_PRIORITY_Msk (0xFFUL << STL_STLNVICACTVOR_PRIORITY_Pos) /*!< STL STLNVICACTVOR: PRIORITY Mask */ + +#define STL_STLNVICACTVOR_INTNUM_Pos 0U /*!< STL STLNVICACTVOR: INTNUM Position */ +#define STL_STLNVICACTVOR_INTNUM_Msk (0x1FFUL /*<< STL_STLNVICACTVOR_INTNUM_Pos*/) /*!< STL STLNVICACTVOR: INTNUM Mask */ + +/* STL Software Test Library Observation Register (STLIDMPUSR) Definitions */ +#define STL_STLIDMPUSR_ADDR_Pos 5U /*!< STL STLIDMPUSR: ADDR Position */ +#define STL_STLIDMPUSR_ADDR_Msk (0x7FFFFFFUL << STL_STLIDMPUSR_ADDR_Pos) /*!< STL STLIDMPUSR: ADDR Mask */ + +#define STL_STLIDMPUSR_INSTR_Pos 2U /*!< STL STLIDMPUSR: INSTR Position */ +#define STL_STLIDMPUSR_INSTR_Msk (0x1UL << STL_STLIDMPUSR_INSTR_Pos) /*!< STL STLIDMPUSR: INSTR Mask */ + +#define STL_STLIDMPUSR_DATA_Pos 1U /*!< STL STLIDMPUSR: DATA Position */ +#define STL_STLIDMPUSR_DATA_Msk (0x1UL << STL_STLIDMPUSR_DATA_Pos) /*!< STL STLIDMPUSR: DATA Mask */ + +/* STL Software Test Library Observation Register (STLIMPUOR) Definitions */ +#define STL_STLIMPUOR_HITREGION_Pos 9U /*!< STL STLIMPUOR: HITREGION Position */ +#define STL_STLIMPUOR_HITREGION_Msk (0xFFUL << STL_STLIMPUOR_HITREGION_Pos) /*!< STL STLIMPUOR: HITREGION Mask */ + +#define STL_STLIMPUOR_ATTR_Pos 0U /*!< STL STLIMPUOR: ATTR Position */ +#define STL_STLIMPUOR_ATTR_Msk (0x1FFUL /*<< STL_STLIMPUOR_ATTR_Pos*/) /*!< STL STLIMPUOR: ATTR Mask */ + +/* STL Software Test Library Observation Register (STLD0MPUOR) Definitions */ +#define STL_STLD0MPUOR_HITREGION_Pos 9U /*!< STL STLD0MPUOR: HITREGION Position */ +#define STL_STLD0MPUOR_HITREGION_Msk (0xFFUL << STL_STLD0MPUOR_HITREGION_Pos) /*!< STL STLD0MPUOR: HITREGION Mask */ + +#define STL_STLD0MPUOR_ATTR_Pos 0U /*!< STL STLD0MPUOR: ATTR Position */ +#define STL_STLD0MPUOR_ATTR_Msk (0x1FFUL /*<< STL_STLD0MPUOR_ATTR_Pos*/) /*!< STL STLD0MPUOR: ATTR Mask */ + +/* STL Software Test Library Observation Register (STLD1MPUOR) Definitions */ +#define STL_STLD1MPUOR_HITREGION_Pos 9U /*!< STL STLD1MPUOR: HITREGION Position */ +#define STL_STLD1MPUOR_HITREGION_Msk (0xFFUL << STL_STLD1MPUOR_HITREGION_Pos) /*!< STL STLD1MPUOR: HITREGION Mask */ + +#define STL_STLD1MPUOR_ATTR_Pos 0U /*!< STL STLD1MPUOR: ATTR Position */ +#define STL_STLD1MPUOR_ATTR_Msk (0x1FFUL /*<< STL_STLD1MPUOR_ATTR_Pos*/) /*!< STL STLD1MPUOR: ATTR Mask */ + +/*@}*/ /* end of group STL_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFmt_Pos 0U /*!< TPI FFCR: EnFmt Position */ +#define TPI_FFCR_EnFmt_Msk (0x3UL << /*TPI_FFCR_EnFmt_Pos*/) /*!< TPI FFCR: EnFmt Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_PMU Performance Monitoring Unit (PMU) + \brief Type definitions for the Performance Monitoring Unit (PMU) + @{ + */ + +/** + \brief Structure type to access the Performance Monitoring Unit (PMU). + */ +typedef struct +{ + __IOM uint32_t EVCNTR[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x0 (R/W) PMU Event Counter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED0[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCNTR; /*!< Offset: 0x7C (R/W) PMU Cycle Counter Register */ + uint32_t RESERVED1[224]; + __IOM uint32_t EVTYPER[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x400 (R/W) PMU Event Type and Filter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED2[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCFILTR; /*!< Offset: 0x47C (R/W) PMU Cycle Counter Filter Register */ + uint32_t RESERVED3[480]; + __IOM uint32_t CNTENSET; /*!< Offset: 0xC00 (R/W) PMU Count Enable Set Register */ + uint32_t RESERVED4[7]; + __IOM uint32_t CNTENCLR; /*!< Offset: 0xC20 (R/W) PMU Count Enable Clear Register */ + uint32_t RESERVED5[7]; + __IOM uint32_t INTENSET; /*!< Offset: 0xC40 (R/W) PMU Interrupt Enable Set Register */ + uint32_t RESERVED6[7]; + __IOM uint32_t INTENCLR; /*!< Offset: 0xC60 (R/W) PMU Interrupt Enable Clear Register */ + uint32_t RESERVED7[7]; + __IOM uint32_t OVSCLR; /*!< Offset: 0xC80 (R/W) PMU Overflow Flag Status Clear Register */ + uint32_t RESERVED8[7]; + __IOM uint32_t SWINC; /*!< Offset: 0xCA0 (R/W) PMU Software Increment Register */ + uint32_t RESERVED9[7]; + __IOM uint32_t OVSSET; /*!< Offset: 0xCC0 (R/W) PMU Overflow Flag Status Set Register */ + uint32_t RESERVED10[79]; + __IOM uint32_t TYPE; /*!< Offset: 0xE00 (R/W) PMU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0xE04 (R/W) PMU Control Register */ + uint32_t RESERVED11[108]; + __IOM uint32_t AUTHSTATUS; /*!< Offset: 0xFB8 (R/W) PMU Authentication Status Register */ + __IOM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/W) PMU Device Architecture Register */ + uint32_t RESERVED12[3]; + __IOM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/W) PMU Device Type Register */ + __IOM uint32_t PIDR4; /*!< Offset: 0xFD0 (R/W) PMU Peripheral Identification Register 4 */ + uint32_t RESERVED13[3]; + __IOM uint32_t PIDR0; /*!< Offset: 0xFE0 (R/W) PMU Peripheral Identification Register 0 */ + __IOM uint32_t PIDR1; /*!< Offset: 0xFE4 (R/W) PMU Peripheral Identification Register 1 */ + __IOM uint32_t PIDR2; /*!< Offset: 0xFE8 (R/W) PMU Peripheral Identification Register 2 */ + __IOM uint32_t PIDR3; /*!< Offset: 0xFEC (R/W) PMU Peripheral Identification Register 3 */ + __IOM uint32_t CIDR0; /*!< Offset: 0xFF0 (R/W) PMU Component Identification Register 0 */ + __IOM uint32_t CIDR1; /*!< Offset: 0xFF4 (R/W) PMU Component Identification Register 1 */ + __IOM uint32_t CIDR2; /*!< Offset: 0xFF8 (R/W) PMU Component Identification Register 2 */ + __IOM uint32_t CIDR3; /*!< Offset: 0xFFC (R/W) PMU Component Identification Register 3 */ +} PMU_Type; + +/** \brief PMU Event Counter Registers (0-30) Definitions */ + +#define PMU_EVCNTR_CNT_Pos 0U /*!< PMU EVCNTR: Counter Position */ +#define PMU_EVCNTR_CNT_Msk (0xFFFFUL /*<< PMU_EVCNTRx_CNT_Pos*/) /*!< PMU EVCNTR: Counter Mask */ + +/** \brief PMU Event Type and Filter Registers (0-30) Definitions */ + +#define PMU_EVTYPER_EVENTTOCNT_Pos 0U /*!< PMU EVTYPER: Event to Count Position */ +#define PMU_EVTYPER_EVENTTOCNT_Msk (0xFFFFUL /*<< EVTYPERx_EVENTTOCNT_Pos*/) /*!< PMU EVTYPER: Event to Count Mask */ + +/** \brief PMU Count Enable Set Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENSET: Event Counter 0 Enable Set Position */ +#define PMU_CNTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENSET_CNT0_ENABLE_Pos*/) /*!< PMU CNTENSET: Event Counter 0 Enable Set Mask */ + +#define PMU_CNTENSET_CNT1_ENABLE_Pos 1U /*!< PMU CNTENSET: Event Counter 1 Enable Set Position */ +#define PMU_CNTENSET_CNT1_ENABLE_Msk (1UL << PMU_CNTENSET_CNT1_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 1 Enable Set Mask */ + +#define PMU_CNTENSET_CNT2_ENABLE_Pos 2U /*!< PMU CNTENSET: Event Counter 2 Enable Set Position */ +#define PMU_CNTENSET_CNT2_ENABLE_Msk (1UL << PMU_CNTENSET_CNT2_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 2 Enable Set Mask */ + +#define PMU_CNTENSET_CNT3_ENABLE_Pos 3U /*!< PMU CNTENSET: Event Counter 3 Enable Set Position */ +#define PMU_CNTENSET_CNT3_ENABLE_Msk (1UL << PMU_CNTENSET_CNT3_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 3 Enable Set Mask */ + +#define PMU_CNTENSET_CNT4_ENABLE_Pos 4U /*!< PMU CNTENSET: Event Counter 4 Enable Set Position */ +#define PMU_CNTENSET_CNT4_ENABLE_Msk (1UL << PMU_CNTENSET_CNT4_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 4 Enable Set Mask */ + +#define PMU_CNTENSET_CNT5_ENABLE_Pos 5U /*!< PMU CNTENSET: Event Counter 5 Enable Set Position */ +#define PMU_CNTENSET_CNT5_ENABLE_Msk (1UL << PMU_CNTENSET_CNT5_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 5 Enable Set Mask */ + +#define PMU_CNTENSET_CNT6_ENABLE_Pos 6U /*!< PMU CNTENSET: Event Counter 6 Enable Set Position */ +#define PMU_CNTENSET_CNT6_ENABLE_Msk (1UL << PMU_CNTENSET_CNT6_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 6 Enable Set Mask */ + +#define PMU_CNTENSET_CNT7_ENABLE_Pos 7U /*!< PMU CNTENSET: Event Counter 7 Enable Set Position */ +#define PMU_CNTENSET_CNT7_ENABLE_Msk (1UL << PMU_CNTENSET_CNT7_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 7 Enable Set Mask */ + +#define PMU_CNTENSET_CNT8_ENABLE_Pos 8U /*!< PMU CNTENSET: Event Counter 8 Enable Set Position */ +#define PMU_CNTENSET_CNT8_ENABLE_Msk (1UL << PMU_CNTENSET_CNT8_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 8 Enable Set Mask */ + +#define PMU_CNTENSET_CNT9_ENABLE_Pos 9U /*!< PMU CNTENSET: Event Counter 9 Enable Set Position */ +#define PMU_CNTENSET_CNT9_ENABLE_Msk (1UL << PMU_CNTENSET_CNT9_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 9 Enable Set Mask */ + +#define PMU_CNTENSET_CNT10_ENABLE_Pos 10U /*!< PMU CNTENSET: Event Counter 10 Enable Set Position */ +#define PMU_CNTENSET_CNT10_ENABLE_Msk (1UL << PMU_CNTENSET_CNT10_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 10 Enable Set Mask */ + +#define PMU_CNTENSET_CNT11_ENABLE_Pos 11U /*!< PMU CNTENSET: Event Counter 11 Enable Set Position */ +#define PMU_CNTENSET_CNT11_ENABLE_Msk (1UL << PMU_CNTENSET_CNT11_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 11 Enable Set Mask */ + +#define PMU_CNTENSET_CNT12_ENABLE_Pos 12U /*!< PMU CNTENSET: Event Counter 12 Enable Set Position */ +#define PMU_CNTENSET_CNT12_ENABLE_Msk (1UL << PMU_CNTENSET_CNT12_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 12 Enable Set Mask */ + +#define PMU_CNTENSET_CNT13_ENABLE_Pos 13U /*!< PMU CNTENSET: Event Counter 13 Enable Set Position */ +#define PMU_CNTENSET_CNT13_ENABLE_Msk (1UL << PMU_CNTENSET_CNT13_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 13 Enable Set Mask */ + +#define PMU_CNTENSET_CNT14_ENABLE_Pos 14U /*!< PMU CNTENSET: Event Counter 14 Enable Set Position */ +#define PMU_CNTENSET_CNT14_ENABLE_Msk (1UL << PMU_CNTENSET_CNT14_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 14 Enable Set Mask */ + +#define PMU_CNTENSET_CNT15_ENABLE_Pos 15U /*!< PMU CNTENSET: Event Counter 15 Enable Set Position */ +#define PMU_CNTENSET_CNT15_ENABLE_Msk (1UL << PMU_CNTENSET_CNT15_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 15 Enable Set Mask */ + +#define PMU_CNTENSET_CNT16_ENABLE_Pos 16U /*!< PMU CNTENSET: Event Counter 16 Enable Set Position */ +#define PMU_CNTENSET_CNT16_ENABLE_Msk (1UL << PMU_CNTENSET_CNT16_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 16 Enable Set Mask */ + +#define PMU_CNTENSET_CNT17_ENABLE_Pos 17U /*!< PMU CNTENSET: Event Counter 17 Enable Set Position */ +#define PMU_CNTENSET_CNT17_ENABLE_Msk (1UL << PMU_CNTENSET_CNT17_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 17 Enable Set Mask */ + +#define PMU_CNTENSET_CNT18_ENABLE_Pos 18U /*!< PMU CNTENSET: Event Counter 18 Enable Set Position */ +#define PMU_CNTENSET_CNT18_ENABLE_Msk (1UL << PMU_CNTENSET_CNT18_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 18 Enable Set Mask */ + +#define PMU_CNTENSET_CNT19_ENABLE_Pos 19U /*!< PMU CNTENSET: Event Counter 19 Enable Set Position */ +#define PMU_CNTENSET_CNT19_ENABLE_Msk (1UL << PMU_CNTENSET_CNT19_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 19 Enable Set Mask */ + +#define PMU_CNTENSET_CNT20_ENABLE_Pos 20U /*!< PMU CNTENSET: Event Counter 20 Enable Set Position */ +#define PMU_CNTENSET_CNT20_ENABLE_Msk (1UL << PMU_CNTENSET_CNT20_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 20 Enable Set Mask */ + +#define PMU_CNTENSET_CNT21_ENABLE_Pos 21U /*!< PMU CNTENSET: Event Counter 21 Enable Set Position */ +#define PMU_CNTENSET_CNT21_ENABLE_Msk (1UL << PMU_CNTENSET_CNT21_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 21 Enable Set Mask */ + +#define PMU_CNTENSET_CNT22_ENABLE_Pos 22U /*!< PMU CNTENSET: Event Counter 22 Enable Set Position */ +#define PMU_CNTENSET_CNT22_ENABLE_Msk (1UL << PMU_CNTENSET_CNT22_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 22 Enable Set Mask */ + +#define PMU_CNTENSET_CNT23_ENABLE_Pos 23U /*!< PMU CNTENSET: Event Counter 23 Enable Set Position */ +#define PMU_CNTENSET_CNT23_ENABLE_Msk (1UL << PMU_CNTENSET_CNT23_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 23 Enable Set Mask */ + +#define PMU_CNTENSET_CNT24_ENABLE_Pos 24U /*!< PMU CNTENSET: Event Counter 24 Enable Set Position */ +#define PMU_CNTENSET_CNT24_ENABLE_Msk (1UL << PMU_CNTENSET_CNT24_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 24 Enable Set Mask */ + +#define PMU_CNTENSET_CNT25_ENABLE_Pos 25U /*!< PMU CNTENSET: Event Counter 25 Enable Set Position */ +#define PMU_CNTENSET_CNT25_ENABLE_Msk (1UL << PMU_CNTENSET_CNT25_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 25 Enable Set Mask */ + +#define PMU_CNTENSET_CNT26_ENABLE_Pos 26U /*!< PMU CNTENSET: Event Counter 26 Enable Set Position */ +#define PMU_CNTENSET_CNT26_ENABLE_Msk (1UL << PMU_CNTENSET_CNT26_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 26 Enable Set Mask */ + +#define PMU_CNTENSET_CNT27_ENABLE_Pos 27U /*!< PMU CNTENSET: Event Counter 27 Enable Set Position */ +#define PMU_CNTENSET_CNT27_ENABLE_Msk (1UL << PMU_CNTENSET_CNT27_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 27 Enable Set Mask */ + +#define PMU_CNTENSET_CNT28_ENABLE_Pos 28U /*!< PMU CNTENSET: Event Counter 28 Enable Set Position */ +#define PMU_CNTENSET_CNT28_ENABLE_Msk (1UL << PMU_CNTENSET_CNT28_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 28 Enable Set Mask */ + +#define PMU_CNTENSET_CNT29_ENABLE_Pos 29U /*!< PMU CNTENSET: Event Counter 29 Enable Set Position */ +#define PMU_CNTENSET_CNT29_ENABLE_Msk (1UL << PMU_CNTENSET_CNT29_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 29 Enable Set Mask */ + +#define PMU_CNTENSET_CNT30_ENABLE_Pos 30U /*!< PMU CNTENSET: Event Counter 30 Enable Set Position */ +#define PMU_CNTENSET_CNT30_ENABLE_Msk (1UL << PMU_CNTENSET_CNT30_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 30 Enable Set Mask */ + +#define PMU_CNTENSET_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENSET: Cycle Counter Enable Set Position */ +#define PMU_CNTENSET_CCNTR_ENABLE_Msk (1UL << PMU_CNTENSET_CCNTR_ENABLE_Pos) /*!< PMU CNTENSET: Cycle Counter Enable Set Mask */ + +/** \brief PMU Count Enable Clear Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Position */ +#define PMU_CNTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU CNTENCLR: Event Counter 1 Enable Clear Position */ +#define PMU_CNTENCLR_CNT1_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT1_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 1 Enable Clear */ + +#define PMU_CNTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Position */ +#define PMU_CNTENCLR_CNT2_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT2_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Position */ +#define PMU_CNTENCLR_CNT3_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT3_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Position */ +#define PMU_CNTENCLR_CNT4_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT4_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Position */ +#define PMU_CNTENCLR_CNT5_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT5_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Position */ +#define PMU_CNTENCLR_CNT6_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT6_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Position */ +#define PMU_CNTENCLR_CNT7_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT7_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Position */ +#define PMU_CNTENCLR_CNT8_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT8_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Position */ +#define PMU_CNTENCLR_CNT9_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT9_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Position */ +#define PMU_CNTENCLR_CNT10_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT10_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Position */ +#define PMU_CNTENCLR_CNT11_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT11_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Position */ +#define PMU_CNTENCLR_CNT12_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT12_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Position */ +#define PMU_CNTENCLR_CNT13_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT13_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Position */ +#define PMU_CNTENCLR_CNT14_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT14_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Position */ +#define PMU_CNTENCLR_CNT15_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT15_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Position */ +#define PMU_CNTENCLR_CNT16_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT16_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Position */ +#define PMU_CNTENCLR_CNT17_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT17_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Position */ +#define PMU_CNTENCLR_CNT18_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT18_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Position */ +#define PMU_CNTENCLR_CNT19_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT19_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Position */ +#define PMU_CNTENCLR_CNT20_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT20_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Position */ +#define PMU_CNTENCLR_CNT21_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT21_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Position */ +#define PMU_CNTENCLR_CNT22_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT22_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Position */ +#define PMU_CNTENCLR_CNT23_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT23_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Position */ +#define PMU_CNTENCLR_CNT24_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT24_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Position */ +#define PMU_CNTENCLR_CNT25_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT25_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Position */ +#define PMU_CNTENCLR_CNT26_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT26_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Position */ +#define PMU_CNTENCLR_CNT27_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT27_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Position */ +#define PMU_CNTENCLR_CNT28_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT28_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Position */ +#define PMU_CNTENCLR_CNT29_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT29_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Position */ +#define PMU_CNTENCLR_CNT30_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT30_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Mask */ + +#define PMU_CNTENCLR_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENCLR: Cycle Counter Enable Clear Position */ +#define PMU_CNTENCLR_CCNTR_ENABLE_Msk (1UL << PMU_CNTENCLR_CCNTR_ENABLE_Pos) /*!< PMU CNTENCLR: Cycle Counter Enable Clear Mask */ + +/** \brief PMU Interrupt Enable Set Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENSET_CNT0_ENABLE_Pos*/) /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT1_ENABLE_Pos 1U /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT1_ENABLE_Msk (1UL << PMU_INTENSET_CNT1_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT2_ENABLE_Pos 2U /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT2_ENABLE_Msk (1UL << PMU_INTENSET_CNT2_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT3_ENABLE_Pos 3U /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT3_ENABLE_Msk (1UL << PMU_INTENSET_CNT3_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT4_ENABLE_Pos 4U /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT4_ENABLE_Msk (1UL << PMU_INTENSET_CNT4_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT5_ENABLE_Pos 5U /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT5_ENABLE_Msk (1UL << PMU_INTENSET_CNT5_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT6_ENABLE_Pos 6U /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT6_ENABLE_Msk (1UL << PMU_INTENSET_CNT6_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT7_ENABLE_Pos 7U /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT7_ENABLE_Msk (1UL << PMU_INTENSET_CNT7_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT8_ENABLE_Pos 8U /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT8_ENABLE_Msk (1UL << PMU_INTENSET_CNT8_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT9_ENABLE_Pos 9U /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT9_ENABLE_Msk (1UL << PMU_INTENSET_CNT9_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT10_ENABLE_Pos 10U /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT10_ENABLE_Msk (1UL << PMU_INTENSET_CNT10_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT11_ENABLE_Pos 11U /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT11_ENABLE_Msk (1UL << PMU_INTENSET_CNT11_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT12_ENABLE_Pos 12U /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT12_ENABLE_Msk (1UL << PMU_INTENSET_CNT12_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT13_ENABLE_Pos 13U /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT13_ENABLE_Msk (1UL << PMU_INTENSET_CNT13_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT14_ENABLE_Pos 14U /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT14_ENABLE_Msk (1UL << PMU_INTENSET_CNT14_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT15_ENABLE_Pos 15U /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT15_ENABLE_Msk (1UL << PMU_INTENSET_CNT15_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT16_ENABLE_Pos 16U /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT16_ENABLE_Msk (1UL << PMU_INTENSET_CNT16_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT17_ENABLE_Pos 17U /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT17_ENABLE_Msk (1UL << PMU_INTENSET_CNT17_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT18_ENABLE_Pos 18U /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT18_ENABLE_Msk (1UL << PMU_INTENSET_CNT18_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT19_ENABLE_Pos 19U /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT19_ENABLE_Msk (1UL << PMU_INTENSET_CNT19_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT20_ENABLE_Pos 20U /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT20_ENABLE_Msk (1UL << PMU_INTENSET_CNT20_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT21_ENABLE_Pos 21U /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT21_ENABLE_Msk (1UL << PMU_INTENSET_CNT21_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT22_ENABLE_Pos 22U /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT22_ENABLE_Msk (1UL << PMU_INTENSET_CNT22_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT23_ENABLE_Pos 23U /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT23_ENABLE_Msk (1UL << PMU_INTENSET_CNT23_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT24_ENABLE_Pos 24U /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT24_ENABLE_Msk (1UL << PMU_INTENSET_CNT24_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT25_ENABLE_Pos 25U /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT25_ENABLE_Msk (1UL << PMU_INTENSET_CNT25_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT26_ENABLE_Pos 26U /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT26_ENABLE_Msk (1UL << PMU_INTENSET_CNT26_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT27_ENABLE_Pos 27U /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT27_ENABLE_Msk (1UL << PMU_INTENSET_CNT27_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT28_ENABLE_Pos 28U /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT28_ENABLE_Msk (1UL << PMU_INTENSET_CNT28_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT29_ENABLE_Pos 29U /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT29_ENABLE_Msk (1UL << PMU_INTENSET_CNT29_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT30_ENABLE_Pos 30U /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT30_ENABLE_Msk (1UL << PMU_INTENSET_CNT30_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Position */ +#define PMU_INTENSET_CCYCNT_ENABLE_Msk (1UL << PMU_INTENSET_CYCCNT_ENABLE_Pos) /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Mask */ + +/** \brief PMU Interrupt Enable Clear Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT1_ENABLE_Msk (1UL << PMU_INTENCLR_CNT1_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear */ + +#define PMU_INTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT2_ENABLE_Msk (1UL << PMU_INTENCLR_CNT2_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT3_ENABLE_Msk (1UL << PMU_INTENCLR_CNT3_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT4_ENABLE_Msk (1UL << PMU_INTENCLR_CNT4_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT5_ENABLE_Msk (1UL << PMU_INTENCLR_CNT5_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT6_ENABLE_Msk (1UL << PMU_INTENCLR_CNT6_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT7_ENABLE_Msk (1UL << PMU_INTENCLR_CNT7_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT8_ENABLE_Msk (1UL << PMU_INTENCLR_CNT8_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT9_ENABLE_Msk (1UL << PMU_INTENCLR_CNT9_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT10_ENABLE_Msk (1UL << PMU_INTENCLR_CNT10_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT11_ENABLE_Msk (1UL << PMU_INTENCLR_CNT11_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT12_ENABLE_Msk (1UL << PMU_INTENCLR_CNT12_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT13_ENABLE_Msk (1UL << PMU_INTENCLR_CNT13_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT14_ENABLE_Msk (1UL << PMU_INTENCLR_CNT14_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT15_ENABLE_Msk (1UL << PMU_INTENCLR_CNT15_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT16_ENABLE_Msk (1UL << PMU_INTENCLR_CNT16_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT17_ENABLE_Msk (1UL << PMU_INTENCLR_CNT17_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT18_ENABLE_Msk (1UL << PMU_INTENCLR_CNT18_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT19_ENABLE_Msk (1UL << PMU_INTENCLR_CNT19_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT20_ENABLE_Msk (1UL << PMU_INTENCLR_CNT20_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT21_ENABLE_Msk (1UL << PMU_INTENCLR_CNT21_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT22_ENABLE_Msk (1UL << PMU_INTENCLR_CNT22_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT23_ENABLE_Msk (1UL << PMU_INTENCLR_CNT23_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT24_ENABLE_Msk (1UL << PMU_INTENCLR_CNT24_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT25_ENABLE_Msk (1UL << PMU_INTENCLR_CNT25_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT26_ENABLE_Msk (1UL << PMU_INTENCLR_CNT26_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT27_ENABLE_Msk (1UL << PMU_INTENCLR_CNT27_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT28_ENABLE_Msk (1UL << PMU_INTENCLR_CNT28_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT29_ENABLE_Msk (1UL << PMU_INTENCLR_CNT29_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT30_ENABLE_Msk (1UL << PMU_INTENCLR_CNT30_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CYCCNT_ENABLE_Msk (1UL << PMU_INTENCLR_CYCCNT_ENABLE_Pos) /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Mask */ + +/** \brief PMU Overflow Flag Status Set Register Definitions */ + +#define PMU_OVSSET_CNT0_STATUS_Pos 0U /*!< PMU OVSSET: Event Counter 0 Overflow Set Position */ +#define PMU_OVSSET_CNT0_STATUS_Msk (1UL /*<< PMU_OVSSET_CNT0_STATUS_Pos*/) /*!< PMU OVSSET: Event Counter 0 Overflow Set Mask */ + +#define PMU_OVSSET_CNT1_STATUS_Pos 1U /*!< PMU OVSSET: Event Counter 1 Overflow Set Position */ +#define PMU_OVSSET_CNT1_STATUS_Msk (1UL << PMU_OVSSET_CNT1_STATUS_Pos) /*!< PMU OVSSET: Event Counter 1 Overflow Set Mask */ + +#define PMU_OVSSET_CNT2_STATUS_Pos 2U /*!< PMU OVSSET: Event Counter 2 Overflow Set Position */ +#define PMU_OVSSET_CNT2_STATUS_Msk (1UL << PMU_OVSSET_CNT2_STATUS_Pos) /*!< PMU OVSSET: Event Counter 2 Overflow Set Mask */ + +#define PMU_OVSSET_CNT3_STATUS_Pos 3U /*!< PMU OVSSET: Event Counter 3 Overflow Set Position */ +#define PMU_OVSSET_CNT3_STATUS_Msk (1UL << PMU_OVSSET_CNT3_STATUS_Pos) /*!< PMU OVSSET: Event Counter 3 Overflow Set Mask */ + +#define PMU_OVSSET_CNT4_STATUS_Pos 4U /*!< PMU OVSSET: Event Counter 4 Overflow Set Position */ +#define PMU_OVSSET_CNT4_STATUS_Msk (1UL << PMU_OVSSET_CNT4_STATUS_Pos) /*!< PMU OVSSET: Event Counter 4 Overflow Set Mask */ + +#define PMU_OVSSET_CNT5_STATUS_Pos 5U /*!< PMU OVSSET: Event Counter 5 Overflow Set Position */ +#define PMU_OVSSET_CNT5_STATUS_Msk (1UL << PMU_OVSSET_CNT5_STATUS_Pos) /*!< PMU OVSSET: Event Counter 5 Overflow Set Mask */ + +#define PMU_OVSSET_CNT6_STATUS_Pos 6U /*!< PMU OVSSET: Event Counter 6 Overflow Set Position */ +#define PMU_OVSSET_CNT6_STATUS_Msk (1UL << PMU_OVSSET_CNT6_STATUS_Pos) /*!< PMU OVSSET: Event Counter 6 Overflow Set Mask */ + +#define PMU_OVSSET_CNT7_STATUS_Pos 7U /*!< PMU OVSSET: Event Counter 7 Overflow Set Position */ +#define PMU_OVSSET_CNT7_STATUS_Msk (1UL << PMU_OVSSET_CNT7_STATUS_Pos) /*!< PMU OVSSET: Event Counter 7 Overflow Set Mask */ + +#define PMU_OVSSET_CNT8_STATUS_Pos 8U /*!< PMU OVSSET: Event Counter 8 Overflow Set Position */ +#define PMU_OVSSET_CNT8_STATUS_Msk (1UL << PMU_OVSSET_CNT8_STATUS_Pos) /*!< PMU OVSSET: Event Counter 8 Overflow Set Mask */ + +#define PMU_OVSSET_CNT9_STATUS_Pos 9U /*!< PMU OVSSET: Event Counter 9 Overflow Set Position */ +#define PMU_OVSSET_CNT9_STATUS_Msk (1UL << PMU_OVSSET_CNT9_STATUS_Pos) /*!< PMU OVSSET: Event Counter 9 Overflow Set Mask */ + +#define PMU_OVSSET_CNT10_STATUS_Pos 10U /*!< PMU OVSSET: Event Counter 10 Overflow Set Position */ +#define PMU_OVSSET_CNT10_STATUS_Msk (1UL << PMU_OVSSET_CNT10_STATUS_Pos) /*!< PMU OVSSET: Event Counter 10 Overflow Set Mask */ + +#define PMU_OVSSET_CNT11_STATUS_Pos 11U /*!< PMU OVSSET: Event Counter 11 Overflow Set Position */ +#define PMU_OVSSET_CNT11_STATUS_Msk (1UL << PMU_OVSSET_CNT11_STATUS_Pos) /*!< PMU OVSSET: Event Counter 11 Overflow Set Mask */ + +#define PMU_OVSSET_CNT12_STATUS_Pos 12U /*!< PMU OVSSET: Event Counter 12 Overflow Set Position */ +#define PMU_OVSSET_CNT12_STATUS_Msk (1UL << PMU_OVSSET_CNT12_STATUS_Pos) /*!< PMU OVSSET: Event Counter 12 Overflow Set Mask */ + +#define PMU_OVSSET_CNT13_STATUS_Pos 13U /*!< PMU OVSSET: Event Counter 13 Overflow Set Position */ +#define PMU_OVSSET_CNT13_STATUS_Msk (1UL << PMU_OVSSET_CNT13_STATUS_Pos) /*!< PMU OVSSET: Event Counter 13 Overflow Set Mask */ + +#define PMU_OVSSET_CNT14_STATUS_Pos 14U /*!< PMU OVSSET: Event Counter 14 Overflow Set Position */ +#define PMU_OVSSET_CNT14_STATUS_Msk (1UL << PMU_OVSSET_CNT14_STATUS_Pos) /*!< PMU OVSSET: Event Counter 14 Overflow Set Mask */ + +#define PMU_OVSSET_CNT15_STATUS_Pos 15U /*!< PMU OVSSET: Event Counter 15 Overflow Set Position */ +#define PMU_OVSSET_CNT15_STATUS_Msk (1UL << PMU_OVSSET_CNT15_STATUS_Pos) /*!< PMU OVSSET: Event Counter 15 Overflow Set Mask */ + +#define PMU_OVSSET_CNT16_STATUS_Pos 16U /*!< PMU OVSSET: Event Counter 16 Overflow Set Position */ +#define PMU_OVSSET_CNT16_STATUS_Msk (1UL << PMU_OVSSET_CNT16_STATUS_Pos) /*!< PMU OVSSET: Event Counter 16 Overflow Set Mask */ + +#define PMU_OVSSET_CNT17_STATUS_Pos 17U /*!< PMU OVSSET: Event Counter 17 Overflow Set Position */ +#define PMU_OVSSET_CNT17_STATUS_Msk (1UL << PMU_OVSSET_CNT17_STATUS_Pos) /*!< PMU OVSSET: Event Counter 17 Overflow Set Mask */ + +#define PMU_OVSSET_CNT18_STATUS_Pos 18U /*!< PMU OVSSET: Event Counter 18 Overflow Set Position */ +#define PMU_OVSSET_CNT18_STATUS_Msk (1UL << PMU_OVSSET_CNT18_STATUS_Pos) /*!< PMU OVSSET: Event Counter 18 Overflow Set Mask */ + +#define PMU_OVSSET_CNT19_STATUS_Pos 19U /*!< PMU OVSSET: Event Counter 19 Overflow Set Position */ +#define PMU_OVSSET_CNT19_STATUS_Msk (1UL << PMU_OVSSET_CNT19_STATUS_Pos) /*!< PMU OVSSET: Event Counter 19 Overflow Set Mask */ + +#define PMU_OVSSET_CNT20_STATUS_Pos 20U /*!< PMU OVSSET: Event Counter 20 Overflow Set Position */ +#define PMU_OVSSET_CNT20_STATUS_Msk (1UL << PMU_OVSSET_CNT20_STATUS_Pos) /*!< PMU OVSSET: Event Counter 20 Overflow Set Mask */ + +#define PMU_OVSSET_CNT21_STATUS_Pos 21U /*!< PMU OVSSET: Event Counter 21 Overflow Set Position */ +#define PMU_OVSSET_CNT21_STATUS_Msk (1UL << PMU_OVSSET_CNT21_STATUS_Pos) /*!< PMU OVSSET: Event Counter 21 Overflow Set Mask */ + +#define PMU_OVSSET_CNT22_STATUS_Pos 22U /*!< PMU OVSSET: Event Counter 22 Overflow Set Position */ +#define PMU_OVSSET_CNT22_STATUS_Msk (1UL << PMU_OVSSET_CNT22_STATUS_Pos) /*!< PMU OVSSET: Event Counter 22 Overflow Set Mask */ + +#define PMU_OVSSET_CNT23_STATUS_Pos 23U /*!< PMU OVSSET: Event Counter 23 Overflow Set Position */ +#define PMU_OVSSET_CNT23_STATUS_Msk (1UL << PMU_OVSSET_CNT23_STATUS_Pos) /*!< PMU OVSSET: Event Counter 23 Overflow Set Mask */ + +#define PMU_OVSSET_CNT24_STATUS_Pos 24U /*!< PMU OVSSET: Event Counter 24 Overflow Set Position */ +#define PMU_OVSSET_CNT24_STATUS_Msk (1UL << PMU_OVSSET_CNT24_STATUS_Pos) /*!< PMU OVSSET: Event Counter 24 Overflow Set Mask */ + +#define PMU_OVSSET_CNT25_STATUS_Pos 25U /*!< PMU OVSSET: Event Counter 25 Overflow Set Position */ +#define PMU_OVSSET_CNT25_STATUS_Msk (1UL << PMU_OVSSET_CNT25_STATUS_Pos) /*!< PMU OVSSET: Event Counter 25 Overflow Set Mask */ + +#define PMU_OVSSET_CNT26_STATUS_Pos 26U /*!< PMU OVSSET: Event Counter 26 Overflow Set Position */ +#define PMU_OVSSET_CNT26_STATUS_Msk (1UL << PMU_OVSSET_CNT26_STATUS_Pos) /*!< PMU OVSSET: Event Counter 26 Overflow Set Mask */ + +#define PMU_OVSSET_CNT27_STATUS_Pos 27U /*!< PMU OVSSET: Event Counter 27 Overflow Set Position */ +#define PMU_OVSSET_CNT27_STATUS_Msk (1UL << PMU_OVSSET_CNT27_STATUS_Pos) /*!< PMU OVSSET: Event Counter 27 Overflow Set Mask */ + +#define PMU_OVSSET_CNT28_STATUS_Pos 28U /*!< PMU OVSSET: Event Counter 28 Overflow Set Position */ +#define PMU_OVSSET_CNT28_STATUS_Msk (1UL << PMU_OVSSET_CNT28_STATUS_Pos) /*!< PMU OVSSET: Event Counter 28 Overflow Set Mask */ + +#define PMU_OVSSET_CNT29_STATUS_Pos 29U /*!< PMU OVSSET: Event Counter 29 Overflow Set Position */ +#define PMU_OVSSET_CNT29_STATUS_Msk (1UL << PMU_OVSSET_CNT29_STATUS_Pos) /*!< PMU OVSSET: Event Counter 29 Overflow Set Mask */ + +#define PMU_OVSSET_CNT30_STATUS_Pos 30U /*!< PMU OVSSET: Event Counter 30 Overflow Set Position */ +#define PMU_OVSSET_CNT30_STATUS_Msk (1UL << PMU_OVSSET_CNT30_STATUS_Pos) /*!< PMU OVSSET: Event Counter 30 Overflow Set Mask */ + +#define PMU_OVSSET_CYCCNT_STATUS_Pos 31U /*!< PMU OVSSET: Cycle Counter Overflow Set Position */ +#define PMU_OVSSET_CYCCNT_STATUS_Msk (1UL << PMU_OVSSET_CYCCNT_STATUS_Pos) /*!< PMU OVSSET: Cycle Counter Overflow Set Mask */ + +/** \brief PMU Overflow Flag Status Clear Register Definitions */ + +#define PMU_OVSCLR_CNT0_STATUS_Pos 0U /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Position */ +#define PMU_OVSCLR_CNT0_STATUS_Msk (1UL /*<< PMU_OVSCLR_CNT0_STATUS_Pos*/) /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT1_STATUS_Pos 1U /*!< PMU OVSCLR: Event Counter 1 Overflow Clear Position */ +#define PMU_OVSCLR_CNT1_STATUS_Msk (1UL << PMU_OVSCLR_CNT1_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 1 Overflow Clear */ + +#define PMU_OVSCLR_CNT2_STATUS_Pos 2U /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Position */ +#define PMU_OVSCLR_CNT2_STATUS_Msk (1UL << PMU_OVSCLR_CNT2_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT3_STATUS_Pos 3U /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Position */ +#define PMU_OVSCLR_CNT3_STATUS_Msk (1UL << PMU_OVSCLR_CNT3_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT4_STATUS_Pos 4U /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Position */ +#define PMU_OVSCLR_CNT4_STATUS_Msk (1UL << PMU_OVSCLR_CNT4_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT5_STATUS_Pos 5U /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Position */ +#define PMU_OVSCLR_CNT5_STATUS_Msk (1UL << PMU_OVSCLR_CNT5_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT6_STATUS_Pos 6U /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Position */ +#define PMU_OVSCLR_CNT6_STATUS_Msk (1UL << PMU_OVSCLR_CNT6_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT7_STATUS_Pos 7U /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Position */ +#define PMU_OVSCLR_CNT7_STATUS_Msk (1UL << PMU_OVSCLR_CNT7_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT8_STATUS_Pos 8U /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Position */ +#define PMU_OVSCLR_CNT8_STATUS_Msk (1UL << PMU_OVSCLR_CNT8_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT9_STATUS_Pos 9U /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Position */ +#define PMU_OVSCLR_CNT9_STATUS_Msk (1UL << PMU_OVSCLR_CNT9_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT10_STATUS_Pos 10U /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Position */ +#define PMU_OVSCLR_CNT10_STATUS_Msk (1UL << PMU_OVSCLR_CNT10_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT11_STATUS_Pos 11U /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Position */ +#define PMU_OVSCLR_CNT11_STATUS_Msk (1UL << PMU_OVSCLR_CNT11_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT12_STATUS_Pos 12U /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Position */ +#define PMU_OVSCLR_CNT12_STATUS_Msk (1UL << PMU_OVSCLR_CNT12_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT13_STATUS_Pos 13U /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Position */ +#define PMU_OVSCLR_CNT13_STATUS_Msk (1UL << PMU_OVSCLR_CNT13_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT14_STATUS_Pos 14U /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Position */ +#define PMU_OVSCLR_CNT14_STATUS_Msk (1UL << PMU_OVSCLR_CNT14_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT15_STATUS_Pos 15U /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Position */ +#define PMU_OVSCLR_CNT15_STATUS_Msk (1UL << PMU_OVSCLR_CNT15_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT16_STATUS_Pos 16U /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Position */ +#define PMU_OVSCLR_CNT16_STATUS_Msk (1UL << PMU_OVSCLR_CNT16_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT17_STATUS_Pos 17U /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Position */ +#define PMU_OVSCLR_CNT17_STATUS_Msk (1UL << PMU_OVSCLR_CNT17_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT18_STATUS_Pos 18U /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Position */ +#define PMU_OVSCLR_CNT18_STATUS_Msk (1UL << PMU_OVSCLR_CNT18_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT19_STATUS_Pos 19U /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Position */ +#define PMU_OVSCLR_CNT19_STATUS_Msk (1UL << PMU_OVSCLR_CNT19_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT20_STATUS_Pos 20U /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Position */ +#define PMU_OVSCLR_CNT20_STATUS_Msk (1UL << PMU_OVSCLR_CNT20_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT21_STATUS_Pos 21U /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Position */ +#define PMU_OVSCLR_CNT21_STATUS_Msk (1UL << PMU_OVSCLR_CNT21_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT22_STATUS_Pos 22U /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Position */ +#define PMU_OVSCLR_CNT22_STATUS_Msk (1UL << PMU_OVSCLR_CNT22_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT23_STATUS_Pos 23U /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Position */ +#define PMU_OVSCLR_CNT23_STATUS_Msk (1UL << PMU_OVSCLR_CNT23_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT24_STATUS_Pos 24U /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Position */ +#define PMU_OVSCLR_CNT24_STATUS_Msk (1UL << PMU_OVSCLR_CNT24_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT25_STATUS_Pos 25U /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Position */ +#define PMU_OVSCLR_CNT25_STATUS_Msk (1UL << PMU_OVSCLR_CNT25_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT26_STATUS_Pos 26U /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Position */ +#define PMU_OVSCLR_CNT26_STATUS_Msk (1UL << PMU_OVSCLR_CNT26_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT27_STATUS_Pos 27U /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Position */ +#define PMU_OVSCLR_CNT27_STATUS_Msk (1UL << PMU_OVSCLR_CNT27_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT28_STATUS_Pos 28U /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Position */ +#define PMU_OVSCLR_CNT28_STATUS_Msk (1UL << PMU_OVSCLR_CNT28_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT29_STATUS_Pos 29U /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Position */ +#define PMU_OVSCLR_CNT29_STATUS_Msk (1UL << PMU_OVSCLR_CNT29_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT30_STATUS_Pos 30U /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Position */ +#define PMU_OVSCLR_CNT30_STATUS_Msk (1UL << PMU_OVSCLR_CNT30_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Mask */ + +#define PMU_OVSCLR_CYCCNT_STATUS_Pos 31U /*!< PMU OVSCLR: Cycle Counter Overflow Clear Position */ +#define PMU_OVSCLR_CYCCNT_STATUS_Msk (1UL << PMU_OVSCLR_CYCCNT_STATUS_Pos) /*!< PMU OVSCLR: Cycle Counter Overflow Clear Mask */ + +/** \brief PMU Software Increment Counter */ + +#define PMU_SWINC_CNT0_Pos 0U /*!< PMU SWINC: Event Counter 0 Software Increment Position */ +#define PMU_SWINC_CNT0_Msk (1UL /*<< PMU_SWINC_CNT0_Pos */) /*!< PMU SWINC: Event Counter 0 Software Increment Mask */ + +#define PMU_SWINC_CNT1_Pos 1U /*!< PMU SWINC: Event Counter 1 Software Increment Position */ +#define PMU_SWINC_CNT1_Msk (1UL << PMU_SWINC_CNT1_Pos) /*!< PMU SWINC: Event Counter 1 Software Increment Mask */ + +#define PMU_SWINC_CNT2_Pos 2U /*!< PMU SWINC: Event Counter 2 Software Increment Position */ +#define PMU_SWINC_CNT2_Msk (1UL << PMU_SWINC_CNT2_Pos) /*!< PMU SWINC: Event Counter 2 Software Increment Mask */ + +#define PMU_SWINC_CNT3_Pos 3U /*!< PMU SWINC: Event Counter 3 Software Increment Position */ +#define PMU_SWINC_CNT3_Msk (1UL << PMU_SWINC_CNT3_Pos) /*!< PMU SWINC: Event Counter 3 Software Increment Mask */ + +#define PMU_SWINC_CNT4_Pos 4U /*!< PMU SWINC: Event Counter 4 Software Increment Position */ +#define PMU_SWINC_CNT4_Msk (1UL << PMU_SWINC_CNT4_Pos) /*!< PMU SWINC: Event Counter 4 Software Increment Mask */ + +#define PMU_SWINC_CNT5_Pos 5U /*!< PMU SWINC: Event Counter 5 Software Increment Position */ +#define PMU_SWINC_CNT5_Msk (1UL << PMU_SWINC_CNT5_Pos) /*!< PMU SWINC: Event Counter 5 Software Increment Mask */ + +#define PMU_SWINC_CNT6_Pos 6U /*!< PMU SWINC: Event Counter 6 Software Increment Position */ +#define PMU_SWINC_CNT6_Msk (1UL << PMU_SWINC_CNT6_Pos) /*!< PMU SWINC: Event Counter 6 Software Increment Mask */ + +#define PMU_SWINC_CNT7_Pos 7U /*!< PMU SWINC: Event Counter 7 Software Increment Position */ +#define PMU_SWINC_CNT7_Msk (1UL << PMU_SWINC_CNT7_Pos) /*!< PMU SWINC: Event Counter 7 Software Increment Mask */ + +#define PMU_SWINC_CNT8_Pos 8U /*!< PMU SWINC: Event Counter 8 Software Increment Position */ +#define PMU_SWINC_CNT8_Msk (1UL << PMU_SWINC_CNT8_Pos) /*!< PMU SWINC: Event Counter 8 Software Increment Mask */ + +#define PMU_SWINC_CNT9_Pos 9U /*!< PMU SWINC: Event Counter 9 Software Increment Position */ +#define PMU_SWINC_CNT9_Msk (1UL << PMU_SWINC_CNT9_Pos) /*!< PMU SWINC: Event Counter 9 Software Increment Mask */ + +#define PMU_SWINC_CNT10_Pos 10U /*!< PMU SWINC: Event Counter 10 Software Increment Position */ +#define PMU_SWINC_CNT10_Msk (1UL << PMU_SWINC_CNT10_Pos) /*!< PMU SWINC: Event Counter 10 Software Increment Mask */ + +#define PMU_SWINC_CNT11_Pos 11U /*!< PMU SWINC: Event Counter 11 Software Increment Position */ +#define PMU_SWINC_CNT11_Msk (1UL << PMU_SWINC_CNT11_Pos) /*!< PMU SWINC: Event Counter 11 Software Increment Mask */ + +#define PMU_SWINC_CNT12_Pos 12U /*!< PMU SWINC: Event Counter 12 Software Increment Position */ +#define PMU_SWINC_CNT12_Msk (1UL << PMU_SWINC_CNT12_Pos) /*!< PMU SWINC: Event Counter 12 Software Increment Mask */ + +#define PMU_SWINC_CNT13_Pos 13U /*!< PMU SWINC: Event Counter 13 Software Increment Position */ +#define PMU_SWINC_CNT13_Msk (1UL << PMU_SWINC_CNT13_Pos) /*!< PMU SWINC: Event Counter 13 Software Increment Mask */ + +#define PMU_SWINC_CNT14_Pos 14U /*!< PMU SWINC: Event Counter 14 Software Increment Position */ +#define PMU_SWINC_CNT14_Msk (1UL << PMU_SWINC_CNT14_Pos) /*!< PMU SWINC: Event Counter 14 Software Increment Mask */ + +#define PMU_SWINC_CNT15_Pos 15U /*!< PMU SWINC: Event Counter 15 Software Increment Position */ +#define PMU_SWINC_CNT15_Msk (1UL << PMU_SWINC_CNT15_Pos) /*!< PMU SWINC: Event Counter 15 Software Increment Mask */ + +#define PMU_SWINC_CNT16_Pos 16U /*!< PMU SWINC: Event Counter 16 Software Increment Position */ +#define PMU_SWINC_CNT16_Msk (1UL << PMU_SWINC_CNT16_Pos) /*!< PMU SWINC: Event Counter 16 Software Increment Mask */ + +#define PMU_SWINC_CNT17_Pos 17U /*!< PMU SWINC: Event Counter 17 Software Increment Position */ +#define PMU_SWINC_CNT17_Msk (1UL << PMU_SWINC_CNT17_Pos) /*!< PMU SWINC: Event Counter 17 Software Increment Mask */ + +#define PMU_SWINC_CNT18_Pos 18U /*!< PMU SWINC: Event Counter 18 Software Increment Position */ +#define PMU_SWINC_CNT18_Msk (1UL << PMU_SWINC_CNT18_Pos) /*!< PMU SWINC: Event Counter 18 Software Increment Mask */ + +#define PMU_SWINC_CNT19_Pos 19U /*!< PMU SWINC: Event Counter 19 Software Increment Position */ +#define PMU_SWINC_CNT19_Msk (1UL << PMU_SWINC_CNT19_Pos) /*!< PMU SWINC: Event Counter 19 Software Increment Mask */ + +#define PMU_SWINC_CNT20_Pos 20U /*!< PMU SWINC: Event Counter 20 Software Increment Position */ +#define PMU_SWINC_CNT20_Msk (1UL << PMU_SWINC_CNT20_Pos) /*!< PMU SWINC: Event Counter 20 Software Increment Mask */ + +#define PMU_SWINC_CNT21_Pos 21U /*!< PMU SWINC: Event Counter 21 Software Increment Position */ +#define PMU_SWINC_CNT21_Msk (1UL << PMU_SWINC_CNT21_Pos) /*!< PMU SWINC: Event Counter 21 Software Increment Mask */ + +#define PMU_SWINC_CNT22_Pos 22U /*!< PMU SWINC: Event Counter 22 Software Increment Position */ +#define PMU_SWINC_CNT22_Msk (1UL << PMU_SWINC_CNT22_Pos) /*!< PMU SWINC: Event Counter 22 Software Increment Mask */ + +#define PMU_SWINC_CNT23_Pos 23U /*!< PMU SWINC: Event Counter 23 Software Increment Position */ +#define PMU_SWINC_CNT23_Msk (1UL << PMU_SWINC_CNT23_Pos) /*!< PMU SWINC: Event Counter 23 Software Increment Mask */ + +#define PMU_SWINC_CNT24_Pos 24U /*!< PMU SWINC: Event Counter 24 Software Increment Position */ +#define PMU_SWINC_CNT24_Msk (1UL << PMU_SWINC_CNT24_Pos) /*!< PMU SWINC: Event Counter 24 Software Increment Mask */ + +#define PMU_SWINC_CNT25_Pos 25U /*!< PMU SWINC: Event Counter 25 Software Increment Position */ +#define PMU_SWINC_CNT25_Msk (1UL << PMU_SWINC_CNT25_Pos) /*!< PMU SWINC: Event Counter 25 Software Increment Mask */ + +#define PMU_SWINC_CNT26_Pos 26U /*!< PMU SWINC: Event Counter 26 Software Increment Position */ +#define PMU_SWINC_CNT26_Msk (1UL << PMU_SWINC_CNT26_Pos) /*!< PMU SWINC: Event Counter 26 Software Increment Mask */ + +#define PMU_SWINC_CNT27_Pos 27U /*!< PMU SWINC: Event Counter 27 Software Increment Position */ +#define PMU_SWINC_CNT27_Msk (1UL << PMU_SWINC_CNT27_Pos) /*!< PMU SWINC: Event Counter 27 Software Increment Mask */ + +#define PMU_SWINC_CNT28_Pos 28U /*!< PMU SWINC: Event Counter 28 Software Increment Position */ +#define PMU_SWINC_CNT28_Msk (1UL << PMU_SWINC_CNT28_Pos) /*!< PMU SWINC: Event Counter 28 Software Increment Mask */ + +#define PMU_SWINC_CNT29_Pos 29U /*!< PMU SWINC: Event Counter 29 Software Increment Position */ +#define PMU_SWINC_CNT29_Msk (1UL << PMU_SWINC_CNT29_Pos) /*!< PMU SWINC: Event Counter 29 Software Increment Mask */ + +#define PMU_SWINC_CNT30_Pos 30U /*!< PMU SWINC: Event Counter 30 Software Increment Position */ +#define PMU_SWINC_CNT30_Msk (1UL << PMU_SWINC_CNT30_Pos) /*!< PMU SWINC: Event Counter 30 Software Increment Mask */ + +/** \brief PMU Control Register Definitions */ + +#define PMU_CTRL_ENABLE_Pos 0U /*!< PMU CTRL: ENABLE Position */ +#define PMU_CTRL_ENABLE_Msk (1UL /*<< PMU_CTRL_ENABLE_Pos*/) /*!< PMU CTRL: ENABLE Mask */ + +#define PMU_CTRL_EVENTCNT_RESET_Pos 1U /*!< PMU CTRL: Event Counter Reset Position */ +#define PMU_CTRL_EVENTCNT_RESET_Msk (1UL << PMU_CTRL_EVENTCNT_RESET_Pos) /*!< PMU CTRL: Event Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_RESET_Pos 2U /*!< PMU CTRL: Cycle Counter Reset Position */ +#define PMU_CTRL_CYCCNT_RESET_Msk (1UL << PMU_CTRL_CYCCNT_RESET_Pos) /*!< PMU CTRL: Cycle Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_DISABLE_Pos 5U /*!< PMU CTRL: Disable Cycle Counter Position */ +#define PMU_CTRL_CYCCNT_DISABLE_Msk (1UL << PMU_CTRL_CYCCNT_DISABLE_Pos) /*!< PMU CTRL: Disable Cycle Counter Mask */ + +#define PMU_CTRL_FRZ_ON_OV_Pos 9U /*!< PMU CTRL: Freeze-on-overflow Position */ +#define PMU_CTRL_FRZ_ON_OV_Msk (1UL << PMU_CTRL_FRZ_ON_OVERFLOW_Pos) /*!< PMU CTRL: Freeze-on-overflow Mask */ + +#define PMU_CTRL_TRACE_ON_OV_Pos 11U /*!< PMU CTRL: Trace-on-overflow Position */ +#define PMU_CTRL_TRACE_ON_OV_Msk (1UL << PMU_CTRL_TRACE_ON_OVERFLOW_Pos) /*!< PMU CTRL: Trace-on-overflow Mask */ + +/** \brief PMU Type Register Definitions */ + +#define PMU_TYPE_NUM_CNTS_Pos 0U /*!< PMU TYPE: Number of Counters Position */ +#define PMU_TYPE_NUM_CNTS_Msk (0xFFUL /*<< PMU_TYPE_NUM_CNTS_Pos*/) /*!< PMU TYPE: Number of Counters Mask */ + +#define PMU_TYPE_SIZE_CNTS_Pos 8U /*!< PMU TYPE: Size of Counters Position */ +#define PMU_TYPE_SIZE_CNTS_Msk (0x3FUL << PMU_TYPE_SIZE_CNTS_Pos) /*!< PMU TYPE: Size of Counters Mask */ + +#define PMU_TYPE_CYCCNT_PRESENT_Pos 14U /*!< PMU TYPE: Cycle Counter Present Position */ +#define PMU_TYPE_CYCCNT_PRESENT_Msk (1UL << PMU_TYPE_CYCCNT_PRESENT_Pos) /*!< PMU TYPE: Cycle Counter Present Mask */ + +#define PMU_TYPE_FRZ_OV_SUPPORT_Pos 21U /*!< PMU TYPE: Freeze-on-overflow Support Position */ +#define PMU_TYPE_FRZ_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Freeze-on-overflow Support Mask */ + +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Pos 23U /*!< PMU TYPE: Trace-on-overflow Support Position */ +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Trace-on-overflow Support Mask */ + +/** \brief PMU Authentication Status Register Definitions */ + +#define PMU_AUTHSTATUS_NSID_Pos 0U /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSID_Msk (0x3UL /*<< PMU_AUTHSTATUS_NSID_Pos*/) /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSNID_Pos 2U /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSNID_Msk (0x3UL << PMU_AUTHSTATUS_NSNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SID_Pos 4U /*!< PMU AUTHSTATUS: Secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_SID_Msk (0x3UL << PMU_AUTHSTATUS_SID_Pos) /*!< PMU AUTHSTATUS: Secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SNID_Pos 6U /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SNID_Msk (0x3UL << PMU_AUTHSTATUS_SNID_Pos) /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUID_Pos 16U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUID_Msk (0x3UL << PMU_AUTHSTATUS_NSUID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUNID_Pos 18U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUNID_Msk (0x3UL << PMU_AUTHSTATUS_NSUNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUID_Pos 20U /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_SUID_Msk (0x3UL << PMU_AUTHSTATUS_SUID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUNID_Pos 22U /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SUNID_Msk (0x3UL << PMU_AUTHSTATUS_SUNID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Mask */ + + +/*@} end of group CMSIS_PMU */ +#endif + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +#define FPU_FPDSCR_FZ16_Pos 19U /*!< FPDSCR: FZ16 bit Position */ +#define FPU_FPDSCR_FZ16_Msk (1UL << FPU_FPDSCR_FZ16_Pos) /*!< FPDSCR: FZ16 bit Mask */ + +#define FPU_FPDSCR_LTPSIZE_Pos 16U /*!< FPDSCR: LTPSIZE bit Position */ +#define FPU_FPDSCR_LTPSIZE_Msk (7UL << FPU_FPDSCR_LTPSIZE_Pos) /*!< FPDSCR: LTPSIZE bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FPRound_Pos 28U /*!< MVFR0: FPRound bits Position */ +#define FPU_MVFR0_FPRound_Msk (0xFUL << FPU_MVFR0_FPRound_Pos) /*!< MVFR0: FPRound bits Mask */ + +#define FPU_MVFR0_FPSqrt_Pos 20U /*!< MVFR0: FPSqrt bits Position */ +#define FPU_MVFR0_FPSqrt_Msk (0xFUL << FPU_MVFR0_FPSqrt_Pos) /*!< MVFR0: FPSqrt bits Mask */ + +#define FPU_MVFR0_FPDivide_Pos 16U /*!< MVFR0: FPDivide bits Position */ +#define FPU_MVFR0_FPDivide_Msk (0xFUL << FPU_MVFR0_FPDivide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FPDP_Pos 8U /*!< MVFR0: FPDP bits Position */ +#define FPU_MVFR0_FPDP_Msk (0xFUL << FPU_MVFR0_FPDP_Pos) /*!< MVFR0: FPDP bits Mask */ + +#define FPU_MVFR0_FPSP_Pos 4U /*!< MVFR0: FPSP bits Position */ +#define FPU_MVFR0_FPSP_Msk (0xFUL << FPU_MVFR0_FPSP_Pos) /*!< MVFR0: FPSP bits Mask */ + +#define FPU_MVFR0_SIMDReg_Pos 0U /*!< MVFR0: SIMDReg bits Position */ +#define FPU_MVFR0_SIMDReg_Msk (0xFUL /*<< FPU_MVFR0_SIMDReg_Pos*/) /*!< MVFR0: SIMDReg bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FMAC_Pos 28U /*!< MVFR1: FMAC bits Position */ +#define FPU_MVFR1_FMAC_Msk (0xFUL << FPU_MVFR1_FMAC_Pos) /*!< MVFR1: FMAC bits Mask */ + +#define FPU_MVFR1_FPHP_Pos 24U /*!< MVFR1: FPHP bits Position */ +#define FPU_MVFR1_FPHP_Msk (0xFUL << FPU_MVFR1_FPHP_Pos) /*!< MVFR1: FPHP bits Mask */ + +#define FPU_MVFR1_FP16_Pos 20U /*!< MVFR1: FP16 bits Position */ +#define FPU_MVFR1_FP16_Msk (0xFUL << FPU_MVFR1_FP16_Pos) /*!< MVFR1: FP16 bits Mask */ + +#define FPU_MVFR1_MVE_Pos 8U /*!< MVFR1: MVE bits Position */ +#define FPU_MVFR1_MVE_Msk (0xFUL << FPU_MVFR1_MVE_Pos) /*!< MVFR1: MVE bits Mask */ + +#define FPU_MVFR1_FPDNaN_Pos 4U /*!< MVFR1: FPDNaN bits Position */ +#define FPU_MVFR1_FPDNaN_Msk (0xFUL << FPU_MVFR1_FPDNaN_Pos) /*!< MVFR1: FPDNaN bits Mask */ + +#define FPU_MVFR1_FPFtZ_Pos 0U /*!< MVFR1: FPFtZ bits Position */ +#define FPU_MVFR1_FPFtZ_Msk (0xFUL /*<< FPU_MVFR1_FPFtZ_Pos*/) /*!< MVFR1: FPFtZ bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_FPD_Pos 23U /*!< \deprecated CoreDebug DHCSR: S_FPD Position */ +#define CoreDebug_DHCSR_S_FPD_Msk (1UL << CoreDebug_DHCSR_S_FPD_Pos) /*!< \deprecated CoreDebug DHCSR: S_FPD Mask */ + +#define CoreDebug_DHCSR_S_SUIDE_Pos 22U /*!< \deprecated CoreDebug DHCSR: S_SUIDE Position */ +#define CoreDebug_DHCSR_S_SUIDE_Msk (1UL << CoreDebug_DHCSR_S_SUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SUIDE Mask */ + +#define CoreDebug_DHCSR_S_NSUIDE_Pos 21U /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Position */ +#define CoreDebug_DHCSR_S_NSUIDE_Msk (1UL << CoreDebug_DHCSR_S_NSUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Mask */ + +#define CoreDebug_DHCSR_S_SDE_Pos 20U /*!< \deprecated CoreDebug DHCSR: S_SDE Position */ +#define CoreDebug_DHCSR_S_SDE_Msk (1UL << CoreDebug_DHCSR_S_SDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SDE Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_PMOV_Pos 6U /*!< \deprecated CoreDebug DHCSR: C_PMOV Position */ +#define CoreDebug_DHCSR_C_PMOV_Msk (1UL << CoreDebug_DHCSR_C_PMOV_Pos) /*!< \deprecated CoreDebug DHCSR: C_PMOV Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Set Clear Exception and Monitor Control Register Definitions */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_REQ_Pos 3U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_SET_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_PEND_Pos 1U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_SET_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_UIDEN_Pos 10U /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_UIDAPEN_Pos 9U /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDAPEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDAPEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Mask */ + +#define CoreDebug_DAUTHCTRL_FSDMA_Pos 8U /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Position */ +#define CoreDebug_DAUTHCTRL_FSDMA_Msk (1UL << CoreDebug_DAUTHCTRL_FSDMA_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_FPD_Pos 23U /*!< DCB DHCSR: Floating-point registers Debuggable Position */ +#define DCB_DHCSR_S_FPD_Msk (0x1UL << DCB_DHCSR_S_FPD_Pos) /*!< DCB DHCSR: Floating-point registers Debuggable Mask */ + +#define DCB_DHCSR_S_SUIDE_Pos 22U /*!< DCB DHCSR: Secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_SUIDE_Msk (0x1UL << DCB_DHCSR_S_SUIDE_Pos) /*!< DCB DHCSR: Secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_NSUIDE_Pos 21U /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_NSUIDE_Msk (0x1UL << DCB_DHCSR_S_NSUIDE_Pos) /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_PMOV_Pos 6U /*!< DCB DHCSR: Halt on PMU overflow control Position */ +#define DCB_DHCSR_C_PMOV_Msk (0x1UL << DCB_DHCSR_C_PMOV_Pos) /*!< DCB DHCSR: Halt on PMU overflow control Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DSCEMCR, Debug Set Clear Exception and Monitor Control Register Definitions */ +#define DCB_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< DCB DSCEMCR: Clear monitor request Position */ +#define DCB_DSCEMCR_CLR_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_REQ_Pos) /*!< DCB DSCEMCR: Clear monitor request Mask */ + +#define DCB_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< DCB DSCEMCR: Clear monitor pend Position */ +#define DCB_DSCEMCR_CLR_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_PEND_Pos) /*!< DCB DSCEMCR: Clear monitor pend Mask */ + +#define DCB_DSCEMCR_SET_MON_REQ_Pos 3U /*!< DCB DSCEMCR: Set monitor request Position */ +#define DCB_DSCEMCR_SET_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_SET_MON_REQ_Pos) /*!< DCB DSCEMCR: Set monitor request Mask */ + +#define DCB_DSCEMCR_SET_MON_PEND_Pos 1U /*!< DCB DSCEMCR: Set monitor pend Position */ +#define DCB_DSCEMCR_SET_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_SET_MON_PEND_Pos) /*!< DCB DSCEMCR: Set monitor pend Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_UIDEN_Pos 10U /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Position */ +#define DCB_DAUTHCTRL_UIDEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Mask */ + +#define DCB_DAUTHCTRL_UIDAPEN_Pos 9U /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Position */ +#define DCB_DAUTHCTRL_UIDAPEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDAPEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Mask */ + +#define DCB_DAUTHCTRL_FSDMA_Pos 8U /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Position */ +#define DCB_DAUTHCTRL_FSDMA_Msk (0x1UL << DCB_DAUTHCTRL_FSDMA_Pos) /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Mask */ + +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SUNID_Pos 22U /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUNID_Msk (0x3UL << DIB_DAUTHSTATUS_SUNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SUID_Pos 20U /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUID_Msk (0x3UL << DIB_DAUTHSTATUS_SUID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_NSUNID_Pos 18U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Position */ +#define DIB_DAUTHSTATUS_NSUNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Mask */ + +#define DIB_DAUTHSTATUS_NSUID_Pos 16U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_NSUID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define MEMSYSCTL_BASE (0xE001E000UL) /*!< Memory System Control Base Address */ + #define ERRBNK_BASE (0xE001E100UL) /*!< Error Banking Base Address */ + #define PWRMODCTL_BASE (0xE001E300UL) /*!< Power Mode Control Base Address */ + #define EWIC_BASE (0xE001E400UL) /*!< External Wakeup Interrupt Controller Base Address */ + #define PRCCFGINF_BASE (0xE001E700UL) /*!< Processor Configuration Information Base Address */ + #define STL_BASE (0xE001E800UL) /*!< Software Test Library Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define ICB ((ICB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define MEMSYSCTL ((MemSysCtl_Type *) MEMSYSCTL_BASE ) /*!< Memory System Control configuration struct */ + #define ERRBNK ((ErrBnk_Type *) ERRBNK_BASE ) /*!< Error Banking configuration struct */ + #define PWRMODCTL ((PwrModCtl_Type *) PWRMODCTL_BASE ) /*!< Power Mode Control configuration struct */ + #define EWIC ((EWIC_Type *) EWIC_BASE ) /*!< EWIC configuration struct */ + #define PRCCFGINF ((PrcCfgInf_Type *) PRCCFGINF_BASE ) /*!< Processor Configuration Information configuration struct */ + #define STL ((STL_Type *) STL_BASE ) /*!< Software Test Library configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + #define PMU_BASE (0xE0003000UL) /*!< PMU Base Address */ + #define PMU ((PMU_Type *) PMU_BASE ) /*!< PMU configuration struct */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define ICB_NS ((ICB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ + +/* 'SCnSCB' is deprecated and replaced by 'ICB' */ +typedef ICB_Type SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISCRITAXIRUW_Pos (ICB_ACTLR_DISCRITAXIRUW_Pos) +#define SCnSCB_ACTLR_DISCRITAXIRUW_Msk (ICB_ACTLR_DISCRITAXIRUW_Msk) + +#define SCnSCB_ACTLR_DISDI_Pos (ICB_ACTLR_DISDI_Pos) +#define SCnSCB_ACTLR_DISDI_Msk (ICB_ACTLR_DISDI_Msk) + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos (ICB_ACTLR_DISCRITAXIRUR_Pos) +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (ICB_ACTLR_DISCRITAXIRUR_Msk) + +#define SCnSCB_ACTLR_EVENTBUSEN_Pos (ICB_ACTLR_EVENTBUSEN_Pos) +#define SCnSCB_ACTLR_EVENTBUSEN_Msk (ICB_ACTLR_EVENTBUSEN_Msk) + +#define SCnSCB_ACTLR_EVENTBUSEN_S_Pos (ICB_ACTLR_EVENTBUSEN_S_Pos) +#define SCnSCB_ACTLR_EVENTBUSEN_S_Msk (ICB_ACTLR_EVENTBUSEN_S_Msk) + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos (ICB_ACTLR_DISITMATBFLUSH_Pos) +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (ICB_ACTLR_DISITMATBFLUSH_Msk) + +#define SCnSCB_ACTLR_DISNWAMODE_Pos (ICB_ACTLR_DISNWAMODE_Pos) +#define SCnSCB_ACTLR_DISNWAMODE_Msk (ICB_ACTLR_DISNWAMODE_Msk) + +#define SCnSCB_ACTLR_FPEXCODIS_Pos (ICB_ACTLR_FPEXCODIS_Pos) +#define SCnSCB_ACTLR_FPEXCODIS_Msk (ICB_ACTLR_FPEXCODIS_Msk) + +#define SCnSCB_ACTLR_DISOLAP_Pos (ICB_ACTLR_DISOLAP_Pos) +#define SCnSCB_ACTLR_DISOLAP_Msk (ICB_ACTLR_DISOLAP_Msk) + +#define SCnSCB_ACTLR_DISOLAPS_Pos (ICB_ACTLR_DISOLAPS_Pos) +#define SCnSCB_ACTLR_DISOLAPS_Msk (ICB_ACTLR_DISOLAPS_Msk) + +#define SCnSCB_ACTLR_DISLOBR_Pos (ICB_ACTLR_DISLOBR_Pos) +#define SCnSCB_ACTLR_DISLOBR_Msk (ICB_ACTLR_DISLOBR_Msk) + +#define SCnSCB_ACTLR_DISLO_Pos (ICB_ACTLR_DISLO_Pos) +#define SCnSCB_ACTLR_DISLO_Msk (ICB_ACTLR_DISLO_Msk) + +#define SCnSCB_ACTLR_DISLOLEP_Pos (ICB_ACTLR_DISLOLEP_Pos) +#define SCnSCB_ACTLR_DISLOLEP_Msk (ICB_ACTLR_DISLOLEP_Msk) + +#define SCnSCB_ACTLR_DISFOLD_Pos (ICB_ACTLR_DISFOLD_Pos) +#define SCnSCB_ACTLR_DISFOLD_Msk (ICB_ACTLR_DISFOLD_Msk) + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos (ICB_ICTR_INTLINESNUM_Pos) +#define SCnSCB_ICTR_INTLINESNUM_Msk (ICB_ICTR_INTLINESNUM_Msk) + +#define SCnSCB (ICB) +#define SCnSCB_NS (ICB_NS) + +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## PMU functions and events #################################### */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + +#include "pmu_armv8.h" + +/** + \brief Cortex-M55 PMU events + \note Architectural PMU events can be found in pmu_armv8.h +*/ + +#define ARMCM55_PMU_ECC_ERR 0xC000 /*!< Any ECC error */ +#define ARMCM55_PMU_ECC_ERR_FATAL 0xC001 /*!< Any fatal ECC error */ +#define ARMCM55_PMU_ECC_ERR_DCACHE 0xC010 /*!< Any ECC error in the data cache */ +#define ARMCM55_PMU_ECC_ERR_ICACHE 0xC011 /*!< Any ECC error in the instruction cache */ +#define ARMCM55_PMU_ECC_ERR_FATAL_DCACHE 0xC012 /*!< Any fatal ECC error in the data cache */ +#define ARMCM55_PMU_ECC_ERR_FATAL_ICACHE 0xC013 /*!< Any fatal ECC error in the instruction cache*/ +#define ARMCM55_PMU_ECC_ERR_DTCM 0xC020 /*!< Any ECC error in the DTCM */ +#define ARMCM55_PMU_ECC_ERR_ITCM 0xC021 /*!< Any ECC error in the ITCM */ +#define ARMCM55_PMU_ECC_ERR_FATAL_DTCM 0xC022 /*!< Any fatal ECC error in the DTCM */ +#define ARMCM55_PMU_ECC_ERR_FATAL_ITCM 0xC023 /*!< Any fatal ECC error in the ITCM */ +#define ARMCM55_PMU_PF_LINEFILL 0xC100 /*!< A prefetcher starts a line-fill */ +#define ARMCM55_PMU_PF_CANCEL 0xC101 /*!< A prefetcher stops prefetching */ +#define ARMCM55_PMU_PF_DROP_LINEFILL 0xC102 /*!< A linefill triggered by a prefetcher has been dropped because of lack of buffering */ +#define ARMCM55_PMU_NWAMODE_ENTER 0xC200 /*!< No write-allocate mode entry */ +#define ARMCM55_PMU_NWAMODE 0xC201 /*!< Write-allocate store is not allocated into the data cache due to no-write-allocate mode */ +#define ARMCM55_PMU_SAHB_ACCESS 0xC300 /*!< Read or write access on the S-AHB interface to the TCM */ +#define ARMCM55_PMU_PAHB_ACCESS 0xC301 /*!< Read or write access to the P-AHB write interface */ +#define ARMCM55_PMU_AXI_WRITE_ACCESS 0xC302 /*!< Any beat access to M-AXI write interface */ +#define ARMCM55_PMU_AXI_READ_ACCESS 0xC303 /*!< Any beat access to M-AXI read interface */ +#define ARMCM55_PMU_DOSTIMEOUT_DOUBLE 0xC400 /*!< Denial of Service timeout has fired twice and caused buffers to drain to allow forward progress */ +#define ARMCM55_PMU_DOSTIMEOUT_TRIPLE 0xC401 /*!< Denial of Service timeout has fired three times and blocked the LSU to force forward progress */ + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + +/* ########################## MVE functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_MveFunctions MVE Functions + \brief Function that provides MVE type. + @{ + */ + +/** + \brief get MVE type + \details returns the MVE type + \returns + - \b 0: No Vector Extension (MVE) + - \b 1: Integer Vector Extension (MVE-I) + - \b 2: Floating-point Vector Extension (MVE-F) + */ +__STATIC_INLINE uint32_t SCB_GetMVEType(void) +{ + const uint32_t mvfr1 = FPU->MVFR1; + if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x2U << FPU_MVFR1_MVE_Pos)) + { + return 2U; + } + else if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x1U << FPU_MVFR1_MVE_Pos)) + { + return 1U; + } + else + { + return 0U; + } +} + + +/*@} end of CMSIS_Core_MveFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM55_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm7.h b/Drivers/CMSIS/Core/Include/core_cm7.h new file mode 100644 index 0000000..8a4ea3e --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm7.h @@ -0,0 +1,2366 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.1.6 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ + uint32_t RESERVED7[5U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< \deprecated SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< \deprecated SCB CACR: ECCEN Mask */ + +#define SCB_CACR_ECCDIS_Pos 1U /*!< SCB CACR: ECCDIS Position */ +#define SCB_CACR_ECCDIS_Msk (1UL << SCB_CACR_ECCDIS_Pos) /*!< SCB CACR: ECCDIS Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBSCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBSCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBSCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ +#define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ + +#define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ +#define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ + +#define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ +#define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ + +#define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ +#define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + +/*@} end of CMSIS_Core_FpuFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_cm85.h b/Drivers/CMSIS/Core/Include/core_cm85.h new file mode 100644 index 0000000..5fbb289 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_cm85.h @@ -0,0 +1,4672 @@ +/**************************************************************************//** + * @file core_cm85.h + * @brief CMSIS Cortex-M85 Core Peripheral Access Layer Header File + * @version V1.0.4 + * @date 21. April 2022 + ******************************************************************************/ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM85_H_GENERIC +#define __CORE_CM85_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M85 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM85 definitions */ + +#define __CORTEX_M (85U) /*!< Cortex-M Core */ + +#if defined ( __CC_ARM ) + #error Legacy Arm Compiler does not support Armv8.1-M target architecture. +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM85_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM85_H_DEPENDANT +#define __CORE_CM85_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM85_REV + #define __CM85_REV 0x0001U + #warning "__CM85_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #if __FPU_PRESENT != 0U + #ifndef __FPU_DP + #define __FPU_DP 0U + #warning "__FPU_DP not defined in device header file; using default!" + #endif + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __PMU_PRESENT + #define __PMU_PRESENT 0U + #warning "__PMU_PRESENT not defined in device header file; using default!" + #endif + + #if __PMU_PRESENT != 0U + #ifndef __PMU_NUM_EVENTCNT + #define __PMU_NUM_EVENTCNT 8U + #warning "__PMU_NUM_EVENTCNT not defined in device header file; using default!" + #elif (__PMU_NUM_EVENTCNT > 8 || __PMU_NUM_EVENTCNT < 2) + #error "__PMU_NUM_EVENTCNT is out of range in device header file!" */ + #endif + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M85 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core EWIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core PMU Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:1; /*!< bit: 20 Reserved */ + uint32_t B:1; /*!< bit: 21 BTI active (read 0) */ + uint32_t _reserved2:2; /*!< bit: 22..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_B_Pos 21U /*!< xPSR: B Position */ +#define xPSR_B_Msk (1UL << xPSR_B_Pos) /*!< xPSR: B Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t BTI_EN:1; /*!< bit: 4 Privileged branch target identification enable */ + uint32_t UBTI_EN:1; /*!< bit: 5 Unprivileged branch target identification enable */ + uint32_t PAC_EN:1; /*!< bit: 6 Privileged pointer authentication enable */ + uint32_t UPAC_EN:1; /*!< bit: 7 Unprivileged pointer authentication enable */ + uint32_t _reserved1:24; /*!< bit: 8..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_UPAC_EN_Pos 7U /*!< CONTROL: UPAC_EN Position */ +#define CONTROL_UPAC_EN_Msk (1UL << CONTROL_UPAC_EN_Pos) /*!< CONTROL: UPAC_EN Mask */ + +#define CONTROL_PAC_EN_Pos 6U /*!< CONTROL: PAC_EN Position */ +#define CONTROL_PAC_EN_Msk (1UL << CONTROL_PAC_EN_Pos) /*!< CONTROL: PAC_EN Mask */ + +#define CONTROL_UBTI_EN_Pos 5U /*!< CONTROL: UBTI_EN Position */ +#define CONTROL_UBTI_EN_Msk (1UL << CONTROL_UBTI_EN_Pos) /*!< CONTROL: UBTI_EN Mask */ + +#define CONTROL_BTI_EN_Pos 4U /*!< CONTROL: BTI_EN Position */ +#define CONTROL_BTI_EN_Msk (1UL << CONTROL_BTI_EN_Pos) /*!< CONTROL: BTI_EN Mask */ + +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + __IOM uint32_t RFSR; /*!< Offset: 0x204 (R/W) RAS Fault Status Register */ + uint32_t RESERVED4[14U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_IESB_Pos 5U /*!< SCB AIRCR: Implicit ESB Enable Position */ +#define SCB_AIRCR_IESB_Msk (1UL << SCB_AIRCR_IESB_Pos) /*!< SCB AIRCR: Implicit ESB Enable Mask */ + +#define SCB_AIRCR_DIT_Pos 4U /*!< SCB AIRCR: Data Independent Timing Position */ +#define SCB_AIRCR_DIT_Msk (1UL << SCB_AIRCR_DIT_Pos) /*!< SCB AIRCR: Data Independent Timing Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_TRD_Pos 20U /*!< SCB CCR: TRD Position */ +#define SCB_CCR_TRD_Msk (1UL << SCB_CCR_TRD_Pos) /*!< SCB CCR: TRD Mask */ + +#define SCB_CCR_LOB_Pos 19U /*!< SCB CCR: LOB Position */ +#define SCB_CCR_LOB_Msk (1UL << SCB_CCR_LOB_Pos) /*!< SCB CCR: LOB Mask */ + +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_PMU_Pos 5U /*!< SCB DFSR: PMU Position */ +#define SCB_DFSR_PMU_Msk (1UL << SCB_DFSR_PMU_Pos) /*!< SCB DFSR: PMU Mask */ + +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CP7_Pos 7U /*!< SCB NSACR: CP7 Position */ +#define SCB_NSACR_CP7_Msk (1UL << SCB_NSACR_CP7_Pos) /*!< SCB NSACR: CP7 Mask */ + +#define SCB_NSACR_CP6_Pos 6U /*!< SCB NSACR: CP6 Position */ +#define SCB_NSACR_CP6_Msk (1UL << SCB_NSACR_CP6_Pos) /*!< SCB NSACR: CP6 Mask */ + +#define SCB_NSACR_CP5_Pos 5U /*!< SCB NSACR: CP5 Position */ +#define SCB_NSACR_CP5_Msk (1UL << SCB_NSACR_CP5_Pos) /*!< SCB NSACR: CP5 Mask */ + +#define SCB_NSACR_CP4_Pos 4U /*!< SCB NSACR: CP4 Position */ +#define SCB_NSACR_CP4_Msk (1UL << SCB_NSACR_CP4_Pos) /*!< SCB NSACR: CP4 Mask */ + +#define SCB_NSACR_CP3_Pos 3U /*!< SCB NSACR: CP3 Position */ +#define SCB_NSACR_CP3_Msk (1UL << SCB_NSACR_CP3_Pos) /*!< SCB NSACR: CP3 Mask */ + +#define SCB_NSACR_CP2_Pos 2U /*!< SCB NSACR: CP2 Position */ +#define SCB_NSACR_CP2_Msk (1UL << SCB_NSACR_CP2_Pos) /*!< SCB NSACR: CP2 Mask */ + +#define SCB_NSACR_CP1_Pos 1U /*!< SCB NSACR: CP1 Position */ +#define SCB_NSACR_CP1_Msk (1UL << SCB_NSACR_CP1_Pos) /*!< SCB NSACR: CP1 Mask */ + +#define SCB_NSACR_CP0_Pos 0U /*!< SCB NSACR: CP0 Position */ +#define SCB_NSACR_CP0_Msk (1UL /*<< SCB_NSACR_CP0_Pos*/) /*!< SCB NSACR: CP0 Mask */ + +/* SCB Debug Feature Register 0 Definitions */ +#define SCB_ID_DFR_UDE_Pos 28U /*!< SCB ID_DFR: UDE Position */ +#define SCB_ID_DFR_UDE_Msk (0xFUL << SCB_ID_DFR_UDE_Pos) /*!< SCB ID_DFR: UDE Mask */ + +#define SCB_ID_DFR_MProfDbg_Pos 20U /*!< SCB ID_DFR: MProfDbg Position */ +#define SCB_ID_DFR_MProfDbg_Msk (0xFUL << SCB_ID_DFR_MProfDbg_Pos) /*!< SCB ID_DFR: MProfDbg Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB RAS Fault Status Register Definitions */ +#define SCB_RFSR_V_Pos 31U /*!< SCB RFSR: V Position */ +#define SCB_RFSR_V_Msk (1UL << SCB_RFSR_V_Pos) /*!< SCB RFSR: V Mask */ + +#define SCB_RFSR_IS_Pos 16U /*!< SCB RFSR: IS Position */ +#define SCB_RFSR_IS_Msk (0x7FFFUL << SCB_RFSR_IS_Pos) /*!< SCB RFSR: IS Mask */ + +#define SCB_RFSR_UET_Pos 0U /*!< SCB RFSR: UET Position */ +#define SCB_RFSR_UET_Msk (3UL /*<< SCB_RFSR_UET_Pos*/) /*!< SCB RFSR: UET Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ICB Implementation Control Block register (ICB) + \brief Type definitions for the Implementation Control Block Register + @{ + */ + +/** + \brief Structure type to access the Implementation Control Block (ICB). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} ICB_Type; + +/* Auxiliary Control Register Definitions */ +#define ICB_ACTLR_DISCRITAXIRUW_Pos 27U /*!< ACTLR: DISCRITAXIRUW Position */ +#define ICB_ACTLR_DISCRITAXIRUW_Msk (1UL << ICB_ACTLR_DISCRITAXIRUW_Pos) /*!< ACTLR: DISCRITAXIRUW Mask */ + +#define ICB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define ICB_ACTLR_DISCRITAXIRUR_Msk (1UL << ICB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define ICB_ACTLR_EVENTBUSEN_Pos 14U /*!< ACTLR: EVENTBUSEN Position */ +#define ICB_ACTLR_EVENTBUSEN_Msk (1UL << ICB_ACTLR_EVENTBUSEN_Pos) /*!< ACTLR: EVENTBUSEN Mask */ + +#define ICB_ACTLR_EVENTBUSEN_S_Pos 13U /*!< ACTLR: EVENTBUSEN_S Position */ +#define ICB_ACTLR_EVENTBUSEN_S_Msk (1UL << ICB_ACTLR_EVENTBUSEN_S_Pos) /*!< ACTLR: EVENTBUSEN_S Mask */ + +#define ICB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define ICB_ACTLR_DISITMATBFLUSH_Msk (1UL << ICB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define ICB_ACTLR_DISNWAMODE_Pos 11U /*!< ACTLR: DISNWAMODE Position */ +#define ICB_ACTLR_DISNWAMODE_Msk (1UL << ICB_ACTLR_DISNWAMODE_Pos) /*!< ACTLR: DISNWAMODE Mask */ + +#define ICB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define ICB_ACTLR_FPEXCODIS_Msk (1UL << ICB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +/* Interrupt Controller Type Register Definitions */ +#define ICB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define ICB_ICTR_INTLINESNUM_Msk (0xFUL /*<< ICB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_ICB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[3U]; + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) ITM Device Type Register */ + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup MemSysCtl_Type Memory System Control Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Memory System Control Registers (MEMSYSCTL) + @{ + */ + +/** + \brief Structure type to access the Memory System Control Registers (MEMSYSCTL). + */ +typedef struct +{ + __IOM uint32_t MSCR; /*!< Offset: 0x000 (R/W) Memory System Control Register */ + __IOM uint32_t PFCR; /*!< Offset: 0x004 (R/W) Prefetcher Control Register */ + uint32_t RESERVED1[2U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x010 (R/W) ITCM Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x014 (R/W) DTCM Control Register */ + __IOM uint32_t PAHBCR; /*!< Offset: 0x018 (R/W) P-AHB Control Register */ + uint32_t RESERVED2[313U]; + __IOM uint32_t ITGU_CTRL; /*!< Offset: 0x500 (R/W) ITGU Control Register */ + __IOM uint32_t ITGU_CFG; /*!< Offset: 0x504 (R/W) ITGU Configuration Register */ + uint32_t RESERVED3[2U]; + __IOM uint32_t ITGU_LUT[16U]; /*!< Offset: 0x510 (R/W) ITGU Look Up Table Register */ + uint32_t RESERVED4[44U]; + __IOM uint32_t DTGU_CTRL; /*!< Offset: 0x600 (R/W) DTGU Control Registers */ + __IOM uint32_t DTGU_CFG; /*!< Offset: 0x604 (R/W) DTGU Configuration Register */ + uint32_t RESERVED5[2U]; + __IOM uint32_t DTGU_LUT[16U]; /*!< Offset: 0x610 (R/W) DTGU Look Up Table Register */ +} MemSysCtl_Type; + +/* MEMSYSCTL Memory System Control Register (MSCR) Register Definitions */ +#define MEMSYSCTL_MSCR_CPWRDN_Pos 17U /*!< MEMSYSCTL MSCR: CPWRDN Position */ +#define MEMSYSCTL_MSCR_CPWRDN_Msk (0x1UL << MEMSYSCTL_MSCR_CPWRDN_Pos) /*!< MEMSYSCTL MSCR: CPWRDN Mask */ + +#define MEMSYSCTL_MSCR_DCCLEAN_Pos 16U /*!< MEMSYSCTL MSCR: DCCLEAN Position */ +#define MEMSYSCTL_MSCR_DCCLEAN_Msk (0x1UL << MEMSYSCTL_MSCR_DCCLEAN_Pos) /*!< MEMSYSCTL MSCR: DCCLEAN Mask */ + +#define MEMSYSCTL_MSCR_ICACTIVE_Pos 13U /*!< MEMSYSCTL MSCR: ICACTIVE Position */ +#define MEMSYSCTL_MSCR_ICACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_ICACTIVE_Pos) /*!< MEMSYSCTL MSCR: ICACTIVE Mask */ + +#define MEMSYSCTL_MSCR_DCACTIVE_Pos 12U /*!< MEMSYSCTL MSCR: DCACTIVE Position */ +#define MEMSYSCTL_MSCR_DCACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_DCACTIVE_Pos) /*!< MEMSYSCTL MSCR: DCACTIVE Mask */ + +#define MEMSYSCTL_MSCR_EVECCFAULT_Pos 3U /*!< MEMSYSCTL MSCR: EVECCFAULT Position */ +#define MEMSYSCTL_MSCR_EVECCFAULT_Msk (0x1UL << MEMSYSCTL_MSCR_EVECCFAULT_Pos) /*!< MEMSYSCTL MSCR: EVECCFAULT Mask */ + +#define MEMSYSCTL_MSCR_FORCEWT_Pos 2U /*!< MEMSYSCTL MSCR: FORCEWT Position */ +#define MEMSYSCTL_MSCR_FORCEWT_Msk (0x1UL << MEMSYSCTL_MSCR_FORCEWT_Pos) /*!< MEMSYSCTL MSCR: FORCEWT Mask */ + +#define MEMSYSCTL_MSCR_ECCEN_Pos 1U /*!< MEMSYSCTL MSCR: ECCEN Position */ +#define MEMSYSCTL_MSCR_ECCEN_Msk (0x1UL << MEMSYSCTL_MSCR_ECCEN_Pos) /*!< MEMSYSCTL MSCR: ECCEN Mask */ + +/* MEMSYSCTL Prefetcher Control Register (PFCR) Register Definitions */ +#define MEMSYSCTL_PFCR_DIS_NLP_Pos 7U /*!< MEMSYSCTL PFCR: DIS_NLP Position */ +#define MEMSYSCTL_PFCR_DIS_NLP_Msk (0x1UL << MEMSYSCTL_PFCR_DIS_NLP_Pos) /*!< MEMSYSCTL PFCR: DIS_NLP Mask */ + +#define MEMSYSCTL_PFCR_ENABLE_Pos 0U /*!< MEMSYSCTL PFCR: ENABLE Position */ +#define MEMSYSCTL_PFCR_ENABLE_Msk (0x1UL /*<< MEMSYSCTL_PFCR_ENABLE_Pos*/) /*!< MEMSYSCTL PFCR: ENABLE Mask */ + +/* MEMSYSCTL ITCM Control Register (ITCMCR) Register Definitions */ +#define MEMSYSCTL_ITCMCR_SZ_Pos 3U /*!< MEMSYSCTL ITCMCR: SZ Position */ +#define MEMSYSCTL_ITCMCR_SZ_Msk (0xFUL << MEMSYSCTL_ITCMCR_SZ_Pos) /*!< MEMSYSCTL ITCMCR: SZ Mask */ + +#define MEMSYSCTL_ITCMCR_EN_Pos 0U /*!< MEMSYSCTL ITCMCR: EN Position */ +#define MEMSYSCTL_ITCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_ITCMCR_EN_Pos*/) /*!< MEMSYSCTL ITCMCR: EN Mask */ + +/* MEMSYSCTL DTCM Control Register (DTCMCR) Register Definitions */ +#define MEMSYSCTL_DTCMCR_SZ_Pos 3U /*!< MEMSYSCTL DTCMCR: SZ Position */ +#define MEMSYSCTL_DTCMCR_SZ_Msk (0xFUL << MEMSYSCTL_DTCMCR_SZ_Pos) /*!< MEMSYSCTL DTCMCR: SZ Mask */ + +#define MEMSYSCTL_DTCMCR_EN_Pos 0U /*!< MEMSYSCTL DTCMCR: EN Position */ +#define MEMSYSCTL_DTCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_DTCMCR_EN_Pos*/) /*!< MEMSYSCTL DTCMCR: EN Mask */ + +/* MEMSYSCTL P-AHB Control Register (PAHBCR) Register Definitions */ +#define MEMSYSCTL_PAHBCR_SZ_Pos 1U /*!< MEMSYSCTL PAHBCR: SZ Position */ +#define MEMSYSCTL_PAHBCR_SZ_Msk (0x7UL << MEMSYSCTL_PAHBCR_SZ_Pos) /*!< MEMSYSCTL PAHBCR: SZ Mask */ + +#define MEMSYSCTL_PAHBCR_EN_Pos 0U /*!< MEMSYSCTL PAHBCR: EN Position */ +#define MEMSYSCTL_PAHBCR_EN_Msk (0x1UL /*<< MEMSYSCTL_PAHBCR_EN_Pos*/) /*!< MEMSYSCTL PAHBCR: EN Mask */ + +/* MEMSYSCTL ITGU Control Register (ITGU_CTRL) Register Definitions */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL ITGU_CTRL: DEREN Position */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_ITGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL ITGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL ITGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_ITGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL ITGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL ITGU Configuration Register (ITGU_CFG) Register Definitions */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL ITGU_CFG: PRESENT Position */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_ITGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL ITGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL ITGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_ITGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL ITGU_CFG: BLKSZ Mask */ + +/* MEMSYSCTL DTGU Control Registers (DTGU_CTRL) Register Definitions */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL DTGU_CTRL: DEREN Position */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_DTGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL DTGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL DTGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_DTGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL DTGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL DTGU Configuration Register (DTGU_CFG) Register Definitions */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL DTGU_CFG: PRESENT Position */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_DTGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL DTGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL DTGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_DTGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL DTGU_CFG: BLKSZ Mask */ + + +/*@}*/ /* end of group MemSysCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PwrModCtl_Type Power Mode Control Registers + \brief Type definitions for the Power Mode Control Registers (PWRMODCTL) + @{ + */ + +/** + \brief Structure type to access the Power Mode Control Registers (PWRMODCTL). + */ +typedef struct +{ + __IOM uint32_t CPDLPSTATE; /*!< Offset: 0x000 (R/W) Core Power Domain Low Power State Register */ + __IOM uint32_t DPDLPSTATE; /*!< Offset: 0x004 (R/W) Debug Power Domain Low Power State Register */ +} PwrModCtl_Type; + +/* PWRMODCTL Core Power Domain Low Power State (CPDLPSTATE) Register Definitions */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos 8U /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos 4U /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos 0U /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Msk (0x3UL /*<< PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos*/) /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Mask */ + +/* PWRMODCTL Debug Power Domain Low Power State (DPDLPSTATE) Register Definitions */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos 0U /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Position */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Msk (0x3UL /*<< PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos*/) /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Mask */ + +/*@}*/ /* end of group PwrModCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup EWIC_Type External Wakeup Interrupt Controller Registers + \brief Type definitions for the External Wakeup Interrupt Controller Registers (EWIC) + @{ + */ + +/** + \brief Structure type to access the External Wakeup Interrupt Controller Registers (EWIC). + */ +typedef struct +{ + __OM uint32_t EVENTSPR; /*!< Offset: 0x000 ( /W) Event Set Pending Register */ + uint32_t RESERVED0[31U]; + __IM uint32_t EVENTMASKA; /*!< Offset: 0x080 (R/W) Event Mask A Register */ + __IM uint32_t EVENTMASK[15]; /*!< Offset: 0x084 (R/W) Event Mask Register */ +} EWIC_Type; + +/* EWIC External Wakeup Interrupt Controller (EVENTSPR) Register Definitions */ +#define EWIC_EVENTSPR_EDBGREQ_Pos 2U /*!< EWIC EVENTSPR: EDBGREQ Position */ +#define EWIC_EVENTSPR_EDBGREQ_Msk (0x1UL << EWIC_EVENTSPR_EDBGREQ_Pos) /*!< EWIC EVENTSPR: EDBGREQ Mask */ + +#define EWIC_EVENTSPR_NMI_Pos 1U /*!< EWIC EVENTSPR: NMI Position */ +#define EWIC_EVENTSPR_NMI_Msk (0x1UL << EWIC_EVENTSPR_NMI_Pos) /*!< EWIC EVENTSPR: NMI Mask */ + +#define EWIC_EVENTSPR_EVENT_Pos 0U /*!< EWIC EVENTSPR: EVENT Position */ +#define EWIC_EVENTSPR_EVENT_Msk (0x1UL /*<< EWIC_EVENTSPR_EVENT_Pos*/) /*!< EWIC EVENTSPR: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASKA) Register Definitions */ +#define EWIC_EVENTMASKA_EDBGREQ_Pos 2U /*!< EWIC EVENTMASKA: EDBGREQ Position */ +#define EWIC_EVENTMASKA_EDBGREQ_Msk (0x1UL << EWIC_EVENTMASKA_EDBGREQ_Pos) /*!< EWIC EVENTMASKA: EDBGREQ Mask */ + +#define EWIC_EVENTMASKA_NMI_Pos 1U /*!< EWIC EVENTMASKA: NMI Position */ +#define EWIC_EVENTMASKA_NMI_Msk (0x1UL << EWIC_EVENTMASKA_NMI_Pos) /*!< EWIC EVENTMASKA: NMI Mask */ + +#define EWIC_EVENTMASKA_EVENT_Pos 0U /*!< EWIC EVENTMASKA: EVENT Position */ +#define EWIC_EVENTMASKA_EVENT_Msk (0x1UL /*<< EWIC_EVENTMASKA_EVENT_Pos*/) /*!< EWIC EVENTMASKA: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASK) Register Definitions */ +#define EWIC_EVENTMASK_IRQ_Pos 0U /*!< EWIC EVENTMASKA: IRQ Position */ +#define EWIC_EVENTMASK_IRQ_Msk (0xFFFFFFFFUL /*<< EWIC_EVENTMASKA_IRQ_Pos*/) /*!< EWIC EVENTMASKA: IRQ Mask */ + +/*@}*/ /* end of group EWIC_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup ErrBnk_Type Error Banking Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Error Banking Registers (ERRBNK) + @{ + */ + +/** + \brief Structure type to access the Error Banking Registers (ERRBNK). + */ +typedef struct +{ + __IOM uint32_t IEBR0; /*!< Offset: 0x000 (R/W) Instruction Cache Error Bank Register 0 */ + __IOM uint32_t IEBR1; /*!< Offset: 0x004 (R/W) Instruction Cache Error Bank Register 1 */ + uint32_t RESERVED0[2U]; + __IOM uint32_t DEBR0; /*!< Offset: 0x010 (R/W) Data Cache Error Bank Register 0 */ + __IOM uint32_t DEBR1; /*!< Offset: 0x014 (R/W) Data Cache Error Bank Register 1 */ + uint32_t RESERVED1[2U]; + __IOM uint32_t TEBR0; /*!< Offset: 0x020 (R/W) TCM Error Bank Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t TEBR1; /*!< Offset: 0x028 (R/W) TCM Error Bank Register 1 */ +} ErrBnk_Type; + +/* ERRBNK Instruction Cache Error Bank Register 0 (IEBR0) Register Definitions */ +#define ERRBNK_IEBR0_SWDEF_Pos 30U /*!< ERRBNK IEBR0: SWDEF Position */ +#define ERRBNK_IEBR0_SWDEF_Msk (0x3UL << ERRBNK_IEBR0_SWDEF_Pos) /*!< ERRBNK IEBR0: SWDEF Mask */ + +#define ERRBNK_IEBR0_BANK_Pos 16U /*!< ERRBNK IEBR0: BANK Position */ +#define ERRBNK_IEBR0_BANK_Msk (0x1UL << ERRBNK_IEBR0_BANK_Pos) /*!< ERRBNK IEBR0: BANK Mask */ + +#define ERRBNK_IEBR0_LOCATION_Pos 2U /*!< ERRBNK IEBR0: LOCATION Position */ +#define ERRBNK_IEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR0_LOCATION_Pos) /*!< ERRBNK IEBR0: LOCATION Mask */ + +#define ERRBNK_IEBR0_LOCKED_Pos 1U /*!< ERRBNK IEBR0: LOCKED Position */ +#define ERRBNK_IEBR0_LOCKED_Msk (0x1UL << ERRBNK_IEBR0_LOCKED_Pos) /*!< ERRBNK IEBR0: LOCKED Mask */ + +#define ERRBNK_IEBR0_VALID_Pos 0U /*!< ERRBNK IEBR0: VALID Position */ +#define ERRBNK_IEBR0_VALID_Msk (0x1UL << /*ERRBNK_IEBR0_VALID_Pos*/) /*!< ERRBNK IEBR0: VALID Mask */ + +/* ERRBNK Instruction Cache Error Bank Register 1 (IEBR1) Register Definitions */ +#define ERRBNK_IEBR1_SWDEF_Pos 30U /*!< ERRBNK IEBR1: SWDEF Position */ +#define ERRBNK_IEBR1_SWDEF_Msk (0x3UL << ERRBNK_IEBR1_SWDEF_Pos) /*!< ERRBNK IEBR1: SWDEF Mask */ + +#define ERRBNK_IEBR1_BANK_Pos 16U /*!< ERRBNK IEBR1: BANK Position */ +#define ERRBNK_IEBR1_BANK_Msk (0x1UL << ERRBNK_IEBR1_BANK_Pos) /*!< ERRBNK IEBR1: BANK Mask */ + +#define ERRBNK_IEBR1_LOCATION_Pos 2U /*!< ERRBNK IEBR1: LOCATION Position */ +#define ERRBNK_IEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR1_LOCATION_Pos) /*!< ERRBNK IEBR1: LOCATION Mask */ + +#define ERRBNK_IEBR1_LOCKED_Pos 1U /*!< ERRBNK IEBR1: LOCKED Position */ +#define ERRBNK_IEBR1_LOCKED_Msk (0x1UL << ERRBNK_IEBR1_LOCKED_Pos) /*!< ERRBNK IEBR1: LOCKED Mask */ + +#define ERRBNK_IEBR1_VALID_Pos 0U /*!< ERRBNK IEBR1: VALID Position */ +#define ERRBNK_IEBR1_VALID_Msk (0x1UL << /*ERRBNK_IEBR1_VALID_Pos*/) /*!< ERRBNK IEBR1: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 0 (DEBR0) Register Definitions */ +#define ERRBNK_DEBR0_SWDEF_Pos 30U /*!< ERRBNK DEBR0: SWDEF Position */ +#define ERRBNK_DEBR0_SWDEF_Msk (0x3UL << ERRBNK_DEBR0_SWDEF_Pos) /*!< ERRBNK DEBR0: SWDEF Mask */ + +#define ERRBNK_DEBR0_TYPE_Pos 17U /*!< ERRBNK DEBR0: TYPE Position */ +#define ERRBNK_DEBR0_TYPE_Msk (0x1UL << ERRBNK_DEBR0_TYPE_Pos) /*!< ERRBNK DEBR0: TYPE Mask */ + +#define ERRBNK_DEBR0_BANK_Pos 16U /*!< ERRBNK DEBR0: BANK Position */ +#define ERRBNK_DEBR0_BANK_Msk (0x1UL << ERRBNK_DEBR0_BANK_Pos) /*!< ERRBNK DEBR0: BANK Mask */ + +#define ERRBNK_DEBR0_LOCATION_Pos 2U /*!< ERRBNK DEBR0: LOCATION Position */ +#define ERRBNK_DEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR0_LOCATION_Pos) /*!< ERRBNK DEBR0: LOCATION Mask */ + +#define ERRBNK_DEBR0_LOCKED_Pos 1U /*!< ERRBNK DEBR0: LOCKED Position */ +#define ERRBNK_DEBR0_LOCKED_Msk (0x1UL << ERRBNK_DEBR0_LOCKED_Pos) /*!< ERRBNK DEBR0: LOCKED Mask */ + +#define ERRBNK_DEBR0_VALID_Pos 0U /*!< ERRBNK DEBR0: VALID Position */ +#define ERRBNK_DEBR0_VALID_Msk (0x1UL << /*ERRBNK_DEBR0_VALID_Pos*/) /*!< ERRBNK DEBR0: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 1 (DEBR1) Register Definitions */ +#define ERRBNK_DEBR1_SWDEF_Pos 30U /*!< ERRBNK DEBR1: SWDEF Position */ +#define ERRBNK_DEBR1_SWDEF_Msk (0x3UL << ERRBNK_DEBR1_SWDEF_Pos) /*!< ERRBNK DEBR1: SWDEF Mask */ + +#define ERRBNK_DEBR1_TYPE_Pos 17U /*!< ERRBNK DEBR1: TYPE Position */ +#define ERRBNK_DEBR1_TYPE_Msk (0x1UL << ERRBNK_DEBR1_TYPE_Pos) /*!< ERRBNK DEBR1: TYPE Mask */ + +#define ERRBNK_DEBR1_BANK_Pos 16U /*!< ERRBNK DEBR1: BANK Position */ +#define ERRBNK_DEBR1_BANK_Msk (0x1UL << ERRBNK_DEBR1_BANK_Pos) /*!< ERRBNK DEBR1: BANK Mask */ + +#define ERRBNK_DEBR1_LOCATION_Pos 2U /*!< ERRBNK DEBR1: LOCATION Position */ +#define ERRBNK_DEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR1_LOCATION_Pos) /*!< ERRBNK DEBR1: LOCATION Mask */ + +#define ERRBNK_DEBR1_LOCKED_Pos 1U /*!< ERRBNK DEBR1: LOCKED Position */ +#define ERRBNK_DEBR1_LOCKED_Msk (0x1UL << ERRBNK_DEBR1_LOCKED_Pos) /*!< ERRBNK DEBR1: LOCKED Mask */ + +#define ERRBNK_DEBR1_VALID_Pos 0U /*!< ERRBNK DEBR1: VALID Position */ +#define ERRBNK_DEBR1_VALID_Msk (0x1UL << /*ERRBNK_DEBR1_VALID_Pos*/) /*!< ERRBNK DEBR1: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 0 (TEBR0) Register Definitions */ +#define ERRBNK_TEBR0_SWDEF_Pos 30U /*!< ERRBNK TEBR0: SWDEF Position */ +#define ERRBNK_TEBR0_SWDEF_Msk (0x3UL << ERRBNK_TEBR0_SWDEF_Pos) /*!< ERRBNK TEBR0: SWDEF Mask */ + +#define ERRBNK_TEBR0_POISON_Pos 28U /*!< ERRBNK TEBR0: POISON Position */ +#define ERRBNK_TEBR0_POISON_Msk (0x1UL << ERRBNK_TEBR0_POISON_Pos) /*!< ERRBNK TEBR0: POISON Mask */ + +#define ERRBNK_TEBR0_TYPE_Pos 27U /*!< ERRBNK TEBR0: TYPE Position */ +#define ERRBNK_TEBR0_TYPE_Msk (0x1UL << ERRBNK_TEBR0_TYPE_Pos) /*!< ERRBNK TEBR0: TYPE Mask */ + +#define ERRBNK_TEBR0_BANK_Pos 24U /*!< ERRBNK TEBR0: BANK Position */ +#define ERRBNK_TEBR0_BANK_Msk (0x3UL << ERRBNK_TEBR0_BANK_Pos) /*!< ERRBNK TEBR0: BANK Mask */ + +#define ERRBNK_TEBR0_LOCATION_Pos 2U /*!< ERRBNK TEBR0: LOCATION Position */ +#define ERRBNK_TEBR0_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR0_LOCATION_Pos) /*!< ERRBNK TEBR0: LOCATION Mask */ + +#define ERRBNK_TEBR0_LOCKED_Pos 1U /*!< ERRBNK TEBR0: LOCKED Position */ +#define ERRBNK_TEBR0_LOCKED_Msk (0x1UL << ERRBNK_TEBR0_LOCKED_Pos) /*!< ERRBNK TEBR0: LOCKED Mask */ + +#define ERRBNK_TEBR0_VALID_Pos 0U /*!< ERRBNK TEBR0: VALID Position */ +#define ERRBNK_TEBR0_VALID_Msk (0x1UL << /*ERRBNK_TEBR0_VALID_Pos*/) /*!< ERRBNK TEBR0: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 1 (TEBR1) Register Definitions */ +#define ERRBNK_TEBR1_SWDEF_Pos 30U /*!< ERRBNK TEBR1: SWDEF Position */ +#define ERRBNK_TEBR1_SWDEF_Msk (0x3UL << ERRBNK_TEBR1_SWDEF_Pos) /*!< ERRBNK TEBR1: SWDEF Mask */ + +#define ERRBNK_TEBR1_POISON_Pos 28U /*!< ERRBNK TEBR1: POISON Position */ +#define ERRBNK_TEBR1_POISON_Msk (0x1UL << ERRBNK_TEBR1_POISON_Pos) /*!< ERRBNK TEBR1: POISON Mask */ + +#define ERRBNK_TEBR1_TYPE_Pos 27U /*!< ERRBNK TEBR1: TYPE Position */ +#define ERRBNK_TEBR1_TYPE_Msk (0x1UL << ERRBNK_TEBR1_TYPE_Pos) /*!< ERRBNK TEBR1: TYPE Mask */ + +#define ERRBNK_TEBR1_BANK_Pos 24U /*!< ERRBNK TEBR1: BANK Position */ +#define ERRBNK_TEBR1_BANK_Msk (0x3UL << ERRBNK_TEBR1_BANK_Pos) /*!< ERRBNK TEBR1: BANK Mask */ + +#define ERRBNK_TEBR1_LOCATION_Pos 2U /*!< ERRBNK TEBR1: LOCATION Position */ +#define ERRBNK_TEBR1_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR1_LOCATION_Pos) /*!< ERRBNK TEBR1: LOCATION Mask */ + +#define ERRBNK_TEBR1_LOCKED_Pos 1U /*!< ERRBNK TEBR1: LOCKED Position */ +#define ERRBNK_TEBR1_LOCKED_Msk (0x1UL << ERRBNK_TEBR1_LOCKED_Pos) /*!< ERRBNK TEBR1: LOCKED Mask */ + +#define ERRBNK_TEBR1_VALID_Pos 0U /*!< ERRBNK TEBR1: VALID Position */ +#define ERRBNK_TEBR1_VALID_Msk (0x1UL << /*ERRBNK_TEBR1_VALID_Pos*/) /*!< ERRBNK TEBR1: VALID Mask */ + +/*@}*/ /* end of group ErrBnk_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PrcCfgInf_Type Processor Configuration Information Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Processor Configuration Information Registerss (PRCCFGINF) + @{ + */ + +/** + \brief Structure type to access the Processor Configuration Information Registerss (PRCCFGINF). + */ +typedef struct +{ + __OM uint32_t CFGINFOSEL; /*!< Offset: 0x000 ( /W) Processor Configuration Information Selection Register */ + __IM uint32_t CFGINFORD; /*!< Offset: 0x004 (R/ ) Processor Configuration Information Read Data Register */ +} PrcCfgInf_Type; + +/* PRCCFGINF Processor Configuration Information Selection Register (CFGINFOSEL) Definitions */ + +/* PRCCFGINF Processor Configuration Information Read Data Register (CFGINFORD) Definitions */ + +/*@}*/ /* end of group PrcCfgInf_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFmt_Pos 0U /*!< TPI FFCR: EnFmt Position */ +#define TPI_FFCR_EnFmt_Msk (0x3UL << /*TPI_FFCR_EnFmt_Pos*/) /*!< TPI FFCR: EnFmt Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_PMU Performance Monitoring Unit (PMU) + \brief Type definitions for the Performance Monitoring Unit (PMU) + @{ + */ + +/** + \brief Structure type to access the Performance Monitoring Unit (PMU). + */ +typedef struct +{ + __IOM uint32_t EVCNTR[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x0 (R/W) PMU Event Counter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED0[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCNTR; /*!< Offset: 0x7C (R/W) PMU Cycle Counter Register */ + uint32_t RESERVED1[224]; + __IOM uint32_t EVTYPER[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x400 (R/W) PMU Event Type and Filter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED2[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCFILTR; /*!< Offset: 0x47C (R/W) PMU Cycle Counter Filter Register */ + uint32_t RESERVED3[480]; + __IOM uint32_t CNTENSET; /*!< Offset: 0xC00 (R/W) PMU Count Enable Set Register */ + uint32_t RESERVED4[7]; + __IOM uint32_t CNTENCLR; /*!< Offset: 0xC20 (R/W) PMU Count Enable Clear Register */ + uint32_t RESERVED5[7]; + __IOM uint32_t INTENSET; /*!< Offset: 0xC40 (R/W) PMU Interrupt Enable Set Register */ + uint32_t RESERVED6[7]; + __IOM uint32_t INTENCLR; /*!< Offset: 0xC60 (R/W) PMU Interrupt Enable Clear Register */ + uint32_t RESERVED7[7]; + __IOM uint32_t OVSCLR; /*!< Offset: 0xC80 (R/W) PMU Overflow Flag Status Clear Register */ + uint32_t RESERVED8[7]; + __IOM uint32_t SWINC; /*!< Offset: 0xCA0 (R/W) PMU Software Increment Register */ + uint32_t RESERVED9[7]; + __IOM uint32_t OVSSET; /*!< Offset: 0xCC0 (R/W) PMU Overflow Flag Status Set Register */ + uint32_t RESERVED10[79]; + __IOM uint32_t TYPE; /*!< Offset: 0xE00 (R/W) PMU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0xE04 (R/W) PMU Control Register */ + uint32_t RESERVED11[108]; + __IOM uint32_t AUTHSTATUS; /*!< Offset: 0xFB8 (R/W) PMU Authentication Status Register */ + __IOM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/W) PMU Device Architecture Register */ + uint32_t RESERVED12[3]; + __IOM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/W) PMU Device Type Register */ + __IOM uint32_t PIDR4; /*!< Offset: 0xFD0 (R/W) PMU Peripheral Identification Register 4 */ + uint32_t RESERVED13[3]; + __IOM uint32_t PIDR0; /*!< Offset: 0xFE0 (R/W) PMU Peripheral Identification Register 0 */ + __IOM uint32_t PIDR1; /*!< Offset: 0xFE4 (R/W) PMU Peripheral Identification Register 1 */ + __IOM uint32_t PIDR2; /*!< Offset: 0xFE8 (R/W) PMU Peripheral Identification Register 2 */ + __IOM uint32_t PIDR3; /*!< Offset: 0xFEC (R/W) PMU Peripheral Identification Register 3 */ + __IOM uint32_t CIDR0; /*!< Offset: 0xFF0 (R/W) PMU Component Identification Register 0 */ + __IOM uint32_t CIDR1; /*!< Offset: 0xFF4 (R/W) PMU Component Identification Register 1 */ + __IOM uint32_t CIDR2; /*!< Offset: 0xFF8 (R/W) PMU Component Identification Register 2 */ + __IOM uint32_t CIDR3; /*!< Offset: 0xFFC (R/W) PMU Component Identification Register 3 */ +} PMU_Type; + +/** \brief PMU Event Counter Registers (0-30) Definitions */ + +#define PMU_EVCNTR_CNT_Pos 0U /*!< PMU EVCNTR: Counter Position */ +#define PMU_EVCNTR_CNT_Msk (0xFFFFUL /*<< PMU_EVCNTRx_CNT_Pos*/) /*!< PMU EVCNTR: Counter Mask */ + +/** \brief PMU Event Type and Filter Registers (0-30) Definitions */ + +#define PMU_EVTYPER_EVENTTOCNT_Pos 0U /*!< PMU EVTYPER: Event to Count Position */ +#define PMU_EVTYPER_EVENTTOCNT_Msk (0xFFFFUL /*<< EVTYPERx_EVENTTOCNT_Pos*/) /*!< PMU EVTYPER: Event to Count Mask */ + +/** \brief PMU Count Enable Set Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENSET: Event Counter 0 Enable Set Position */ +#define PMU_CNTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENSET_CNT0_ENABLE_Pos*/) /*!< PMU CNTENSET: Event Counter 0 Enable Set Mask */ + +#define PMU_CNTENSET_CNT1_ENABLE_Pos 1U /*!< PMU CNTENSET: Event Counter 1 Enable Set Position */ +#define PMU_CNTENSET_CNT1_ENABLE_Msk (1UL << PMU_CNTENSET_CNT1_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 1 Enable Set Mask */ + +#define PMU_CNTENSET_CNT2_ENABLE_Pos 2U /*!< PMU CNTENSET: Event Counter 2 Enable Set Position */ +#define PMU_CNTENSET_CNT2_ENABLE_Msk (1UL << PMU_CNTENSET_CNT2_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 2 Enable Set Mask */ + +#define PMU_CNTENSET_CNT3_ENABLE_Pos 3U /*!< PMU CNTENSET: Event Counter 3 Enable Set Position */ +#define PMU_CNTENSET_CNT3_ENABLE_Msk (1UL << PMU_CNTENSET_CNT3_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 3 Enable Set Mask */ + +#define PMU_CNTENSET_CNT4_ENABLE_Pos 4U /*!< PMU CNTENSET: Event Counter 4 Enable Set Position */ +#define PMU_CNTENSET_CNT4_ENABLE_Msk (1UL << PMU_CNTENSET_CNT4_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 4 Enable Set Mask */ + +#define PMU_CNTENSET_CNT5_ENABLE_Pos 5U /*!< PMU CNTENSET: Event Counter 5 Enable Set Position */ +#define PMU_CNTENSET_CNT5_ENABLE_Msk (1UL << PMU_CNTENSET_CNT5_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 5 Enable Set Mask */ + +#define PMU_CNTENSET_CNT6_ENABLE_Pos 6U /*!< PMU CNTENSET: Event Counter 6 Enable Set Position */ +#define PMU_CNTENSET_CNT6_ENABLE_Msk (1UL << PMU_CNTENSET_CNT6_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 6 Enable Set Mask */ + +#define PMU_CNTENSET_CNT7_ENABLE_Pos 7U /*!< PMU CNTENSET: Event Counter 7 Enable Set Position */ +#define PMU_CNTENSET_CNT7_ENABLE_Msk (1UL << PMU_CNTENSET_CNT7_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 7 Enable Set Mask */ + +#define PMU_CNTENSET_CNT8_ENABLE_Pos 8U /*!< PMU CNTENSET: Event Counter 8 Enable Set Position */ +#define PMU_CNTENSET_CNT8_ENABLE_Msk (1UL << PMU_CNTENSET_CNT8_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 8 Enable Set Mask */ + +#define PMU_CNTENSET_CNT9_ENABLE_Pos 9U /*!< PMU CNTENSET: Event Counter 9 Enable Set Position */ +#define PMU_CNTENSET_CNT9_ENABLE_Msk (1UL << PMU_CNTENSET_CNT9_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 9 Enable Set Mask */ + +#define PMU_CNTENSET_CNT10_ENABLE_Pos 10U /*!< PMU CNTENSET: Event Counter 10 Enable Set Position */ +#define PMU_CNTENSET_CNT10_ENABLE_Msk (1UL << PMU_CNTENSET_CNT10_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 10 Enable Set Mask */ + +#define PMU_CNTENSET_CNT11_ENABLE_Pos 11U /*!< PMU CNTENSET: Event Counter 11 Enable Set Position */ +#define PMU_CNTENSET_CNT11_ENABLE_Msk (1UL << PMU_CNTENSET_CNT11_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 11 Enable Set Mask */ + +#define PMU_CNTENSET_CNT12_ENABLE_Pos 12U /*!< PMU CNTENSET: Event Counter 12 Enable Set Position */ +#define PMU_CNTENSET_CNT12_ENABLE_Msk (1UL << PMU_CNTENSET_CNT12_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 12 Enable Set Mask */ + +#define PMU_CNTENSET_CNT13_ENABLE_Pos 13U /*!< PMU CNTENSET: Event Counter 13 Enable Set Position */ +#define PMU_CNTENSET_CNT13_ENABLE_Msk (1UL << PMU_CNTENSET_CNT13_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 13 Enable Set Mask */ + +#define PMU_CNTENSET_CNT14_ENABLE_Pos 14U /*!< PMU CNTENSET: Event Counter 14 Enable Set Position */ +#define PMU_CNTENSET_CNT14_ENABLE_Msk (1UL << PMU_CNTENSET_CNT14_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 14 Enable Set Mask */ + +#define PMU_CNTENSET_CNT15_ENABLE_Pos 15U /*!< PMU CNTENSET: Event Counter 15 Enable Set Position */ +#define PMU_CNTENSET_CNT15_ENABLE_Msk (1UL << PMU_CNTENSET_CNT15_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 15 Enable Set Mask */ + +#define PMU_CNTENSET_CNT16_ENABLE_Pos 16U /*!< PMU CNTENSET: Event Counter 16 Enable Set Position */ +#define PMU_CNTENSET_CNT16_ENABLE_Msk (1UL << PMU_CNTENSET_CNT16_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 16 Enable Set Mask */ + +#define PMU_CNTENSET_CNT17_ENABLE_Pos 17U /*!< PMU CNTENSET: Event Counter 17 Enable Set Position */ +#define PMU_CNTENSET_CNT17_ENABLE_Msk (1UL << PMU_CNTENSET_CNT17_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 17 Enable Set Mask */ + +#define PMU_CNTENSET_CNT18_ENABLE_Pos 18U /*!< PMU CNTENSET: Event Counter 18 Enable Set Position */ +#define PMU_CNTENSET_CNT18_ENABLE_Msk (1UL << PMU_CNTENSET_CNT18_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 18 Enable Set Mask */ + +#define PMU_CNTENSET_CNT19_ENABLE_Pos 19U /*!< PMU CNTENSET: Event Counter 19 Enable Set Position */ +#define PMU_CNTENSET_CNT19_ENABLE_Msk (1UL << PMU_CNTENSET_CNT19_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 19 Enable Set Mask */ + +#define PMU_CNTENSET_CNT20_ENABLE_Pos 20U /*!< PMU CNTENSET: Event Counter 20 Enable Set Position */ +#define PMU_CNTENSET_CNT20_ENABLE_Msk (1UL << PMU_CNTENSET_CNT20_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 20 Enable Set Mask */ + +#define PMU_CNTENSET_CNT21_ENABLE_Pos 21U /*!< PMU CNTENSET: Event Counter 21 Enable Set Position */ +#define PMU_CNTENSET_CNT21_ENABLE_Msk (1UL << PMU_CNTENSET_CNT21_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 21 Enable Set Mask */ + +#define PMU_CNTENSET_CNT22_ENABLE_Pos 22U /*!< PMU CNTENSET: Event Counter 22 Enable Set Position */ +#define PMU_CNTENSET_CNT22_ENABLE_Msk (1UL << PMU_CNTENSET_CNT22_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 22 Enable Set Mask */ + +#define PMU_CNTENSET_CNT23_ENABLE_Pos 23U /*!< PMU CNTENSET: Event Counter 23 Enable Set Position */ +#define PMU_CNTENSET_CNT23_ENABLE_Msk (1UL << PMU_CNTENSET_CNT23_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 23 Enable Set Mask */ + +#define PMU_CNTENSET_CNT24_ENABLE_Pos 24U /*!< PMU CNTENSET: Event Counter 24 Enable Set Position */ +#define PMU_CNTENSET_CNT24_ENABLE_Msk (1UL << PMU_CNTENSET_CNT24_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 24 Enable Set Mask */ + +#define PMU_CNTENSET_CNT25_ENABLE_Pos 25U /*!< PMU CNTENSET: Event Counter 25 Enable Set Position */ +#define PMU_CNTENSET_CNT25_ENABLE_Msk (1UL << PMU_CNTENSET_CNT25_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 25 Enable Set Mask */ + +#define PMU_CNTENSET_CNT26_ENABLE_Pos 26U /*!< PMU CNTENSET: Event Counter 26 Enable Set Position */ +#define PMU_CNTENSET_CNT26_ENABLE_Msk (1UL << PMU_CNTENSET_CNT26_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 26 Enable Set Mask */ + +#define PMU_CNTENSET_CNT27_ENABLE_Pos 27U /*!< PMU CNTENSET: Event Counter 27 Enable Set Position */ +#define PMU_CNTENSET_CNT27_ENABLE_Msk (1UL << PMU_CNTENSET_CNT27_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 27 Enable Set Mask */ + +#define PMU_CNTENSET_CNT28_ENABLE_Pos 28U /*!< PMU CNTENSET: Event Counter 28 Enable Set Position */ +#define PMU_CNTENSET_CNT28_ENABLE_Msk (1UL << PMU_CNTENSET_CNT28_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 28 Enable Set Mask */ + +#define PMU_CNTENSET_CNT29_ENABLE_Pos 29U /*!< PMU CNTENSET: Event Counter 29 Enable Set Position */ +#define PMU_CNTENSET_CNT29_ENABLE_Msk (1UL << PMU_CNTENSET_CNT29_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 29 Enable Set Mask */ + +#define PMU_CNTENSET_CNT30_ENABLE_Pos 30U /*!< PMU CNTENSET: Event Counter 30 Enable Set Position */ +#define PMU_CNTENSET_CNT30_ENABLE_Msk (1UL << PMU_CNTENSET_CNT30_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 30 Enable Set Mask */ + +#define PMU_CNTENSET_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENSET: Cycle Counter Enable Set Position */ +#define PMU_CNTENSET_CCNTR_ENABLE_Msk (1UL << PMU_CNTENSET_CCNTR_ENABLE_Pos) /*!< PMU CNTENSET: Cycle Counter Enable Set Mask */ + +/** \brief PMU Count Enable Clear Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Position */ +#define PMU_CNTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU CNTENCLR: Event Counter 1 Enable Clear Position */ +#define PMU_CNTENCLR_CNT1_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT1_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 1 Enable Clear */ + +#define PMU_CNTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Position */ +#define PMU_CNTENCLR_CNT2_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT2_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Position */ +#define PMU_CNTENCLR_CNT3_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT3_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Position */ +#define PMU_CNTENCLR_CNT4_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT4_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Position */ +#define PMU_CNTENCLR_CNT5_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT5_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Position */ +#define PMU_CNTENCLR_CNT6_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT6_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Position */ +#define PMU_CNTENCLR_CNT7_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT7_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Position */ +#define PMU_CNTENCLR_CNT8_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT8_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Position */ +#define PMU_CNTENCLR_CNT9_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT9_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Position */ +#define PMU_CNTENCLR_CNT10_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT10_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Position */ +#define PMU_CNTENCLR_CNT11_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT11_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Position */ +#define PMU_CNTENCLR_CNT12_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT12_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Position */ +#define PMU_CNTENCLR_CNT13_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT13_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Position */ +#define PMU_CNTENCLR_CNT14_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT14_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Position */ +#define PMU_CNTENCLR_CNT15_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT15_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Position */ +#define PMU_CNTENCLR_CNT16_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT16_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Position */ +#define PMU_CNTENCLR_CNT17_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT17_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Position */ +#define PMU_CNTENCLR_CNT18_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT18_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Position */ +#define PMU_CNTENCLR_CNT19_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT19_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Position */ +#define PMU_CNTENCLR_CNT20_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT20_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Position */ +#define PMU_CNTENCLR_CNT21_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT21_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Position */ +#define PMU_CNTENCLR_CNT22_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT22_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Position */ +#define PMU_CNTENCLR_CNT23_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT23_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Position */ +#define PMU_CNTENCLR_CNT24_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT24_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Position */ +#define PMU_CNTENCLR_CNT25_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT25_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Position */ +#define PMU_CNTENCLR_CNT26_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT26_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Position */ +#define PMU_CNTENCLR_CNT27_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT27_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Position */ +#define PMU_CNTENCLR_CNT28_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT28_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Position */ +#define PMU_CNTENCLR_CNT29_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT29_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Position */ +#define PMU_CNTENCLR_CNT30_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT30_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Mask */ + +#define PMU_CNTENCLR_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENCLR: Cycle Counter Enable Clear Position */ +#define PMU_CNTENCLR_CCNTR_ENABLE_Msk (1UL << PMU_CNTENCLR_CCNTR_ENABLE_Pos) /*!< PMU CNTENCLR: Cycle Counter Enable Clear Mask */ + +/** \brief PMU Interrupt Enable Set Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENSET_CNT0_ENABLE_Pos*/) /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT1_ENABLE_Pos 1U /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT1_ENABLE_Msk (1UL << PMU_INTENSET_CNT1_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT2_ENABLE_Pos 2U /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT2_ENABLE_Msk (1UL << PMU_INTENSET_CNT2_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT3_ENABLE_Pos 3U /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT3_ENABLE_Msk (1UL << PMU_INTENSET_CNT3_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT4_ENABLE_Pos 4U /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT4_ENABLE_Msk (1UL << PMU_INTENSET_CNT4_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT5_ENABLE_Pos 5U /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT5_ENABLE_Msk (1UL << PMU_INTENSET_CNT5_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT6_ENABLE_Pos 6U /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT6_ENABLE_Msk (1UL << PMU_INTENSET_CNT6_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT7_ENABLE_Pos 7U /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT7_ENABLE_Msk (1UL << PMU_INTENSET_CNT7_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT8_ENABLE_Pos 8U /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT8_ENABLE_Msk (1UL << PMU_INTENSET_CNT8_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT9_ENABLE_Pos 9U /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT9_ENABLE_Msk (1UL << PMU_INTENSET_CNT9_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT10_ENABLE_Pos 10U /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT10_ENABLE_Msk (1UL << PMU_INTENSET_CNT10_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT11_ENABLE_Pos 11U /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT11_ENABLE_Msk (1UL << PMU_INTENSET_CNT11_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT12_ENABLE_Pos 12U /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT12_ENABLE_Msk (1UL << PMU_INTENSET_CNT12_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT13_ENABLE_Pos 13U /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT13_ENABLE_Msk (1UL << PMU_INTENSET_CNT13_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT14_ENABLE_Pos 14U /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT14_ENABLE_Msk (1UL << PMU_INTENSET_CNT14_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT15_ENABLE_Pos 15U /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT15_ENABLE_Msk (1UL << PMU_INTENSET_CNT15_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT16_ENABLE_Pos 16U /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT16_ENABLE_Msk (1UL << PMU_INTENSET_CNT16_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT17_ENABLE_Pos 17U /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT17_ENABLE_Msk (1UL << PMU_INTENSET_CNT17_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT18_ENABLE_Pos 18U /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT18_ENABLE_Msk (1UL << PMU_INTENSET_CNT18_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT19_ENABLE_Pos 19U /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT19_ENABLE_Msk (1UL << PMU_INTENSET_CNT19_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT20_ENABLE_Pos 20U /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT20_ENABLE_Msk (1UL << PMU_INTENSET_CNT20_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT21_ENABLE_Pos 21U /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT21_ENABLE_Msk (1UL << PMU_INTENSET_CNT21_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT22_ENABLE_Pos 22U /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT22_ENABLE_Msk (1UL << PMU_INTENSET_CNT22_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT23_ENABLE_Pos 23U /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT23_ENABLE_Msk (1UL << PMU_INTENSET_CNT23_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT24_ENABLE_Pos 24U /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT24_ENABLE_Msk (1UL << PMU_INTENSET_CNT24_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT25_ENABLE_Pos 25U /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT25_ENABLE_Msk (1UL << PMU_INTENSET_CNT25_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT26_ENABLE_Pos 26U /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT26_ENABLE_Msk (1UL << PMU_INTENSET_CNT26_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT27_ENABLE_Pos 27U /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT27_ENABLE_Msk (1UL << PMU_INTENSET_CNT27_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT28_ENABLE_Pos 28U /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT28_ENABLE_Msk (1UL << PMU_INTENSET_CNT28_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT29_ENABLE_Pos 29U /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT29_ENABLE_Msk (1UL << PMU_INTENSET_CNT29_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT30_ENABLE_Pos 30U /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT30_ENABLE_Msk (1UL << PMU_INTENSET_CNT30_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Position */ +#define PMU_INTENSET_CCYCNT_ENABLE_Msk (1UL << PMU_INTENSET_CYCCNT_ENABLE_Pos) /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Mask */ + +/** \brief PMU Interrupt Enable Clear Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT1_ENABLE_Msk (1UL << PMU_INTENCLR_CNT1_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear */ + +#define PMU_INTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT2_ENABLE_Msk (1UL << PMU_INTENCLR_CNT2_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT3_ENABLE_Msk (1UL << PMU_INTENCLR_CNT3_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT4_ENABLE_Msk (1UL << PMU_INTENCLR_CNT4_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT5_ENABLE_Msk (1UL << PMU_INTENCLR_CNT5_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT6_ENABLE_Msk (1UL << PMU_INTENCLR_CNT6_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT7_ENABLE_Msk (1UL << PMU_INTENCLR_CNT7_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT8_ENABLE_Msk (1UL << PMU_INTENCLR_CNT8_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT9_ENABLE_Msk (1UL << PMU_INTENCLR_CNT9_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT10_ENABLE_Msk (1UL << PMU_INTENCLR_CNT10_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT11_ENABLE_Msk (1UL << PMU_INTENCLR_CNT11_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT12_ENABLE_Msk (1UL << PMU_INTENCLR_CNT12_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT13_ENABLE_Msk (1UL << PMU_INTENCLR_CNT13_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT14_ENABLE_Msk (1UL << PMU_INTENCLR_CNT14_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT15_ENABLE_Msk (1UL << PMU_INTENCLR_CNT15_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT16_ENABLE_Msk (1UL << PMU_INTENCLR_CNT16_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT17_ENABLE_Msk (1UL << PMU_INTENCLR_CNT17_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT18_ENABLE_Msk (1UL << PMU_INTENCLR_CNT18_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT19_ENABLE_Msk (1UL << PMU_INTENCLR_CNT19_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT20_ENABLE_Msk (1UL << PMU_INTENCLR_CNT20_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT21_ENABLE_Msk (1UL << PMU_INTENCLR_CNT21_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT22_ENABLE_Msk (1UL << PMU_INTENCLR_CNT22_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT23_ENABLE_Msk (1UL << PMU_INTENCLR_CNT23_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT24_ENABLE_Msk (1UL << PMU_INTENCLR_CNT24_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT25_ENABLE_Msk (1UL << PMU_INTENCLR_CNT25_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT26_ENABLE_Msk (1UL << PMU_INTENCLR_CNT26_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT27_ENABLE_Msk (1UL << PMU_INTENCLR_CNT27_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT28_ENABLE_Msk (1UL << PMU_INTENCLR_CNT28_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT29_ENABLE_Msk (1UL << PMU_INTENCLR_CNT29_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT30_ENABLE_Msk (1UL << PMU_INTENCLR_CNT30_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CYCCNT_ENABLE_Msk (1UL << PMU_INTENCLR_CYCCNT_ENABLE_Pos) /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Mask */ + +/** \brief PMU Overflow Flag Status Set Register Definitions */ + +#define PMU_OVSSET_CNT0_STATUS_Pos 0U /*!< PMU OVSSET: Event Counter 0 Overflow Set Position */ +#define PMU_OVSSET_CNT0_STATUS_Msk (1UL /*<< PMU_OVSSET_CNT0_STATUS_Pos*/) /*!< PMU OVSSET: Event Counter 0 Overflow Set Mask */ + +#define PMU_OVSSET_CNT1_STATUS_Pos 1U /*!< PMU OVSSET: Event Counter 1 Overflow Set Position */ +#define PMU_OVSSET_CNT1_STATUS_Msk (1UL << PMU_OVSSET_CNT1_STATUS_Pos) /*!< PMU OVSSET: Event Counter 1 Overflow Set Mask */ + +#define PMU_OVSSET_CNT2_STATUS_Pos 2U /*!< PMU OVSSET: Event Counter 2 Overflow Set Position */ +#define PMU_OVSSET_CNT2_STATUS_Msk (1UL << PMU_OVSSET_CNT2_STATUS_Pos) /*!< PMU OVSSET: Event Counter 2 Overflow Set Mask */ + +#define PMU_OVSSET_CNT3_STATUS_Pos 3U /*!< PMU OVSSET: Event Counter 3 Overflow Set Position */ +#define PMU_OVSSET_CNT3_STATUS_Msk (1UL << PMU_OVSSET_CNT3_STATUS_Pos) /*!< PMU OVSSET: Event Counter 3 Overflow Set Mask */ + +#define PMU_OVSSET_CNT4_STATUS_Pos 4U /*!< PMU OVSSET: Event Counter 4 Overflow Set Position */ +#define PMU_OVSSET_CNT4_STATUS_Msk (1UL << PMU_OVSSET_CNT4_STATUS_Pos) /*!< PMU OVSSET: Event Counter 4 Overflow Set Mask */ + +#define PMU_OVSSET_CNT5_STATUS_Pos 5U /*!< PMU OVSSET: Event Counter 5 Overflow Set Position */ +#define PMU_OVSSET_CNT5_STATUS_Msk (1UL << PMU_OVSSET_CNT5_STATUS_Pos) /*!< PMU OVSSET: Event Counter 5 Overflow Set Mask */ + +#define PMU_OVSSET_CNT6_STATUS_Pos 6U /*!< PMU OVSSET: Event Counter 6 Overflow Set Position */ +#define PMU_OVSSET_CNT6_STATUS_Msk (1UL << PMU_OVSSET_CNT6_STATUS_Pos) /*!< PMU OVSSET: Event Counter 6 Overflow Set Mask */ + +#define PMU_OVSSET_CNT7_STATUS_Pos 7U /*!< PMU OVSSET: Event Counter 7 Overflow Set Position */ +#define PMU_OVSSET_CNT7_STATUS_Msk (1UL << PMU_OVSSET_CNT7_STATUS_Pos) /*!< PMU OVSSET: Event Counter 7 Overflow Set Mask */ + +#define PMU_OVSSET_CNT8_STATUS_Pos 8U /*!< PMU OVSSET: Event Counter 8 Overflow Set Position */ +#define PMU_OVSSET_CNT8_STATUS_Msk (1UL << PMU_OVSSET_CNT8_STATUS_Pos) /*!< PMU OVSSET: Event Counter 8 Overflow Set Mask */ + +#define PMU_OVSSET_CNT9_STATUS_Pos 9U /*!< PMU OVSSET: Event Counter 9 Overflow Set Position */ +#define PMU_OVSSET_CNT9_STATUS_Msk (1UL << PMU_OVSSET_CNT9_STATUS_Pos) /*!< PMU OVSSET: Event Counter 9 Overflow Set Mask */ + +#define PMU_OVSSET_CNT10_STATUS_Pos 10U /*!< PMU OVSSET: Event Counter 10 Overflow Set Position */ +#define PMU_OVSSET_CNT10_STATUS_Msk (1UL << PMU_OVSSET_CNT10_STATUS_Pos) /*!< PMU OVSSET: Event Counter 10 Overflow Set Mask */ + +#define PMU_OVSSET_CNT11_STATUS_Pos 11U /*!< PMU OVSSET: Event Counter 11 Overflow Set Position */ +#define PMU_OVSSET_CNT11_STATUS_Msk (1UL << PMU_OVSSET_CNT11_STATUS_Pos) /*!< PMU OVSSET: Event Counter 11 Overflow Set Mask */ + +#define PMU_OVSSET_CNT12_STATUS_Pos 12U /*!< PMU OVSSET: Event Counter 12 Overflow Set Position */ +#define PMU_OVSSET_CNT12_STATUS_Msk (1UL << PMU_OVSSET_CNT12_STATUS_Pos) /*!< PMU OVSSET: Event Counter 12 Overflow Set Mask */ + +#define PMU_OVSSET_CNT13_STATUS_Pos 13U /*!< PMU OVSSET: Event Counter 13 Overflow Set Position */ +#define PMU_OVSSET_CNT13_STATUS_Msk (1UL << PMU_OVSSET_CNT13_STATUS_Pos) /*!< PMU OVSSET: Event Counter 13 Overflow Set Mask */ + +#define PMU_OVSSET_CNT14_STATUS_Pos 14U /*!< PMU OVSSET: Event Counter 14 Overflow Set Position */ +#define PMU_OVSSET_CNT14_STATUS_Msk (1UL << PMU_OVSSET_CNT14_STATUS_Pos) /*!< PMU OVSSET: Event Counter 14 Overflow Set Mask */ + +#define PMU_OVSSET_CNT15_STATUS_Pos 15U /*!< PMU OVSSET: Event Counter 15 Overflow Set Position */ +#define PMU_OVSSET_CNT15_STATUS_Msk (1UL << PMU_OVSSET_CNT15_STATUS_Pos) /*!< PMU OVSSET: Event Counter 15 Overflow Set Mask */ + +#define PMU_OVSSET_CNT16_STATUS_Pos 16U /*!< PMU OVSSET: Event Counter 16 Overflow Set Position */ +#define PMU_OVSSET_CNT16_STATUS_Msk (1UL << PMU_OVSSET_CNT16_STATUS_Pos) /*!< PMU OVSSET: Event Counter 16 Overflow Set Mask */ + +#define PMU_OVSSET_CNT17_STATUS_Pos 17U /*!< PMU OVSSET: Event Counter 17 Overflow Set Position */ +#define PMU_OVSSET_CNT17_STATUS_Msk (1UL << PMU_OVSSET_CNT17_STATUS_Pos) /*!< PMU OVSSET: Event Counter 17 Overflow Set Mask */ + +#define PMU_OVSSET_CNT18_STATUS_Pos 18U /*!< PMU OVSSET: Event Counter 18 Overflow Set Position */ +#define PMU_OVSSET_CNT18_STATUS_Msk (1UL << PMU_OVSSET_CNT18_STATUS_Pos) /*!< PMU OVSSET: Event Counter 18 Overflow Set Mask */ + +#define PMU_OVSSET_CNT19_STATUS_Pos 19U /*!< PMU OVSSET: Event Counter 19 Overflow Set Position */ +#define PMU_OVSSET_CNT19_STATUS_Msk (1UL << PMU_OVSSET_CNT19_STATUS_Pos) /*!< PMU OVSSET: Event Counter 19 Overflow Set Mask */ + +#define PMU_OVSSET_CNT20_STATUS_Pos 20U /*!< PMU OVSSET: Event Counter 20 Overflow Set Position */ +#define PMU_OVSSET_CNT20_STATUS_Msk (1UL << PMU_OVSSET_CNT20_STATUS_Pos) /*!< PMU OVSSET: Event Counter 20 Overflow Set Mask */ + +#define PMU_OVSSET_CNT21_STATUS_Pos 21U /*!< PMU OVSSET: Event Counter 21 Overflow Set Position */ +#define PMU_OVSSET_CNT21_STATUS_Msk (1UL << PMU_OVSSET_CNT21_STATUS_Pos) /*!< PMU OVSSET: Event Counter 21 Overflow Set Mask */ + +#define PMU_OVSSET_CNT22_STATUS_Pos 22U /*!< PMU OVSSET: Event Counter 22 Overflow Set Position */ +#define PMU_OVSSET_CNT22_STATUS_Msk (1UL << PMU_OVSSET_CNT22_STATUS_Pos) /*!< PMU OVSSET: Event Counter 22 Overflow Set Mask */ + +#define PMU_OVSSET_CNT23_STATUS_Pos 23U /*!< PMU OVSSET: Event Counter 23 Overflow Set Position */ +#define PMU_OVSSET_CNT23_STATUS_Msk (1UL << PMU_OVSSET_CNT23_STATUS_Pos) /*!< PMU OVSSET: Event Counter 23 Overflow Set Mask */ + +#define PMU_OVSSET_CNT24_STATUS_Pos 24U /*!< PMU OVSSET: Event Counter 24 Overflow Set Position */ +#define PMU_OVSSET_CNT24_STATUS_Msk (1UL << PMU_OVSSET_CNT24_STATUS_Pos) /*!< PMU OVSSET: Event Counter 24 Overflow Set Mask */ + +#define PMU_OVSSET_CNT25_STATUS_Pos 25U /*!< PMU OVSSET: Event Counter 25 Overflow Set Position */ +#define PMU_OVSSET_CNT25_STATUS_Msk (1UL << PMU_OVSSET_CNT25_STATUS_Pos) /*!< PMU OVSSET: Event Counter 25 Overflow Set Mask */ + +#define PMU_OVSSET_CNT26_STATUS_Pos 26U /*!< PMU OVSSET: Event Counter 26 Overflow Set Position */ +#define PMU_OVSSET_CNT26_STATUS_Msk (1UL << PMU_OVSSET_CNT26_STATUS_Pos) /*!< PMU OVSSET: Event Counter 26 Overflow Set Mask */ + +#define PMU_OVSSET_CNT27_STATUS_Pos 27U /*!< PMU OVSSET: Event Counter 27 Overflow Set Position */ +#define PMU_OVSSET_CNT27_STATUS_Msk (1UL << PMU_OVSSET_CNT27_STATUS_Pos) /*!< PMU OVSSET: Event Counter 27 Overflow Set Mask */ + +#define PMU_OVSSET_CNT28_STATUS_Pos 28U /*!< PMU OVSSET: Event Counter 28 Overflow Set Position */ +#define PMU_OVSSET_CNT28_STATUS_Msk (1UL << PMU_OVSSET_CNT28_STATUS_Pos) /*!< PMU OVSSET: Event Counter 28 Overflow Set Mask */ + +#define PMU_OVSSET_CNT29_STATUS_Pos 29U /*!< PMU OVSSET: Event Counter 29 Overflow Set Position */ +#define PMU_OVSSET_CNT29_STATUS_Msk (1UL << PMU_OVSSET_CNT29_STATUS_Pos) /*!< PMU OVSSET: Event Counter 29 Overflow Set Mask */ + +#define PMU_OVSSET_CNT30_STATUS_Pos 30U /*!< PMU OVSSET: Event Counter 30 Overflow Set Position */ +#define PMU_OVSSET_CNT30_STATUS_Msk (1UL << PMU_OVSSET_CNT30_STATUS_Pos) /*!< PMU OVSSET: Event Counter 30 Overflow Set Mask */ + +#define PMU_OVSSET_CYCCNT_STATUS_Pos 31U /*!< PMU OVSSET: Cycle Counter Overflow Set Position */ +#define PMU_OVSSET_CYCCNT_STATUS_Msk (1UL << PMU_OVSSET_CYCCNT_STATUS_Pos) /*!< PMU OVSSET: Cycle Counter Overflow Set Mask */ + +/** \brief PMU Overflow Flag Status Clear Register Definitions */ + +#define PMU_OVSCLR_CNT0_STATUS_Pos 0U /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Position */ +#define PMU_OVSCLR_CNT0_STATUS_Msk (1UL /*<< PMU_OVSCLR_CNT0_STATUS_Pos*/) /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT1_STATUS_Pos 1U /*!< PMU OVSCLR: Event Counter 1 Overflow Clear Position */ +#define PMU_OVSCLR_CNT1_STATUS_Msk (1UL << PMU_OVSCLR_CNT1_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 1 Overflow Clear */ + +#define PMU_OVSCLR_CNT2_STATUS_Pos 2U /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Position */ +#define PMU_OVSCLR_CNT2_STATUS_Msk (1UL << PMU_OVSCLR_CNT2_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT3_STATUS_Pos 3U /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Position */ +#define PMU_OVSCLR_CNT3_STATUS_Msk (1UL << PMU_OVSCLR_CNT3_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT4_STATUS_Pos 4U /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Position */ +#define PMU_OVSCLR_CNT4_STATUS_Msk (1UL << PMU_OVSCLR_CNT4_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT5_STATUS_Pos 5U /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Position */ +#define PMU_OVSCLR_CNT5_STATUS_Msk (1UL << PMU_OVSCLR_CNT5_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT6_STATUS_Pos 6U /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Position */ +#define PMU_OVSCLR_CNT6_STATUS_Msk (1UL << PMU_OVSCLR_CNT6_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT7_STATUS_Pos 7U /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Position */ +#define PMU_OVSCLR_CNT7_STATUS_Msk (1UL << PMU_OVSCLR_CNT7_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT8_STATUS_Pos 8U /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Position */ +#define PMU_OVSCLR_CNT8_STATUS_Msk (1UL << PMU_OVSCLR_CNT8_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT9_STATUS_Pos 9U /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Position */ +#define PMU_OVSCLR_CNT9_STATUS_Msk (1UL << PMU_OVSCLR_CNT9_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT10_STATUS_Pos 10U /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Position */ +#define PMU_OVSCLR_CNT10_STATUS_Msk (1UL << PMU_OVSCLR_CNT10_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT11_STATUS_Pos 11U /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Position */ +#define PMU_OVSCLR_CNT11_STATUS_Msk (1UL << PMU_OVSCLR_CNT11_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT12_STATUS_Pos 12U /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Position */ +#define PMU_OVSCLR_CNT12_STATUS_Msk (1UL << PMU_OVSCLR_CNT12_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT13_STATUS_Pos 13U /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Position */ +#define PMU_OVSCLR_CNT13_STATUS_Msk (1UL << PMU_OVSCLR_CNT13_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT14_STATUS_Pos 14U /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Position */ +#define PMU_OVSCLR_CNT14_STATUS_Msk (1UL << PMU_OVSCLR_CNT14_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT15_STATUS_Pos 15U /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Position */ +#define PMU_OVSCLR_CNT15_STATUS_Msk (1UL << PMU_OVSCLR_CNT15_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT16_STATUS_Pos 16U /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Position */ +#define PMU_OVSCLR_CNT16_STATUS_Msk (1UL << PMU_OVSCLR_CNT16_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT17_STATUS_Pos 17U /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Position */ +#define PMU_OVSCLR_CNT17_STATUS_Msk (1UL << PMU_OVSCLR_CNT17_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT18_STATUS_Pos 18U /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Position */ +#define PMU_OVSCLR_CNT18_STATUS_Msk (1UL << PMU_OVSCLR_CNT18_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT19_STATUS_Pos 19U /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Position */ +#define PMU_OVSCLR_CNT19_STATUS_Msk (1UL << PMU_OVSCLR_CNT19_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT20_STATUS_Pos 20U /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Position */ +#define PMU_OVSCLR_CNT20_STATUS_Msk (1UL << PMU_OVSCLR_CNT20_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT21_STATUS_Pos 21U /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Position */ +#define PMU_OVSCLR_CNT21_STATUS_Msk (1UL << PMU_OVSCLR_CNT21_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT22_STATUS_Pos 22U /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Position */ +#define PMU_OVSCLR_CNT22_STATUS_Msk (1UL << PMU_OVSCLR_CNT22_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT23_STATUS_Pos 23U /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Position */ +#define PMU_OVSCLR_CNT23_STATUS_Msk (1UL << PMU_OVSCLR_CNT23_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT24_STATUS_Pos 24U /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Position */ +#define PMU_OVSCLR_CNT24_STATUS_Msk (1UL << PMU_OVSCLR_CNT24_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT25_STATUS_Pos 25U /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Position */ +#define PMU_OVSCLR_CNT25_STATUS_Msk (1UL << PMU_OVSCLR_CNT25_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT26_STATUS_Pos 26U /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Position */ +#define PMU_OVSCLR_CNT26_STATUS_Msk (1UL << PMU_OVSCLR_CNT26_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT27_STATUS_Pos 27U /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Position */ +#define PMU_OVSCLR_CNT27_STATUS_Msk (1UL << PMU_OVSCLR_CNT27_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT28_STATUS_Pos 28U /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Position */ +#define PMU_OVSCLR_CNT28_STATUS_Msk (1UL << PMU_OVSCLR_CNT28_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT29_STATUS_Pos 29U /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Position */ +#define PMU_OVSCLR_CNT29_STATUS_Msk (1UL << PMU_OVSCLR_CNT29_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT30_STATUS_Pos 30U /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Position */ +#define PMU_OVSCLR_CNT30_STATUS_Msk (1UL << PMU_OVSCLR_CNT30_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Mask */ + +#define PMU_OVSCLR_CYCCNT_STATUS_Pos 31U /*!< PMU OVSCLR: Cycle Counter Overflow Clear Position */ +#define PMU_OVSCLR_CYCCNT_STATUS_Msk (1UL << PMU_OVSCLR_CYCCNT_STATUS_Pos) /*!< PMU OVSCLR: Cycle Counter Overflow Clear Mask */ + +/** \brief PMU Software Increment Counter */ + +#define PMU_SWINC_CNT0_Pos 0U /*!< PMU SWINC: Event Counter 0 Software Increment Position */ +#define PMU_SWINC_CNT0_Msk (1UL /*<< PMU_SWINC_CNT0_Pos */) /*!< PMU SWINC: Event Counter 0 Software Increment Mask */ + +#define PMU_SWINC_CNT1_Pos 1U /*!< PMU SWINC: Event Counter 1 Software Increment Position */ +#define PMU_SWINC_CNT1_Msk (1UL << PMU_SWINC_CNT1_Pos) /*!< PMU SWINC: Event Counter 1 Software Increment Mask */ + +#define PMU_SWINC_CNT2_Pos 2U /*!< PMU SWINC: Event Counter 2 Software Increment Position */ +#define PMU_SWINC_CNT2_Msk (1UL << PMU_SWINC_CNT2_Pos) /*!< PMU SWINC: Event Counter 2 Software Increment Mask */ + +#define PMU_SWINC_CNT3_Pos 3U /*!< PMU SWINC: Event Counter 3 Software Increment Position */ +#define PMU_SWINC_CNT3_Msk (1UL << PMU_SWINC_CNT3_Pos) /*!< PMU SWINC: Event Counter 3 Software Increment Mask */ + +#define PMU_SWINC_CNT4_Pos 4U /*!< PMU SWINC: Event Counter 4 Software Increment Position */ +#define PMU_SWINC_CNT4_Msk (1UL << PMU_SWINC_CNT4_Pos) /*!< PMU SWINC: Event Counter 4 Software Increment Mask */ + +#define PMU_SWINC_CNT5_Pos 5U /*!< PMU SWINC: Event Counter 5 Software Increment Position */ +#define PMU_SWINC_CNT5_Msk (1UL << PMU_SWINC_CNT5_Pos) /*!< PMU SWINC: Event Counter 5 Software Increment Mask */ + +#define PMU_SWINC_CNT6_Pos 6U /*!< PMU SWINC: Event Counter 6 Software Increment Position */ +#define PMU_SWINC_CNT6_Msk (1UL << PMU_SWINC_CNT6_Pos) /*!< PMU SWINC: Event Counter 6 Software Increment Mask */ + +#define PMU_SWINC_CNT7_Pos 7U /*!< PMU SWINC: Event Counter 7 Software Increment Position */ +#define PMU_SWINC_CNT7_Msk (1UL << PMU_SWINC_CNT7_Pos) /*!< PMU SWINC: Event Counter 7 Software Increment Mask */ + +#define PMU_SWINC_CNT8_Pos 8U /*!< PMU SWINC: Event Counter 8 Software Increment Position */ +#define PMU_SWINC_CNT8_Msk (1UL << PMU_SWINC_CNT8_Pos) /*!< PMU SWINC: Event Counter 8 Software Increment Mask */ + +#define PMU_SWINC_CNT9_Pos 9U /*!< PMU SWINC: Event Counter 9 Software Increment Position */ +#define PMU_SWINC_CNT9_Msk (1UL << PMU_SWINC_CNT9_Pos) /*!< PMU SWINC: Event Counter 9 Software Increment Mask */ + +#define PMU_SWINC_CNT10_Pos 10U /*!< PMU SWINC: Event Counter 10 Software Increment Position */ +#define PMU_SWINC_CNT10_Msk (1UL << PMU_SWINC_CNT10_Pos) /*!< PMU SWINC: Event Counter 10 Software Increment Mask */ + +#define PMU_SWINC_CNT11_Pos 11U /*!< PMU SWINC: Event Counter 11 Software Increment Position */ +#define PMU_SWINC_CNT11_Msk (1UL << PMU_SWINC_CNT11_Pos) /*!< PMU SWINC: Event Counter 11 Software Increment Mask */ + +#define PMU_SWINC_CNT12_Pos 12U /*!< PMU SWINC: Event Counter 12 Software Increment Position */ +#define PMU_SWINC_CNT12_Msk (1UL << PMU_SWINC_CNT12_Pos) /*!< PMU SWINC: Event Counter 12 Software Increment Mask */ + +#define PMU_SWINC_CNT13_Pos 13U /*!< PMU SWINC: Event Counter 13 Software Increment Position */ +#define PMU_SWINC_CNT13_Msk (1UL << PMU_SWINC_CNT13_Pos) /*!< PMU SWINC: Event Counter 13 Software Increment Mask */ + +#define PMU_SWINC_CNT14_Pos 14U /*!< PMU SWINC: Event Counter 14 Software Increment Position */ +#define PMU_SWINC_CNT14_Msk (1UL << PMU_SWINC_CNT14_Pos) /*!< PMU SWINC: Event Counter 14 Software Increment Mask */ + +#define PMU_SWINC_CNT15_Pos 15U /*!< PMU SWINC: Event Counter 15 Software Increment Position */ +#define PMU_SWINC_CNT15_Msk (1UL << PMU_SWINC_CNT15_Pos) /*!< PMU SWINC: Event Counter 15 Software Increment Mask */ + +#define PMU_SWINC_CNT16_Pos 16U /*!< PMU SWINC: Event Counter 16 Software Increment Position */ +#define PMU_SWINC_CNT16_Msk (1UL << PMU_SWINC_CNT16_Pos) /*!< PMU SWINC: Event Counter 16 Software Increment Mask */ + +#define PMU_SWINC_CNT17_Pos 17U /*!< PMU SWINC: Event Counter 17 Software Increment Position */ +#define PMU_SWINC_CNT17_Msk (1UL << PMU_SWINC_CNT17_Pos) /*!< PMU SWINC: Event Counter 17 Software Increment Mask */ + +#define PMU_SWINC_CNT18_Pos 18U /*!< PMU SWINC: Event Counter 18 Software Increment Position */ +#define PMU_SWINC_CNT18_Msk (1UL << PMU_SWINC_CNT18_Pos) /*!< PMU SWINC: Event Counter 18 Software Increment Mask */ + +#define PMU_SWINC_CNT19_Pos 19U /*!< PMU SWINC: Event Counter 19 Software Increment Position */ +#define PMU_SWINC_CNT19_Msk (1UL << PMU_SWINC_CNT19_Pos) /*!< PMU SWINC: Event Counter 19 Software Increment Mask */ + +#define PMU_SWINC_CNT20_Pos 20U /*!< PMU SWINC: Event Counter 20 Software Increment Position */ +#define PMU_SWINC_CNT20_Msk (1UL << PMU_SWINC_CNT20_Pos) /*!< PMU SWINC: Event Counter 20 Software Increment Mask */ + +#define PMU_SWINC_CNT21_Pos 21U /*!< PMU SWINC: Event Counter 21 Software Increment Position */ +#define PMU_SWINC_CNT21_Msk (1UL << PMU_SWINC_CNT21_Pos) /*!< PMU SWINC: Event Counter 21 Software Increment Mask */ + +#define PMU_SWINC_CNT22_Pos 22U /*!< PMU SWINC: Event Counter 22 Software Increment Position */ +#define PMU_SWINC_CNT22_Msk (1UL << PMU_SWINC_CNT22_Pos) /*!< PMU SWINC: Event Counter 22 Software Increment Mask */ + +#define PMU_SWINC_CNT23_Pos 23U /*!< PMU SWINC: Event Counter 23 Software Increment Position */ +#define PMU_SWINC_CNT23_Msk (1UL << PMU_SWINC_CNT23_Pos) /*!< PMU SWINC: Event Counter 23 Software Increment Mask */ + +#define PMU_SWINC_CNT24_Pos 24U /*!< PMU SWINC: Event Counter 24 Software Increment Position */ +#define PMU_SWINC_CNT24_Msk (1UL << PMU_SWINC_CNT24_Pos) /*!< PMU SWINC: Event Counter 24 Software Increment Mask */ + +#define PMU_SWINC_CNT25_Pos 25U /*!< PMU SWINC: Event Counter 25 Software Increment Position */ +#define PMU_SWINC_CNT25_Msk (1UL << PMU_SWINC_CNT25_Pos) /*!< PMU SWINC: Event Counter 25 Software Increment Mask */ + +#define PMU_SWINC_CNT26_Pos 26U /*!< PMU SWINC: Event Counter 26 Software Increment Position */ +#define PMU_SWINC_CNT26_Msk (1UL << PMU_SWINC_CNT26_Pos) /*!< PMU SWINC: Event Counter 26 Software Increment Mask */ + +#define PMU_SWINC_CNT27_Pos 27U /*!< PMU SWINC: Event Counter 27 Software Increment Position */ +#define PMU_SWINC_CNT27_Msk (1UL << PMU_SWINC_CNT27_Pos) /*!< PMU SWINC: Event Counter 27 Software Increment Mask */ + +#define PMU_SWINC_CNT28_Pos 28U /*!< PMU SWINC: Event Counter 28 Software Increment Position */ +#define PMU_SWINC_CNT28_Msk (1UL << PMU_SWINC_CNT28_Pos) /*!< PMU SWINC: Event Counter 28 Software Increment Mask */ + +#define PMU_SWINC_CNT29_Pos 29U /*!< PMU SWINC: Event Counter 29 Software Increment Position */ +#define PMU_SWINC_CNT29_Msk (1UL << PMU_SWINC_CNT29_Pos) /*!< PMU SWINC: Event Counter 29 Software Increment Mask */ + +#define PMU_SWINC_CNT30_Pos 30U /*!< PMU SWINC: Event Counter 30 Software Increment Position */ +#define PMU_SWINC_CNT30_Msk (1UL << PMU_SWINC_CNT30_Pos) /*!< PMU SWINC: Event Counter 30 Software Increment Mask */ + +/** \brief PMU Control Register Definitions */ + +#define PMU_CTRL_ENABLE_Pos 0U /*!< PMU CTRL: ENABLE Position */ +#define PMU_CTRL_ENABLE_Msk (1UL /*<< PMU_CTRL_ENABLE_Pos*/) /*!< PMU CTRL: ENABLE Mask */ + +#define PMU_CTRL_EVENTCNT_RESET_Pos 1U /*!< PMU CTRL: Event Counter Reset Position */ +#define PMU_CTRL_EVENTCNT_RESET_Msk (1UL << PMU_CTRL_EVENTCNT_RESET_Pos) /*!< PMU CTRL: Event Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_RESET_Pos 2U /*!< PMU CTRL: Cycle Counter Reset Position */ +#define PMU_CTRL_CYCCNT_RESET_Msk (1UL << PMU_CTRL_CYCCNT_RESET_Pos) /*!< PMU CTRL: Cycle Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_DISABLE_Pos 5U /*!< PMU CTRL: Disable Cycle Counter Position */ +#define PMU_CTRL_CYCCNT_DISABLE_Msk (1UL << PMU_CTRL_CYCCNT_DISABLE_Pos) /*!< PMU CTRL: Disable Cycle Counter Mask */ + +#define PMU_CTRL_FRZ_ON_OV_Pos 9U /*!< PMU CTRL: Freeze-on-overflow Position */ +#define PMU_CTRL_FRZ_ON_OV_Msk (1UL << PMU_CTRL_FRZ_ON_OVERFLOW_Pos) /*!< PMU CTRL: Freeze-on-overflow Mask */ + +#define PMU_CTRL_TRACE_ON_OV_Pos 11U /*!< PMU CTRL: Trace-on-overflow Position */ +#define PMU_CTRL_TRACE_ON_OV_Msk (1UL << PMU_CTRL_TRACE_ON_OVERFLOW_Pos) /*!< PMU CTRL: Trace-on-overflow Mask */ + +/** \brief PMU Type Register Definitions */ + +#define PMU_TYPE_NUM_CNTS_Pos 0U /*!< PMU TYPE: Number of Counters Position */ +#define PMU_TYPE_NUM_CNTS_Msk (0xFFUL /*<< PMU_TYPE_NUM_CNTS_Pos*/) /*!< PMU TYPE: Number of Counters Mask */ + +#define PMU_TYPE_SIZE_CNTS_Pos 8U /*!< PMU TYPE: Size of Counters Position */ +#define PMU_TYPE_SIZE_CNTS_Msk (0x3FUL << PMU_TYPE_SIZE_CNTS_Pos) /*!< PMU TYPE: Size of Counters Mask */ + +#define PMU_TYPE_CYCCNT_PRESENT_Pos 14U /*!< PMU TYPE: Cycle Counter Present Position */ +#define PMU_TYPE_CYCCNT_PRESENT_Msk (1UL << PMU_TYPE_CYCCNT_PRESENT_Pos) /*!< PMU TYPE: Cycle Counter Present Mask */ + +#define PMU_TYPE_FRZ_OV_SUPPORT_Pos 21U /*!< PMU TYPE: Freeze-on-overflow Support Position */ +#define PMU_TYPE_FRZ_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Freeze-on-overflow Support Mask */ + +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Pos 23U /*!< PMU TYPE: Trace-on-overflow Support Position */ +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Trace-on-overflow Support Mask */ + +/** \brief PMU Authentication Status Register Definitions */ + +#define PMU_AUTHSTATUS_NSID_Pos 0U /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSID_Msk (0x3UL /*<< PMU_AUTHSTATUS_NSID_Pos*/) /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSNID_Pos 2U /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSNID_Msk (0x3UL << PMU_AUTHSTATUS_NSNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SID_Pos 4U /*!< PMU AUTHSTATUS: Secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_SID_Msk (0x3UL << PMU_AUTHSTATUS_SID_Pos) /*!< PMU AUTHSTATUS: Secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SNID_Pos 6U /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SNID_Msk (0x3UL << PMU_AUTHSTATUS_SNID_Pos) /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUID_Pos 16U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUID_Msk (0x3UL << PMU_AUTHSTATUS_NSUID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUNID_Pos 18U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUNID_Msk (0x3UL << PMU_AUTHSTATUS_NSUNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUID_Pos 20U /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_SUID_Msk (0x3UL << PMU_AUTHSTATUS_SUID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUNID_Pos 22U /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SUNID_Msk (0x3UL << PMU_AUTHSTATUS_SUNID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Mask */ + + +/*@} end of group CMSIS_PMU */ +#endif + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +#define FPU_FPDSCR_FZ16_Pos 19U /*!< FPDSCR: FZ16 bit Position */ +#define FPU_FPDSCR_FZ16_Msk (1UL << FPU_FPDSCR_FZ16_Pos) /*!< FPDSCR: FZ16 bit Mask */ + +#define FPU_FPDSCR_LTPSIZE_Pos 16U /*!< FPDSCR: LTPSIZE bit Position */ +#define FPU_FPDSCR_LTPSIZE_Msk (7UL << FPU_FPDSCR_LTPSIZE_Pos) /*!< FPDSCR: LTPSIZE bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FPRound_Pos 28U /*!< MVFR0: FPRound bits Position */ +#define FPU_MVFR0_FPRound_Msk (0xFUL << FPU_MVFR0_FPRound_Pos) /*!< MVFR0: FPRound bits Mask */ + +#define FPU_MVFR0_FPSqrt_Pos 20U /*!< MVFR0: FPSqrt bits Position */ +#define FPU_MVFR0_FPSqrt_Msk (0xFUL << FPU_MVFR0_FPSqrt_Pos) /*!< MVFR0: FPSqrt bits Mask */ + +#define FPU_MVFR0_FPDivide_Pos 16U /*!< MVFR0: FPDivide bits Position */ +#define FPU_MVFR0_FPDivide_Msk (0xFUL << FPU_MVFR0_FPDivide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FPDP_Pos 8U /*!< MVFR0: FPDP bits Position */ +#define FPU_MVFR0_FPDP_Msk (0xFUL << FPU_MVFR0_FPDP_Pos) /*!< MVFR0: FPDP bits Mask */ + +#define FPU_MVFR0_FPSP_Pos 4U /*!< MVFR0: FPSP bits Position */ +#define FPU_MVFR0_FPSP_Msk (0xFUL << FPU_MVFR0_FPSP_Pos) /*!< MVFR0: FPSP bits Mask */ + +#define FPU_MVFR0_SIMDReg_Pos 0U /*!< MVFR0: SIMDReg bits Position */ +#define FPU_MVFR0_SIMDReg_Msk (0xFUL /*<< FPU_MVFR0_SIMDReg_Pos*/) /*!< MVFR0: SIMDReg bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FMAC_Pos 28U /*!< MVFR1: FMAC bits Position */ +#define FPU_MVFR1_FMAC_Msk (0xFUL << FPU_MVFR1_FMAC_Pos) /*!< MVFR1: FMAC bits Mask */ + +#define FPU_MVFR1_FPHP_Pos 24U /*!< MVFR1: FPHP bits Position */ +#define FPU_MVFR1_FPHP_Msk (0xFUL << FPU_MVFR1_FPHP_Pos) /*!< MVFR1: FPHP bits Mask */ + +#define FPU_MVFR1_FP16_Pos 20U /*!< MVFR1: FP16 bits Position */ +#define FPU_MVFR1_FP16_Msk (0xFUL << FPU_MVFR1_FP16_Pos) /*!< MVFR1: FP16 bits Mask */ + +#define FPU_MVFR1_MVE_Pos 8U /*!< MVFR1: MVE bits Position */ +#define FPU_MVFR1_MVE_Msk (0xFUL << FPU_MVFR1_MVE_Pos) /*!< MVFR1: MVE bits Mask */ + +#define FPU_MVFR1_FPDNaN_Pos 4U /*!< MVFR1: FPDNaN bits Position */ +#define FPU_MVFR1_FPDNaN_Msk (0xFUL << FPU_MVFR1_FPDNaN_Pos) /*!< MVFR1: FPDNaN bits Mask */ + +#define FPU_MVFR1_FPFtZ_Pos 0U /*!< MVFR1: FPFtZ bits Position */ +#define FPU_MVFR1_FPFtZ_Msk (0xFUL /*<< FPU_MVFR1_FPFtZ_Pos*/) /*!< MVFR1: FPFtZ bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_FPD_Pos 23U /*!< \deprecated CoreDebug DHCSR: S_FPD Position */ +#define CoreDebug_DHCSR_S_FPD_Msk (1UL << CoreDebug_DHCSR_S_FPD_Pos) /*!< \deprecated CoreDebug DHCSR: S_FPD Mask */ + +#define CoreDebug_DHCSR_S_SUIDE_Pos 22U /*!< \deprecated CoreDebug DHCSR: S_SUIDE Position */ +#define CoreDebug_DHCSR_S_SUIDE_Msk (1UL << CoreDebug_DHCSR_S_SUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SUIDE Mask */ + +#define CoreDebug_DHCSR_S_NSUIDE_Pos 21U /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Position */ +#define CoreDebug_DHCSR_S_NSUIDE_Msk (1UL << CoreDebug_DHCSR_S_NSUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Mask */ + +#define CoreDebug_DHCSR_S_SDE_Pos 20U /*!< \deprecated CoreDebug DHCSR: S_SDE Position */ +#define CoreDebug_DHCSR_S_SDE_Msk (1UL << CoreDebug_DHCSR_S_SDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SDE Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_PMOV_Pos 6U /*!< \deprecated CoreDebug DHCSR: C_PMOV Position */ +#define CoreDebug_DHCSR_C_PMOV_Msk (1UL << CoreDebug_DHCSR_C_PMOV_Pos) /*!< \deprecated CoreDebug DHCSR: C_PMOV Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Set Clear Exception and Monitor Control Register Definitions */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_REQ_Pos 3U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_SET_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_PEND_Pos 1U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_SET_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_UIDEN_Pos 10U /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_UIDAPEN_Pos 9U /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDAPEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDAPEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Mask */ + +#define CoreDebug_DAUTHCTRL_FSDMA_Pos 8U /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Position */ +#define CoreDebug_DAUTHCTRL_FSDMA_Msk (1UL << CoreDebug_DAUTHCTRL_FSDMA_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_FPD_Pos 23U /*!< DCB DHCSR: Floating-point registers Debuggable Position */ +#define DCB_DHCSR_S_FPD_Msk (0x1UL << DCB_DHCSR_S_FPD_Pos) /*!< DCB DHCSR: Floating-point registers Debuggable Mask */ + +#define DCB_DHCSR_S_SUIDE_Pos 22U /*!< DCB DHCSR: Secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_SUIDE_Msk (0x1UL << DCB_DHCSR_S_SUIDE_Pos) /*!< DCB DHCSR: Secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_NSUIDE_Pos 21U /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_NSUIDE_Msk (0x1UL << DCB_DHCSR_S_NSUIDE_Pos) /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_PMOV_Pos 6U /*!< DCB DHCSR: Halt on PMU overflow control Position */ +#define DCB_DHCSR_C_PMOV_Msk (0x1UL << DCB_DHCSR_C_PMOV_Pos) /*!< DCB DHCSR: Halt on PMU overflow control Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DSCEMCR, Debug Set Clear Exception and Monitor Control Register Definitions */ +#define DCB_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< DCB DSCEMCR: Clear monitor request Position */ +#define DCB_DSCEMCR_CLR_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_REQ_Pos) /*!< DCB DSCEMCR: Clear monitor request Mask */ + +#define DCB_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< DCB DSCEMCR: Clear monitor pend Position */ +#define DCB_DSCEMCR_CLR_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_PEND_Pos) /*!< DCB DSCEMCR: Clear monitor pend Mask */ + +#define DCB_DSCEMCR_SET_MON_REQ_Pos 3U /*!< DCB DSCEMCR: Set monitor request Position */ +#define DCB_DSCEMCR_SET_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_SET_MON_REQ_Pos) /*!< DCB DSCEMCR: Set monitor request Mask */ + +#define DCB_DSCEMCR_SET_MON_PEND_Pos 1U /*!< DCB DSCEMCR: Set monitor pend Position */ +#define DCB_DSCEMCR_SET_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_SET_MON_PEND_Pos) /*!< DCB DSCEMCR: Set monitor pend Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_UIDEN_Pos 10U /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Position */ +#define DCB_DAUTHCTRL_UIDEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Mask */ + +#define DCB_DAUTHCTRL_UIDAPEN_Pos 9U /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Position */ +#define DCB_DAUTHCTRL_UIDAPEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDAPEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Mask */ + +#define DCB_DAUTHCTRL_FSDMA_Pos 8U /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Position */ +#define DCB_DAUTHCTRL_FSDMA_Msk (0x1UL << DCB_DAUTHCTRL_FSDMA_Pos) /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Mask */ + +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SUNID_Pos 22U /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUNID_Msk (0x3UL << DIB_DAUTHSTATUS_SUNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SUID_Pos 20U /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUID_Msk (0x3UL << DIB_DAUTHSTATUS_SUID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_NSUNID_Pos 18U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Position */ +#define DIB_DAUTHSTATUS_NSUNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Mask */ + +#define DIB_DAUTHSTATUS_NSUID_Pos 16U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_NSUID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define MEMSYSCTL_BASE (0xE001E000UL) /*!< Memory System Control Base Address */ + #define ERRBNK_BASE (0xE001E100UL) /*!< Error Banking Base Address */ + #define PWRMODCTL_BASE (0xE001E300UL) /*!< Power Mode Control Base Address */ + #define EWIC_BASE (0xE001E400UL) /*!< External Wakeup Interrupt Controller Base Address */ + #define PRCCFGINF_BASE (0xE001E700UL) /*!< Processor Configuration Information Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define ICB ((ICB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define MEMSYSCTL ((MemSysCtl_Type *) MEMSYSCTL_BASE ) /*!< Memory System Control configuration struct */ + #define ERRBNK ((ErrBnk_Type *) ERRBNK_BASE ) /*!< Error Banking configuration struct */ + #define PWRMODCTL ((PwrModCtl_Type *) PWRMODCTL_BASE ) /*!< Power Mode Control configuration struct */ + #define EWIC ((EWIC_Type *) EWIC_BASE ) /*!< EWIC configuration struct */ + #define PRCCFGINF ((PrcCfgInf_Type *) PRCCFGINF_BASE ) /*!< Processor Configuration Information configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + #define PMU_BASE (0xE0003000UL) /*!< PMU Base Address */ + #define PMU ((PMU_Type *) PMU_BASE ) /*!< PMU configuration struct */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define ICB_NS ((ICB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ + +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## PMU functions and events #################################### */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + +#include "pmu_armv8.h" + +/** + \brief Cortex-M85 PMU events + \note Architectural PMU events can be found in pmu_armv8.h +*/ + +#define ARMCM85_PMU_ECC_ERR 0xC000 /*!< One or more Error Correcting Code (ECC) errors detected */ +#define ARMCM85_PMU_ECC_ERR_MBIT 0xC001 /*!< One or more multi-bit ECC errors detected */ +#define ARMCM85_PMU_ECC_ERR_DCACHE 0xC010 /*!< One or more ECC errors in the data cache */ +#define ARMCM85_PMU_ECC_ERR_ICACHE 0xC011 /*!< One or more ECC errors in the instruction cache */ +#define ARMCM85_PMU_ECC_ERR_MBIT_DCACHE 0xC012 /*!< One or more multi-bit ECC errors in the data cache */ +#define ARMCM85_PMU_ECC_ERR_MBIT_ICACHE 0xC013 /*!< One or more multi-bit ECC errors in the instruction cache */ +#define ARMCM85_PMU_ECC_ERR_DTCM 0xC020 /*!< One or more ECC errors in the Data Tightly Coupled Memory (DTCM) */ +#define ARMCM85_PMU_ECC_ERR_ITCM 0xC021 /*!< One or more ECC errors in the Instruction Tightly Coupled Memory (ITCM) */ +#define ARMCM85_PMU_ECC_ERR_MBIT_DTCM 0xC022 /*!< One or more multi-bit ECC errors in the DTCM */ +#define ARMCM85_PMU_ECC_ERR_MBIT_ITCM 0xC023 /*!< One or more multi-bit ECC errors in the ITCM */ +#define ARMCM85_PMU_PF_LINEFILL 0xC100 /*!< The prefetcher starts a line-fill */ +#define ARMCM85_PMU_PF_CANCEL 0xC101 /*!< The prefetcher stops prefetching */ +#define ARMCM85_PMU_PF_DROP_LINEFILL 0xC102 /*!< A linefill triggered by a prefetcher has been dropped because of lack of buffering */ +#define ARMCM85_PMU_NWAMODE_ENTER 0xC200 /*!< No write-allocate mode entry */ +#define ARMCM85_PMU_NWAMODE 0xC201 /*!< Write-allocate store is not allocated into the data cache due to no-write-allocate mode */ +#define ARMCM85_PMU_SAHB_ACCESS 0xC300 /*!< Read or write access on the S-AHB interface to the TCM */ +#define ARMCM85_PMU_PAHB_ACCESS 0xC301 /*!< Read or write access on the P-AHB write interface */ +#define ARMCM85_PMU_AXI_WRITE_ACCESS 0xC302 /*!< Any beat access to M-AXI write interface */ +#define ARMCM85_PMU_AXI_READ_ACCESS 0xC303 /*!< Any beat access to M-AXI read interface */ +#define ARMCM85_PMU_DOSTIMEOUT_DOUBLE 0xC400 /*!< Denial of Service timeout has fired twice and caused buffers to drain to allow forward progress */ +#define ARMCM85_PMU_DOSTIMEOUT_TRIPLE 0xC401 /*!< Denial of Service timeout has fired three times and blocked the LSU to force forward progress */ + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + +/* ########################## MVE functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_MveFunctions MVE Functions + \brief Function that provides MVE type. + @{ + */ + +/** + \brief get MVE type + \details returns the MVE type + \returns + - \b 0: No Vector Extension (MVE) + - \b 1: Integer Vector Extension (MVE-I) + - \b 2: Floating-point Vector Extension (MVE-F) + */ +__STATIC_INLINE uint32_t SCB_GetMVEType(void) +{ + const uint32_t mvfr1 = FPU->MVFR1; + if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x2U << FPU_MVFR1_MVE_Pos)) + { + return 2U; + } + else if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x1U << FPU_MVFR1_MVE_Pos)) + { + return 1U; + } + else + { + return 0U; + } +} + + +/*@} end of CMSIS_Core_MveFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + +/* ################### PAC Key functions ########################### */ + +#if (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) +#include "pac_armv81.h" +#endif + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM85_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_sc000.h b/Drivers/CMSIS/Core/Include/core_sc000.h new file mode 100644 index 0000000..357c1df --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_sc000.h @@ -0,0 +1,1030 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 27. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M0 and M0+ do not require the architectural barrier - assume SC000 is the same */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_sc300.h b/Drivers/CMSIS/Core/Include/core_sc300.h new file mode 100644 index 0000000..5b66b5f --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_sc300.h @@ -0,0 +1,1917 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.10 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/core_starmc1.h b/Drivers/CMSIS/Core/Include/core_starmc1.h new file mode 100644 index 0000000..68f5bce --- /dev/null +++ b/Drivers/CMSIS/Core/Include/core_starmc1.h @@ -0,0 +1,3592 @@ +/**************************************************************************//** + * @file core_starmc1.h + * @brief CMSIS ArmChina STAR-MC1 Core Peripheral Access Layer Header File + * @version V1.0.2 + * @date 07. April 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. + * Copyright (c) 2018-2022 Arm China. + * All rights reserved. + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_STAR_H_GENERIC +#define __CORE_STAR_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup STAR-MC1 + @{ + */ + +#include "cmsis_version.h" + +/* Macro Define for STAR-MC1 */ +#define __STAR_MC (1U) /*!< STAR-MC Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_STAR_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_STAR_H_DEPENDANT +#define __CORE_STAR_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __STAR_REV + #define __STAR_REV 0x0000U + #warning "__STAR_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group STAR-MC1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for STAR-MC1 processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED_ADD1[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: F00-D00=0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} SCB_Type; + +typedef struct +{ + __IOM uint32_t CACR; /*!< Offset: 0x0 (R/W) L1 Cache Control Register */ + __IOM uint32_t ITCMCR; /*!< Offset: 0x10 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x14 (R/W) Data Tightly-Coupled Memory Control Registers */ +}EMSS_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +#define SCB_CLIDR_IC_Pos 0U /*!< SCB CLIDR: IC Position */ +#define SCB_CLIDR_IC_Msk (1UL << SCB_CLIDR_IC_Pos) /*!< SCB CLIDR: IC Mask */ + +#define SCB_CLIDR_DC_Pos 1U /*!< SCB CLIDR: DC Position */ +#define SCB_CLIDR_DC_Msk (1UL << SCB_CLIDR_DC_Pos) /*!< SCB CLIDR: DC Mask */ + + + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache line Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_LEVEL_Pos 1U /*!< SCB DCISW: Level Position */ +#define SCB_DCISW_LEVEL_Msk (7UL << SCB_DCISW_LEVEL_Pos) /*!< SCB DCISW: Level Mask */ + +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0xFFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean line by Set-way Register Definitions */ +#define SCB_DCCSW_LEVEL_Pos 1U /*!< SCB DCCSW: Level Position */ +#define SCB_DCCSW_LEVEL_Msk (7UL << SCB_DCCSW_LEVEL_Pos) /*!< SCB DCCSW: Level Mask */ + +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0xFFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_LEVEL_Pos 1U /*!< SCB DCCISW: Level Position */ +#define SCB_DCCISW_LEVEL_Msk (7UL << SCB_DCCISW_LEVEL_Pos) /*!< SCB DCCISW: Level Mask */ + +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0xFFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* ArmChina: Implementation Defined */ +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_DCCLEAN_Pos 16U /*!< SCB CACR: DCCLEAN Position */ +#define SCB_CACR_DCCLEAN_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: DCCLEAN Mask */ + +#define SCB_CACR_ICACTIVE_Pos 13U /*!< SCB CACR: ICACTIVE Position */ +#define SCB_CACR_ICACTIVE_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: ICACTIVE Mask */ + +#define SCB_CACR_DCACTIVE_Pos 12U /*!< SCB CACR: DCACTIVE Position */ +#define SCB_CACR_DCACTIVE_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: DCACTIVE Mask */ + +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define EMSS_BASE (0xE001E000UL) /*!AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses including + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/** + \brief Software Reset + \details Initiates a system reset request to reset the CPU. + */ +__NO_RETURN __STATIC_INLINE void __SW_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses including + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_BFHFNMINS_Msk) | /* Keep BFHFNMINS unchanged. Use this Reset function in case your case need to keep it */ + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | /* Keep priority group unchanged */ + SCB_AIRCR_SYSRESETREQ_Msk ); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#define __SCB_DCACHE_LINE_SIZE 32U /*!< STAR-MC1 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#define __SCB_ICACHE_LINE_SIZE 32U /*!< STAR-MC1 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief I-Cache Invalidate by address + \details Invalidates I-Cache for the given address. + I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + I-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] isize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (void *addr, int32_t isize) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if ( isize > 0 ) { + int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_ICACHE_LINE_SIZE; + op_size -= __SCB_ICACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ +#endif + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_STAR_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core/Include/mpu_armv7.h b/Drivers/CMSIS/Core/Include/mpu_armv7.h new file mode 100644 index 0000000..3b26817 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.2 + * @date 25. May 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load(). +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/Drivers/CMSIS/Core/Include/mpu_armv8.h b/Drivers/CMSIS/Core/Include/mpu_armv8.h new file mode 100644 index 0000000..b6ff9a9 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/mpu_armv8.h @@ -0,0 +1,352 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU + * @version V5.1.3 + * @date 03. February 2021 + ******************************************************************************/ +/* + * Copyright (c) 2017-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + ((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + (((BASE) & MPU_RBAR_BASE_Msk) | \ + (((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + (((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \ + (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#if defined(MPU_RLAR_PXN_Pos) + +/** \brief Region Limit Address Register with PXN value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ + (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \ + (((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ + (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#endif + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DMB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_LoadEx() +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/Drivers/CMSIS/Core/Include/pac_armv81.h b/Drivers/CMSIS/Core/Include/pac_armv81.h new file mode 100644 index 0000000..b802d6b --- /dev/null +++ b/Drivers/CMSIS/Core/Include/pac_armv81.h @@ -0,0 +1,206 @@ +/****************************************************************************** + * @file pac_armv81.h + * @brief CMSIS PAC key functions for Armv8.1-M PAC extension + * @version V1.0.0 + * @date 23. March 2022 + ******************************************************************************/ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef PAC_ARMV81_H +#define PAC_ARMV81_H + + +/* ################### PAC Key functions ########################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_PacKeyFunctions PAC Key functions + \brief Functions that access the PAC keys. + @{ + */ + +#if (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) + +/** + \brief read the PAC key used for privileged mode + \details Reads the PAC key stored in the PAC_KEY_P registers. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __get_PAC_KEY_P (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_p_0\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_p_1\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_p_2\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_p_3\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for privileged mode + \details writes the given PAC key to the PAC_KEY_P registers. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __set_PAC_KEY_P (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_p_0, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_p_1, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_p_2, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_p_3, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief read the PAC key used for unprivileged mode + \details Reads the PAC key stored in the PAC_KEY_U registers. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __get_PAC_KEY_U (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_u_0\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_u_1\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_u_2\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_u_3\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for unprivileged mode + \details writes the given PAC key to the PAC_KEY_U registers. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __set_PAC_KEY_U (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_u_0, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_u_1, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_u_2, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_u_3, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) + +/** + \brief read the PAC key used for privileged mode (non-secure) + \details Reads the PAC key stored in the non-secure PAC_KEY_P registers when in secure mode. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_get_PAC_KEY_P_NS (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_p_0_ns\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_p_1_ns\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_p_2_ns\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_p_3_ns\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for privileged mode (non-secure) + \details writes the given PAC key to the non-secure PAC_KEY_P registers when in secure mode. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_set_PAC_KEY_P_NS (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_p_0_ns, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_p_1_ns, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_p_2_ns, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_p_3_ns, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief read the PAC key used for unprivileged mode (non-secure) + \details Reads the PAC key stored in the non-secure PAC_KEY_U registers when in secure mode. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_get_PAC_KEY_U_NS (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_u_0_ns\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_u_1_ns\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_u_2_ns\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_u_3_ns\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for unprivileged mode (non-secure) + \details writes the given PAC key to the non-secure PAC_KEY_U registers when in secure mode. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_set_PAC_KEY_U_NS (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_u_0_ns, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_u_1_ns, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_u_2_ns, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_u_3_ns, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +#endif /* (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) */ + +#endif /* (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) */ + +/*@} end of CMSIS_Core_PacKeyFunctions */ + + +#endif /* PAC_ARMV81_H */ diff --git a/Drivers/CMSIS/Core/Include/pmu_armv8.h b/Drivers/CMSIS/Core/Include/pmu_armv8.h new file mode 100644 index 0000000..4cbc570 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/pmu_armv8.h @@ -0,0 +1,337 @@ +/****************************************************************************** + * @file pmu_armv8.h + * @brief CMSIS PMU API for Armv8.1-M PMU + * @version V1.0.1 + * @date 15. April 2020 + ******************************************************************************/ +/* + * Copyright (c) 2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_PMU_ARMV8_H +#define ARM_PMU_ARMV8_H + +/** + * \brief PMU Events + * \note See the Armv8.1-M Architecture Reference Manual for full details on these PMU events. + * */ + +#define ARM_PMU_SW_INCR 0x0000 /*!< Software update to the PMU_SWINC register, architecturally executed and condition code check pass */ +#define ARM_PMU_L1I_CACHE_REFILL 0x0001 /*!< L1 I-Cache refill */ +#define ARM_PMU_L1D_CACHE_REFILL 0x0003 /*!< L1 D-Cache refill */ +#define ARM_PMU_L1D_CACHE 0x0004 /*!< L1 D-Cache access */ +#define ARM_PMU_LD_RETIRED 0x0006 /*!< Memory-reading instruction architecturally executed and condition code check pass */ +#define ARM_PMU_ST_RETIRED 0x0007 /*!< Memory-writing instruction architecturally executed and condition code check pass */ +#define ARM_PMU_INST_RETIRED 0x0008 /*!< Instruction architecturally executed */ +#define ARM_PMU_EXC_TAKEN 0x0009 /*!< Exception entry */ +#define ARM_PMU_EXC_RETURN 0x000A /*!< Exception return instruction architecturally executed and the condition code check pass */ +#define ARM_PMU_PC_WRITE_RETIRED 0x000C /*!< Software change to the Program Counter (PC). Instruction is architecturally executed and condition code check pass */ +#define ARM_PMU_BR_IMMED_RETIRED 0x000D /*!< Immediate branch architecturally executed */ +#define ARM_PMU_BR_RETURN_RETIRED 0x000E /*!< Function return instruction architecturally executed and the condition code check pass */ +#define ARM_PMU_UNALIGNED_LDST_RETIRED 0x000F /*!< Unaligned memory memory-reading or memory-writing instruction architecturally executed and condition code check pass */ +#define ARM_PMU_BR_MIS_PRED 0x0010 /*!< Mispredicted or not predicted branch speculatively executed */ +#define ARM_PMU_CPU_CYCLES 0x0011 /*!< Cycle */ +#define ARM_PMU_BR_PRED 0x0012 /*!< Predictable branch speculatively executed */ +#define ARM_PMU_MEM_ACCESS 0x0013 /*!< Data memory access */ +#define ARM_PMU_L1I_CACHE 0x0014 /*!< Level 1 instruction cache access */ +#define ARM_PMU_L1D_CACHE_WB 0x0015 /*!< Level 1 data cache write-back */ +#define ARM_PMU_L2D_CACHE 0x0016 /*!< Level 2 data cache access */ +#define ARM_PMU_L2D_CACHE_REFILL 0x0017 /*!< Level 2 data cache refill */ +#define ARM_PMU_L2D_CACHE_WB 0x0018 /*!< Level 2 data cache write-back */ +#define ARM_PMU_BUS_ACCESS 0x0019 /*!< Bus access */ +#define ARM_PMU_MEMORY_ERROR 0x001A /*!< Local memory error */ +#define ARM_PMU_INST_SPEC 0x001B /*!< Instruction speculatively executed */ +#define ARM_PMU_BUS_CYCLES 0x001D /*!< Bus cycles */ +#define ARM_PMU_CHAIN 0x001E /*!< For an odd numbered counter, increment when an overflow occurs on the preceding even-numbered counter on the same PE */ +#define ARM_PMU_L1D_CACHE_ALLOCATE 0x001F /*!< Level 1 data cache allocation without refill */ +#define ARM_PMU_L2D_CACHE_ALLOCATE 0x0020 /*!< Level 2 data cache allocation without refill */ +#define ARM_PMU_BR_RETIRED 0x0021 /*!< Branch instruction architecturally executed */ +#define ARM_PMU_BR_MIS_PRED_RETIRED 0x0022 /*!< Mispredicted branch instruction architecturally executed */ +#define ARM_PMU_STALL_FRONTEND 0x0023 /*!< No operation issued because of the frontend */ +#define ARM_PMU_STALL_BACKEND 0x0024 /*!< No operation issued because of the backend */ +#define ARM_PMU_L2I_CACHE 0x0027 /*!< Level 2 instruction cache access */ +#define ARM_PMU_L2I_CACHE_REFILL 0x0028 /*!< Level 2 instruction cache refill */ +#define ARM_PMU_L3D_CACHE_ALLOCATE 0x0029 /*!< Level 3 data cache allocation without refill */ +#define ARM_PMU_L3D_CACHE_REFILL 0x002A /*!< Level 3 data cache refill */ +#define ARM_PMU_L3D_CACHE 0x002B /*!< Level 3 data cache access */ +#define ARM_PMU_L3D_CACHE_WB 0x002C /*!< Level 3 data cache write-back */ +#define ARM_PMU_LL_CACHE_RD 0x0036 /*!< Last level data cache read */ +#define ARM_PMU_LL_CACHE_MISS_RD 0x0037 /*!< Last level data cache read miss */ +#define ARM_PMU_L1D_CACHE_MISS_RD 0x0039 /*!< Level 1 data cache read miss */ +#define ARM_PMU_OP_COMPLETE 0x003A /*!< Operation retired */ +#define ARM_PMU_OP_SPEC 0x003B /*!< Operation speculatively executed */ +#define ARM_PMU_STALL 0x003C /*!< Stall cycle for instruction or operation not sent for execution */ +#define ARM_PMU_STALL_OP_BACKEND 0x003D /*!< Stall cycle for instruction or operation not sent for execution due to pipeline backend */ +#define ARM_PMU_STALL_OP_FRONTEND 0x003E /*!< Stall cycle for instruction or operation not sent for execution due to pipeline frontend */ +#define ARM_PMU_STALL_OP 0x003F /*!< Instruction or operation slots not occupied each cycle */ +#define ARM_PMU_L1D_CACHE_RD 0x0040 /*!< Level 1 data cache read */ +#define ARM_PMU_LE_RETIRED 0x0100 /*!< Loop end instruction executed */ +#define ARM_PMU_LE_SPEC 0x0101 /*!< Loop end instruction speculatively executed */ +#define ARM_PMU_BF_RETIRED 0x0104 /*!< Branch future instruction architecturally executed and condition code check pass */ +#define ARM_PMU_BF_SPEC 0x0105 /*!< Branch future instruction speculatively executed and condition code check pass */ +#define ARM_PMU_LE_CANCEL 0x0108 /*!< Loop end instruction not taken */ +#define ARM_PMU_BF_CANCEL 0x0109 /*!< Branch future instruction not taken */ +#define ARM_PMU_SE_CALL_S 0x0114 /*!< Call to secure function, resulting in Security state change */ +#define ARM_PMU_SE_CALL_NS 0x0115 /*!< Call to non-secure function, resulting in Security state change */ +#define ARM_PMU_DWT_CMPMATCH0 0x0118 /*!< DWT comparator 0 match */ +#define ARM_PMU_DWT_CMPMATCH1 0x0119 /*!< DWT comparator 1 match */ +#define ARM_PMU_DWT_CMPMATCH2 0x011A /*!< DWT comparator 2 match */ +#define ARM_PMU_DWT_CMPMATCH3 0x011B /*!< DWT comparator 3 match */ +#define ARM_PMU_MVE_INST_RETIRED 0x0200 /*!< MVE instruction architecturally executed */ +#define ARM_PMU_MVE_INST_SPEC 0x0201 /*!< MVE instruction speculatively executed */ +#define ARM_PMU_MVE_FP_RETIRED 0x0204 /*!< MVE floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_SPEC 0x0205 /*!< MVE floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_HP_RETIRED 0x0208 /*!< MVE half-precision floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_HP_SPEC 0x0209 /*!< MVE half-precision floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_SP_RETIRED 0x020C /*!< MVE single-precision floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_SP_SPEC 0x020D /*!< MVE single-precision floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_MAC_RETIRED 0x0214 /*!< MVE floating-point multiply or multiply-accumulate instruction architecturally executed */ +#define ARM_PMU_MVE_FP_MAC_SPEC 0x0215 /*!< MVE floating-point multiply or multiply-accumulate instruction speculatively executed */ +#define ARM_PMU_MVE_INT_RETIRED 0x0224 /*!< MVE integer instruction architecturally executed */ +#define ARM_PMU_MVE_INT_SPEC 0x0225 /*!< MVE integer instruction speculatively executed */ +#define ARM_PMU_MVE_INT_MAC_RETIRED 0x0228 /*!< MVE multiply or multiply-accumulate instruction architecturally executed */ +#define ARM_PMU_MVE_INT_MAC_SPEC 0x0229 /*!< MVE multiply or multiply-accumulate instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_RETIRED 0x0238 /*!< MVE load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_SPEC 0x0239 /*!< MVE load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_RETIRED 0x023C /*!< MVE load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_SPEC 0x023D /*!< MVE load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_RETIRED 0x0240 /*!< MVE store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_SPEC 0x0241 /*!< MVE store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_CONTIG_RETIRED 0x0244 /*!< MVE contiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_CONTIG_SPEC 0x0245 /*!< MVE contiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_CONTIG_RETIRED 0x0248 /*!< MVE contiguous load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_CONTIG_SPEC 0x0249 /*!< MVE contiguous load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_CONTIG_RETIRED 0x024C /*!< MVE contiguous store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_CONTIG_SPEC 0x024D /*!< MVE contiguous store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_NONCONTIG_RETIRED 0x0250 /*!< MVE non-contiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_NONCONTIG_SPEC 0x0251 /*!< MVE non-contiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_NONCONTIG_RETIRED 0x0254 /*!< MVE non-contiguous load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_NONCONTIG_SPEC 0x0255 /*!< MVE non-contiguous load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_NONCONTIG_RETIRED 0x0258 /*!< MVE non-contiguous store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_NONCONTIG_SPEC 0x0259 /*!< MVE non-contiguous store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_MULTI_RETIRED 0x025C /*!< MVE memory instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_LDST_MULTI_SPEC 0x025D /*!< MVE memory instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_LD_MULTI_RETIRED 0x0260 /*!< MVE memory load instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_LD_MULTI_SPEC 0x0261 /*!< MVE memory load instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_ST_MULTI_RETIRED 0x0261 /*!< MVE memory store instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_ST_MULTI_SPEC 0x0265 /*!< MVE memory store instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_RETIRED 0x028C /*!< MVE unaligned memory load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_SPEC 0x028D /*!< MVE unaligned memory load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_UNALIGNED_RETIRED 0x0290 /*!< MVE unaligned load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_UNALIGNED_SPEC 0x0291 /*!< MVE unaligned load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_UNALIGNED_RETIRED 0x0294 /*!< MVE unaligned store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_UNALIGNED_SPEC 0x0295 /*!< MVE unaligned store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_RETIRED 0x0298 /*!< MVE unaligned noncontiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_SPEC 0x0299 /*!< MVE unaligned noncontiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_RETIRED 0x02A0 /*!< MVE vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_SPEC 0x02A1 /*!< MVE vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_FP_RETIRED 0x02A4 /*!< MVE floating-point vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_FP_SPEC 0x02A5 /*!< MVE floating-point vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_INT_RETIRED 0x02A8 /*!< MVE integer vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_INT_SPEC 0x02A9 /*!< MVE integer vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_PRED 0x02B8 /*!< Cycles where one or more predicated beats architecturally executed */ +#define ARM_PMU_MVE_STALL 0x02CC /*!< Stall cycles caused by an MVE instruction */ +#define ARM_PMU_MVE_STALL_RESOURCE 0x02CD /*!< Stall cycles caused by an MVE instruction because of resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_MEM 0x02CE /*!< Stall cycles caused by an MVE instruction because of memory resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_FP 0x02CF /*!< Stall cycles caused by an MVE instruction because of floating-point resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_INT 0x02D0 /*!< Stall cycles caused by an MVE instruction because of integer resource conflicts */ +#define ARM_PMU_MVE_STALL_BREAK 0x02D3 /*!< Stall cycles caused by an MVE chain break */ +#define ARM_PMU_MVE_STALL_DEPENDENCY 0x02D4 /*!< Stall cycles caused by MVE register dependency */ +#define ARM_PMU_ITCM_ACCESS 0x4007 /*!< Instruction TCM access */ +#define ARM_PMU_DTCM_ACCESS 0x4008 /*!< Data TCM access */ +#define ARM_PMU_TRCEXTOUT0 0x4010 /*!< ETM external output 0 */ +#define ARM_PMU_TRCEXTOUT1 0x4011 /*!< ETM external output 1 */ +#define ARM_PMU_TRCEXTOUT2 0x4012 /*!< ETM external output 2 */ +#define ARM_PMU_TRCEXTOUT3 0x4013 /*!< ETM external output 3 */ +#define ARM_PMU_CTI_TRIGOUT4 0x4018 /*!< Cross-trigger Interface output trigger 4 */ +#define ARM_PMU_CTI_TRIGOUT5 0x4019 /*!< Cross-trigger Interface output trigger 5 */ +#define ARM_PMU_CTI_TRIGOUT6 0x401A /*!< Cross-trigger Interface output trigger 6 */ +#define ARM_PMU_CTI_TRIGOUT7 0x401B /*!< Cross-trigger Interface output trigger 7 */ + +/** \brief PMU Functions */ + +__STATIC_INLINE void ARM_PMU_Enable(void); +__STATIC_INLINE void ARM_PMU_Disable(void); + +__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type); + +__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void); +__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void); + +__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask); +__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask); + +__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void); +__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num); + +__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void); +__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask); + +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask); +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask); + +__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask); + +/** + \brief Enable the PMU +*/ +__STATIC_INLINE void ARM_PMU_Enable(void) +{ + PMU->CTRL |= PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Disable the PMU +*/ +__STATIC_INLINE void ARM_PMU_Disable(void) +{ + PMU->CTRL &= ~PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Set event to count for PMU eventer counter + \param [in] num Event counter (0-30) to configure + \param [in] type Event to count +*/ +__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type) +{ + PMU->EVTYPER[num] = type; +} + +/** + \brief Reset cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void) +{ + PMU->CTRL |= PMU_CTRL_CYCCNT_RESET_Msk; +} + +/** + \brief Reset all event counters +*/ +__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void) +{ + PMU->CTRL |= PMU_CTRL_EVENTCNT_RESET_Msk; +} + +/** + \brief Enable counters + \param [in] mask Counters to enable + \note Enables one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask) +{ + PMU->CNTENSET = mask; +} + +/** + \brief Disable counters + \param [in] mask Counters to enable + \note Disables one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask) +{ + PMU->CNTENCLR = mask; +} + +/** + \brief Read cycle counter + \return Cycle count +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void) +{ + return PMU->CCNTR; +} + +/** + \brief Read event counter + \param [in] num Event counter (0-30) to read + \return Event count +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num) +{ + return PMU_EVCNTR_CNT_Msk & PMU->EVCNTR[num]; +} + +/** + \brief Read counter overflow status + \return Counter overflow status bits for the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void) +{ + return PMU->OVSSET; +} + +/** + \brief Clear counter overflow status + \param [in] mask Counter overflow status bits to clear + \note Clears overflow status bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask) +{ + PMU->OVSCLR = mask; +} + +/** + \brief Enable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to set + \note Sets overflow interrupt request bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask) +{ + PMU->INTENSET = mask; +} + +/** + \brief Disable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to clear + \note Clears overflow interrupt request bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask) +{ + PMU->INTENCLR = mask; +} + +/** + \brief Software increment event counter + \param [in] mask Counters to increment + \note Software increment bits for one or more event counters (0-30) +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask) +{ + PMU->SWINC = mask; +} + +#endif diff --git a/Drivers/CMSIS/Core/Include/tz_context.h b/Drivers/CMSIS/Core/Include/tz_context.h new file mode 100644 index 0000000..d4c1474 --- /dev/null +++ b/Drivers/CMSIS/Core/Include/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c b/Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c new file mode 100644 index 0000000..cde9ff0 --- /dev/null +++ b/Drivers/CMSIS/Core/Template/ARMv8-M/main_s.c @@ -0,0 +1,58 @@ +/****************************************************************************** + * @file main_s.c + * @brief Code template for secure main function + * @version V1.1.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2013-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +/* Use CMSE intrinsics */ +#include + +#include "RTE_Components.h" +#include CMSIS_device_header + +/* TZ_START_NS: Start address of non-secure application */ +#ifndef TZ_START_NS +#define TZ_START_NS (0x200000U) +#endif + +/* typedef for non-secure callback functions */ +typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call)); + +/* Secure main() */ +int main(void) { + funcptr_void NonSecure_ResetHandler; + + /* Add user setup code for secure part here*/ + + /* Set non-secure main stack (MSP_NS) */ + __TZ_set_MSP_NS(*((uint32_t *)(TZ_START_NS))); + + /* Get non-secure reset handler */ + NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((TZ_START_NS) + 4U))); + + /* Start non-secure state software application */ + NonSecure_ResetHandler(); + + /* Non-secure software does not return, this code is not executed */ + while (1) { + __NOP(); + } +} diff --git a/Drivers/CMSIS/Core/Template/ARMv8-M/tz_context.c b/Drivers/CMSIS/Core/Template/ARMv8-M/tz_context.c new file mode 100644 index 0000000..298bbf7 --- /dev/null +++ b/Drivers/CMSIS/Core/Template/ARMv8-M/tz_context.c @@ -0,0 +1,200 @@ +/****************************************************************************** + * @file tz_context.c + * @brief Context Management for Armv8-M TrustZone - Sample implementation + * @version V1.1.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2016-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#include "RTE_Components.h" +#include CMSIS_device_header +#include "tz_context.h" + +/// Number of process slots (threads may call secure library code) +#ifndef TZ_PROCESS_STACK_SLOTS +#define TZ_PROCESS_STACK_SLOTS 8U +#endif + +/// Stack size of the secure library code +#ifndef TZ_PROCESS_STACK_SIZE +#define TZ_PROCESS_STACK_SIZE 256U +#endif + +typedef struct { + uint32_t sp_top; // stack space top + uint32_t sp_limit; // stack space limit + uint32_t sp; // current stack pointer +} stack_info_t; + +static stack_info_t ProcessStackInfo [TZ_PROCESS_STACK_SLOTS]; +static uint64_t ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U]; +static uint32_t ProcessStackFreeSlot = 0xFFFFFFFFU; + + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_InitContextSystem_S (void) { + uint32_t n; + + if (__get_IPSR() == 0U) { + return 0U; // Thread Mode + } + + for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) { + ProcessStackInfo[n].sp = 0U; + ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n]; + ProcessStackInfo[n].sp_top = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE; + *((uint32_t *)ProcessStackMemory[n]) = n + 1U; + } + *((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU; + + ProcessStackFreeSlot = 0U; + + // Default process stack pointer and stack limit + __set_PSPLIM((uint32_t)ProcessStackMemory); + __set_PSP ((uint32_t)ProcessStackMemory); + + // Privileged Thread Mode using PSP + __set_CONTROL(0x02U); + + return 1U; // Success +} + + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +__attribute__((cmse_nonsecure_entry)) +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) { + uint32_t slot; + + (void)module; // Ignore (fixed Stack size) + + if (__get_IPSR() == 0U) { + return 0U; // Thread Mode + } + + if (ProcessStackFreeSlot == 0xFFFFFFFFU) { + return 0U; // No slot available + } + + slot = ProcessStackFreeSlot; + ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]); + + ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top; + + return (slot + 1U); +} + + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) { + uint32_t slot; + + if (__get_IPSR() == 0U) { + return 0U; // Thread Mode + } + + if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { + return 0U; // Invalid ID + } + + slot = id - 1U; + + if (ProcessStackInfo[slot].sp == 0U) { + return 0U; // Inactive slot + } + ProcessStackInfo[slot].sp = 0U; + + *((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot; + ProcessStackFreeSlot = slot; + + return 1U; // Success +} + + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) { + uint32_t slot; + + if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { + return 0U; // Thread Mode or using Main Stack for threads + } + + if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { + return 0U; // Invalid ID + } + + slot = id - 1U; + + if (ProcessStackInfo[slot].sp == 0U) { + return 0U; // Inactive slot + } + + // Setup process stack pointer and stack limit + __set_PSPLIM(ProcessStackInfo[slot].sp_limit); + __set_PSP (ProcessStackInfo[slot].sp); + + return 1U; // Success +} + + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) { + uint32_t slot; + uint32_t sp; + + if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { + return 0U; // Thread Mode or using Main Stack for threads + } + + if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { + return 0U; // Invalid ID + } + + slot = id - 1U; + + if (ProcessStackInfo[slot].sp == 0U) { + return 0U; // Inactive slot + } + + sp = __get_PSP(); + if ((sp < ProcessStackInfo[slot].sp_limit) || + (sp > ProcessStackInfo[slot].sp_top)) { + return 0U; // SP out of range + } + ProcessStackInfo[slot].sp = sp; + + // Default process stack pointer and stack limit + __set_PSPLIM((uint32_t)ProcessStackMemory); + __set_PSP ((uint32_t)ProcessStackMemory); + + return 1U; // Success +} diff --git a/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h b/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h new file mode 100644 index 0000000..2bd73d8 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h @@ -0,0 +1,563 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.5 + * @date 05. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1)) + #define __ARM_ARCH_7A__ 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __forceinline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __wfi + +/** + \brief Wait For Event + */ +#define __WFE __wfe + +/** + \brief Send Event + */ +#define __SEV __sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + */ +#define __DMB() __dmb(0xF) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + +/** + \brief Rotate Right in unsigned value (32 bit) + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + +/* ########################### Core Function Access ########################### */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(void); */ + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + +/** + \brief Get FPSCR (Floating Point Status/Control) + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + +/** + \brief Set FPSCR (Floating Point Status/Control) + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +/** \brief Get CPSR (Current Program Status Register) + \return CPSR Register value + */ +__STATIC_INLINE uint32_t __get_CPSR(void) +{ + register uint32_t __regCPSR __ASM("cpsr"); + return(__regCPSR); +} + + +/** \brief Set CPSR (Current Program Status Register) + \param [in] cpsr CPSR value to set + */ +__STATIC_INLINE void __set_CPSR(uint32_t cpsr) +{ + register uint32_t __regCPSR __ASM("cpsr"); + __regCPSR = cpsr; +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_INLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_INLINE __ASM void __set_mode(uint32_t mode) +{ + MOV r1, lr + MSR CPSR_C, r0 + BX r1 +} + +/** \brief Get Stack Pointer + \return Stack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP(void) +{ + MOV r0, sp + BX lr +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP(uint32_t stack) +{ + MOV sp, r0 + BX lr +} + + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYSStack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP_usr(void) +{ + ARM + PRESERVE8 + + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV R0, SP + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack) +{ + ARM + PRESERVE8 + + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Get FPEXC (Floating Point Exception Control Register) + \return Floating Point Exception Control Register value + */ +__STATIC_INLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + return(__regfpexc); +#else + return(0); +#endif +} + +/** \brief Set FPEXC (Floating Point Exception Control Register) + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + __regfpexc = (fpexc); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0) +#define __get_CP64(cp, op1, Rt, CRm) \ + do { \ + uint32_t ltmp, htmp; \ + __ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ + (Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \ + } while(0) + +#define __set_CP64(cp, op1, Rt, CRm) \ + do { \ + const uint64_t tmp = (Rt); \ + const uint32_t ltmp = (uint32_t)(tmp); \ + const uint32_t htmp = (uint32_t)(tmp >> 32U); \ + __ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ + } while(0) + +#include "cmsis_cp15.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE __ASM void __FPU_Enable(void) +{ + ARM + + //Permit access to VFP/NEON, registers by modifying CPACR + MRC p15,0,R1,c1,c0,2 + ORR R1,R1,#0x00F00000 + MCR p15,0,R1,c1,c0,2 + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + ISB + + //Enable VFP/NEON + VMRS R1,FPEXC + ORR R1,R1,#0x40000000 + VMSR FPEXC,R1 + + //Initialise VFP/NEON registers to 0 + MOV R2,#0 + + //Initialise D16 registers to 0 + VMOV D0, R2,R2 + VMOV D1, R2,R2 + VMOV D2, R2,R2 + VMOV D3, R2,R2 + VMOV D4, R2,R2 + VMOV D5, R2,R2 + VMOV D6, R2,R2 + VMOV D7, R2,R2 + VMOV D8, R2,R2 + VMOV D9, R2,R2 + VMOV D10,R2,R2 + VMOV D11,R2,R2 + VMOV D12,R2,R2 + VMOV D13,R2,R2 + VMOV D14,R2,R2 + VMOV D15,R2,R2 + + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + //Initialise D32 registers to 0 + VMOV D16,R2,R2 + VMOV D17,R2,R2 + VMOV D18,R2,R2 + VMOV D19,R2,R2 + VMOV D20,R2,R2 + VMOV D21,R2,R2 + VMOV D22,R2,R2 + VMOV D23,R2,R2 + VMOV D24,R2,R2 + VMOV D25,R2,R2 + VMOV D26,R2,R2 + VMOV D27,R2,R2 + VMOV D28,R2,R2 + VMOV D29,R2,R2 + VMOV D30,R2,R2 + VMOV D31,R2,R2 + ENDIF + + //Initialise FPSCR to a known state + VMRS R1,FPSCR + LDR R2,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + AND R1,R1,R2 + VMSR FPSCR,R1 + + BX LR +} + +#endif /* __CMSIS_ARMCC_H */ diff --git a/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h b/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h new file mode 100644 index 0000000..b7d69c7 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h @@ -0,0 +1,614 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.2.1 + * @date 05. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_inline)) +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __builtin_arm_wfi + +/** + \brief Wait For Event + */ +#define __WFE __builtin_arm_wfe + +/** + \brief Send Event + */ +#define __SEV __builtin_arm_sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() __builtin_arm_dsb(0xF) + +/** + \brief Data Memory Barrier + */ +#define __DMB() __builtin_arm_dmb(0xF) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD8 __builtin_arm_qadd8 +#define __QSUB8 __builtin_arm_qsub8 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __SXTB16 __builtin_arm_sxtb16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSDX __builtin_arm_smlsdx +#define __USAT16 __builtin_arm_usat16 +#define __SSUB8 __builtin_arm_ssub8 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 + + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ + +/* ########################### Core Function Access ########################### */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#define __get_FPSCR __builtin_arm_get_fpscr + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#define __set_FPSCR __builtin_arm_set_fpscr + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ + __ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc", "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) +{ + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP(void) +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr(void) +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %0 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : : "memory" + ); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %0 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack) : "memory" + ); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#include "cmsis_cp15.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#if (defined(__ARM_NEON) && (__ARM_NEON == 1)) + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R1,FPSCR \n" + " LDR R2,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R1,R1,R2 \n" + " VMSR FPSCR,R1 " + : : : "cc", "r1", "r2" + ); +} + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h b/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h new file mode 100644 index 0000000..9c6cab7 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h @@ -0,0 +1,213 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.2 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include "cmsis_iccarm.h" + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef CMSIS_DEPRECATED + #warning No compiler specific solution for CMSIS_DEPRECATED. CMSIS_DEPRECATED is ignored. + #define CMSIS_DEPRECATED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __UNALIGNED_UINT32 + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h b/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h new file mode 100644 index 0000000..75e57b8 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h @@ -0,0 +1,514 @@ +/**************************************************************************//** + * @file cmsis_cp15.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.1 + * @date 07. Sep 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_CP15_H +#define __CMSIS_CP15_H + +/** \brief Get ACTLR + \return Auxiliary Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTLR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 1); + return(result); +} + +/** \brief Set ACTLR + \param [in] actlr Auxiliary Control value to set + */ +__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr) +{ + __set_CP(15, 0, actlr, 1, 0, 1); +} + +/** \brief Get CPACR + \return Coprocessor Access Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPACR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 2); + return result; +} + +/** \brief Set CPACR + \param [in] cpacr Coprocessor Access Control value to set + */ +__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr) +{ + __set_CP(15, 0, cpacr, 1, 0, 2); +} + +/** \brief Get DFSR + \return Data Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DFSR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 5, 0, 0); + return result; +} + +/** \brief Set DFSR + \param [in] dfsr Data Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr) +{ + __set_CP(15, 0, dfsr, 5, 0, 0); +} + +/** \brief Get IFSR + \return Instruction Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IFSR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 5, 0, 1); + return result; +} + +/** \brief Set IFSR + \param [in] ifsr Instruction Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr) +{ + __set_CP(15, 0, ifsr, 5, 0, 1); +} + +/** \brief Get ISR + \return Interrupt Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ISR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 1, 0); + return result; +} + +/** \brief Get CBAR + \return Configuration Base Address register value + */ +__STATIC_FORCEINLINE uint32_t __get_CBAR(void) +{ + uint32_t result; + __get_CP(15, 4, result, 15, 0, 0); + return result; +} + +/** \brief Get TTBR0 + + This function returns the value of the Translation Table Base Register 0. + + \return Translation Table Base Register 0 value + */ +__STATIC_FORCEINLINE uint32_t __get_TTBR0(void) +{ + uint32_t result; + __get_CP(15, 0, result, 2, 0, 0); + return result; +} + +/** \brief Set TTBR0 + + This function assigns the given value to the Translation Table Base Register 0. + + \param [in] ttbr0 Translation Table Base Register 0 value to set + */ +__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0) +{ + __set_CP(15, 0, ttbr0, 2, 0, 0); +} + +/** \brief Get DACR + + This function returns the value of the Domain Access Control Register. + + \return Domain Access Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DACR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 3, 0, 0); + return result; +} + +/** \brief Set DACR + + This function assigns the given value to the Domain Access Control Register. + + \param [in] dacr Domain Access Control Register value to set + */ +__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr) +{ + __set_CP(15, 0, dacr, 3, 0, 0); +} + +/** \brief Set SCTLR + + This function assigns the given value to the System Control Register. + + \param [in] sctlr System Control Register value to set + */ +__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr) +{ + __set_CP(15, 0, sctlr, 1, 0, 0); +} + +/** \brief Get SCTLR + \return System Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_SCTLR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 0); + return result; +} + +/** \brief Set ACTRL + \param [in] actrl Auxiliary Control Register value to set + */ +__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl) +{ + __set_CP(15, 0, actrl, 1, 0, 1); +} + +/** \brief Get ACTRL + \return Auxiliary Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTRL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 1); + return result; +} + +/** \brief Get MPIDR + + This function returns the value of the Multiprocessor Affinity Register. + + \return Multiprocessor Affinity Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MPIDR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 0, 0, 5); + return result; +} + +/** \brief Get VBAR + + This function returns the value of the Vector Base Address Register. + + \return Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_VBAR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 0, 0); + return result; +} + +/** \brief Set VBAR + + This function assigns the given value to the Vector Base Address Register. + + \param [in] vbar Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar) +{ + __set_CP(15, 0, vbar, 12, 0, 0); +} + +/** \brief Get MVBAR + + This function returns the value of the Monitor Vector Base Address Register. + + \return Monitor Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_MVBAR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 0, 1); + return result; +} + +/** \brief Set MVBAR + + This function assigns the given value to the Monitor Vector Base Address Register. + + \param [in] mvbar Monitor Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_MVBAR(uint32_t mvbar) +{ + __set_CP(15, 0, mvbar, 12, 0, 1); +} + +#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \ + defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \ + defined(DOXYGEN) + +/** \brief Set CNTFRQ + + This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \param [in] value CNTFRQ Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value) +{ + __set_CP(15, 0, value, 14, 0, 0); +} + +/** \brief Get CNTFRQ + + This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \return CNTFRQ Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 0 , 0); + return result; +} + +/** \brief Set CNTP_TVAL + + This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + + \param [in] value CNTP_TVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value) +{ + __set_CP(15, 0, value, 14, 2, 0); +} + +/** \brief Get CNTP_TVAL + + This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + + \return CNTP_TVAL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 2, 0); + return result; +} + +/** \brief Get CNTPCT + + This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT). + + \return CNTPCT Register value + */ +__STATIC_FORCEINLINE uint64_t __get_CNTPCT(void) +{ + uint64_t result; + __get_CP64(15, 0, result, 14); + return result; +} + +/** \brief Set CNTP_CVAL + + This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + + \param [in] value CNTP_CVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value) +{ + __set_CP64(15, 2, value, 14); +} + +/** \brief Get CNTP_CVAL + + This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + + \return CNTP_CVAL Register value + */ +__STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void) +{ + uint64_t result; + __get_CP64(15, 2, result, 14); + return result; +} + +/** \brief Set CNTP_CTL + + This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + + \param [in] value CNTP_CTL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value) +{ + __set_CP(15, 0, value, 14, 2, 1); +} + +/** \brief Get CNTP_CTL register + \return CNTP_CTL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 2, 1); + return result; +} + +#endif + +/** \brief Set TLBIALL + + TLB Invalidate All + */ +__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value) +{ + __set_CP(15, 0, value, 8, 7, 0); +} + +/** \brief Set BPIALL. + + Branch Predictor Invalidate All + */ +__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value) +{ + __set_CP(15, 0, value, 7, 5, 6); +} + +/** \brief Set ICIALLU + + Instruction Cache Invalidate All + */ +__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value) +{ + __set_CP(15, 0, value, 7, 5, 0); +} + +/** \brief Set DCCMVAC + + Data cache clean + */ +__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 10, 1); +} + +/** \brief Set DCIMVAC + + Data cache invalidate + */ +__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 6, 1); +} + +/** \brief Set DCCIMVAC + + Data cache clean and invalidate + */ +__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 14, 1); +} + +/** \brief Set CSSELR + */ +__STATIC_FORCEINLINE void __set_CSSELR(uint32_t value) +{ +// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory"); + __set_CP(15, 2, value, 0, 0, 0); +} + +/** \brief Get CSSELR + \return CSSELR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CSSELR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 2, result, 0, 0, 0); + return result; +} + +/** \brief Set CCSIDR + \deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead. + */ +CMSIS_DEPRECATED +__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value) +{ + __set_CSSELR(value); +} + +/** \brief Get CCSIDR + \return CCSIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 0); + return result; +} + +/** \brief Get CLIDR + \return CLIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CLIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 1); + return result; +} + +/** \brief Set DCISW + */ +__STATIC_FORCEINLINE void __set_DCISW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 6, 2); +} + +/** \brief Set DCCSW + */ +__STATIC_FORCEINLINE void __set_DCCSW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 10, 2); +} + +/** \brief Set DCCISW + */ +__STATIC_FORCEINLINE void __set_DCCISW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 14, 2); +} + +#endif diff --git a/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h b/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h new file mode 100644 index 0000000..7f153d4 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h @@ -0,0 +1,917 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.3.2 + * @date 24. March 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_inline)) +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + +/** + \brief Wait For Event + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + +/** + \brief Send Event + */ +#define __SEV() __ASM volatile ("sev") + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : "=r" (result) : "r" (value) ); + return result; +#endif +} + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + __ASM ("rev16 %0, %1" : "=r" (result) : "r" (value)); + return result; +} + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return result; +#endif +} + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return result; +} + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +/* ########################### Core Function Access ########################### */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #if __has_builtin(__builtin_arm_get_fpscr) + // Re-enable using built-in when GCC has been fixed + // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); + #else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); + #endif + #else + return(0U); + #endif +} + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #if __has_builtin(__builtin_arm_set_fpscr) + // Re-enable using built-in when GCC has been fixed + // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); + #else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); + #endif + #else + (void)fpscr; + #endif +} + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ + __ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "cc", "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) +{ + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP(void) +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr(void) +{ + uint32_t cpsr = __get_CPSR(); + uint32_t result; + __ASM volatile( + "CPS #0x1F \n" + "MOV %0, sp " : "=r"(result) : : "memory" + ); + __set_CPSR(cpsr); + __ISB(); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr = __get_CPSR(); + __ASM volatile( + "CPS #0x1F \n" + "MOV sp, %0 " : : "r" (topOfProcStack) : "memory" + ); + __set_CPSR(cpsr); + __ISB(); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#include "cmsis_cp15.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#if (defined(__ARM_NEON) && (__ARM_NEON == 1)) + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R1,FPSCR \n" + " LDR R2,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R1,R1,R2 \n" + " VMSR FPSCR,R1 " + : : : "cc", "r1", "r2" + ); +} + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h b/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h new file mode 100644 index 0000000..5b345c6 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h @@ -0,0 +1,573 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 15. May 2019 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// Copyright (c) 2018-2019 Arm Limited +// +// SPDX-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. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#pragma language=extended + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_7A__ +/* Macro already defined */ +#else + #if defined(__ARM7A__) + #define __ARM_ARCH_7A__ 1 + #endif +#endif + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint16_t __iar_uint16_read(void const *ptr) + { + return *(__packed uint16_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) + { + *(__packed uint16_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint32_t __iar_uint32_read(void const *ptr) + { + return *(__packed uint32_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) + { + *(__packed uint32_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#if 0 +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma language=save + #pragma language=extended + __packed struct __iar_u32 { uint32_t v; }; + #pragma language=restore + #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __enable_irq __iar_builtin_enable_interrupt + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + #if __FPU_PRESENT + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #else + #define __get_FPSCR() ( 0 ) + #endif + + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE)) + + #define __get_CPSR() (__arm_rsr("CPSR")) + #define __get_mode() (__get_CPSR() & 0x1FU) + + #define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE))) + #define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE))) + + + #define __get_FPEXC() (__arm_rsr("FPEXC")) + #define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE)) + + #define __get_CP(cp, op1, RT, CRn, CRm, op2) \ + ((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2)) + + #define __set_CP(cp, op1, RT, CRn, CRm, op2) \ + (__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT))) + + #define __get_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) + + #define __set_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + + #include "cmsis_cp15.h" + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #define __SSAT __iar_builtin_SSAT + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #define __USAT __iar_builtin_USAT + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if !__FPU_PRESENT + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if !__FPU_PRESENT + #define __get_FPSCR() (0) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + __IAR_FT void __set_mode(uint32_t mode) + { + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); + } + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + __IAR_FT uint32_t __get_FPEXC(void) + { + #if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); + #else + return(0); + #endif + } + + __IAR_FT void __set_FPEXC(uint32_t fpexc) + { + #if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); + #endif + } + + + #define __get_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) + #define __set_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) + #define __get_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) + #define __set_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + + #include "cmsis_cp15.h" + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + + +__IAR_FT uint32_t __get_SP_usr(void) +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" + ); + return result; +} + +__IAR_FT void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" + ); +} + +#define __get_mode() (__get_CPSR() & 0x1FU) + +__STATIC_INLINE +void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#ifdef __ARM_ADVANCED_SIMD__ + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R1,FPSCR \n" + " MOV32 R2,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R1,R1,R2 \n" + " VMSR FPSCR,R1 \n" + : : : "cc", "r1", "r2" + ); +} + + + +#undef __IAR_FT +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/Drivers/CMSIS/Core_A/Include/core_ca.h b/Drivers/CMSIS/Core_A/Include/core_ca.h new file mode 100644 index 0000000..15ada25 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/core_ca.h @@ -0,0 +1,2614 @@ +/**************************************************************************//** + * @file core_ca.h + * @brief CMSIS Cortex-A Core Peripheral Access Layer Header File + * @version V1.0.3 + * @date 28. January 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CA_H_GENERIC +#define __CORE_CA_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ + +/* CMSIS CA definitions */ +#define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS-Core(A) main version */ +#define __CA_CMSIS_VERSION_SUB (1U) /*!< \brief [15:0] CMSIS-Core(A) sub version */ +#define __CA_CMSIS_VERSION ((__CA_CMSIS_VERSION_MAIN << 16U) | \ + __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS-Core(A) version number */ + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CA_H_DEPENDANT +#define __CORE_CA_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + + /* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CA_REV + #define __CA_REV 0x0000U + #warning "__CA_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __GIC_PRESENT + #define __GIC_PRESENT 1U + #warning "__GIC_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __TIM_PRESENT + #define __TIM_PRESENT 1U + #warning "__TIM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __L2C_PRESENT + #define __L2C_PRESENT 0U + #warning "__L2C_PRESENT not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< \brief Defines 'read only' permissions */ +#else + #define __I volatile const /*!< \brief Defines 'read only' permissions */ +#endif +#define __O volatile /*!< \brief Defines 'write only' permissions */ +#define __IO volatile /*!< \brief Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*!< \brief Defines 'read only' structure member permissions */ +#define __OM volatile /*!< \brief Defines 'write only' structure member permissions */ +#define __IOM volatile /*!< \brief Defines 'read / write' structure member permissions */ +#define RESERVED(N, T) T RESERVED##N; // placeholder struct members used for "reserved" areas + + /******************************************************************************* + * Register Abstraction + Core Register contain: + - CPSR + - CP15 Registers + - L2C-310 Cache Controller + - Generic Interrupt Controller Distributor + - Generic Interrupt Controller Interface + ******************************************************************************/ + +/* Core Register CPSR */ +typedef union +{ + struct + { + uint32_t M:5; /*!< \brief bit: 0.. 4 Mode field */ + uint32_t T:1; /*!< \brief bit: 5 Thumb execution state bit */ + uint32_t F:1; /*!< \brief bit: 6 FIQ mask bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ mask bit */ + uint32_t A:1; /*!< \brief bit: 8 Asynchronous abort mask bit */ + uint32_t E:1; /*!< \brief bit: 9 Endianness execution state bit */ + uint32_t IT1:6; /*!< \brief bit: 10..15 If-Then execution state bits 2-7 */ + uint32_t GE:4; /*!< \brief bit: 16..19 Greater than or Equal flags */ + RESERVED(0:4, uint32_t) + uint32_t J:1; /*!< \brief bit: 24 Jazelle bit */ + uint32_t IT0:2; /*!< \brief bit: 25..26 If-Then execution state bits 0-1 */ + uint32_t Q:1; /*!< \brief bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< \brief bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< \brief bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< \brief bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< \brief bit: 31 Negative condition code flag */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPSR_Type; + + + +/* CPSR Register Definitions */ +#define CPSR_N_Pos 31U /*!< \brief CPSR: N Position */ +#define CPSR_N_Msk (1UL << CPSR_N_Pos) /*!< \brief CPSR: N Mask */ + +#define CPSR_Z_Pos 30U /*!< \brief CPSR: Z Position */ +#define CPSR_Z_Msk (1UL << CPSR_Z_Pos) /*!< \brief CPSR: Z Mask */ + +#define CPSR_C_Pos 29U /*!< \brief CPSR: C Position */ +#define CPSR_C_Msk (1UL << CPSR_C_Pos) /*!< \brief CPSR: C Mask */ + +#define CPSR_V_Pos 28U /*!< \brief CPSR: V Position */ +#define CPSR_V_Msk (1UL << CPSR_V_Pos) /*!< \brief CPSR: V Mask */ + +#define CPSR_Q_Pos 27U /*!< \brief CPSR: Q Position */ +#define CPSR_Q_Msk (1UL << CPSR_Q_Pos) /*!< \brief CPSR: Q Mask */ + +#define CPSR_IT0_Pos 25U /*!< \brief CPSR: IT0 Position */ +#define CPSR_IT0_Msk (3UL << CPSR_IT0_Pos) /*!< \brief CPSR: IT0 Mask */ + +#define CPSR_J_Pos 24U /*!< \brief CPSR: J Position */ +#define CPSR_J_Msk (1UL << CPSR_J_Pos) /*!< \brief CPSR: J Mask */ + +#define CPSR_GE_Pos 16U /*!< \brief CPSR: GE Position */ +#define CPSR_GE_Msk (0xFUL << CPSR_GE_Pos) /*!< \brief CPSR: GE Mask */ + +#define CPSR_IT1_Pos 10U /*!< \brief CPSR: IT1 Position */ +#define CPSR_IT1_Msk (0x3FUL << CPSR_IT1_Pos) /*!< \brief CPSR: IT1 Mask */ + +#define CPSR_E_Pos 9U /*!< \brief CPSR: E Position */ +#define CPSR_E_Msk (1UL << CPSR_E_Pos) /*!< \brief CPSR: E Mask */ + +#define CPSR_A_Pos 8U /*!< \brief CPSR: A Position */ +#define CPSR_A_Msk (1UL << CPSR_A_Pos) /*!< \brief CPSR: A Mask */ + +#define CPSR_I_Pos 7U /*!< \brief CPSR: I Position */ +#define CPSR_I_Msk (1UL << CPSR_I_Pos) /*!< \brief CPSR: I Mask */ + +#define CPSR_F_Pos 6U /*!< \brief CPSR: F Position */ +#define CPSR_F_Msk (1UL << CPSR_F_Pos) /*!< \brief CPSR: F Mask */ + +#define CPSR_T_Pos 5U /*!< \brief CPSR: T Position */ +#define CPSR_T_Msk (1UL << CPSR_T_Pos) /*!< \brief CPSR: T Mask */ + +#define CPSR_M_Pos 0U /*!< \brief CPSR: M Position */ +#define CPSR_M_Msk (0x1FUL << CPSR_M_Pos) /*!< \brief CPSR: M Mask */ + +#define CPSR_M_USR 0x10U /*!< \brief CPSR: M User mode (PL0) */ +#define CPSR_M_FIQ 0x11U /*!< \brief CPSR: M Fast Interrupt mode (PL1) */ +#define CPSR_M_IRQ 0x12U /*!< \brief CPSR: M Interrupt mode (PL1) */ +#define CPSR_M_SVC 0x13U /*!< \brief CPSR: M Supervisor mode (PL1) */ +#define CPSR_M_MON 0x16U /*!< \brief CPSR: M Monitor mode (PL1) */ +#define CPSR_M_ABT 0x17U /*!< \brief CPSR: M Abort mode (PL1) */ +#define CPSR_M_HYP 0x1AU /*!< \brief CPSR: M Hypervisor mode (PL2) */ +#define CPSR_M_UND 0x1BU /*!< \brief CPSR: M Undefined mode (PL1) */ +#define CPSR_M_SYS 0x1FU /*!< \brief CPSR: M System mode (PL1) */ + +/* CP15 Register SCTLR */ +typedef union +{ + struct + { + uint32_t M:1; /*!< \brief bit: 0 MMU enable */ + uint32_t A:1; /*!< \brief bit: 1 Alignment check enable */ + uint32_t C:1; /*!< \brief bit: 2 Cache enable */ + RESERVED(0:2, uint32_t) + uint32_t CP15BEN:1; /*!< \brief bit: 5 CP15 barrier enable */ + RESERVED(1:1, uint32_t) + uint32_t B:1; /*!< \brief bit: 7 Endianness model */ + RESERVED(2:2, uint32_t) + uint32_t SW:1; /*!< \brief bit: 10 SWP and SWPB enable */ + uint32_t Z:1; /*!< \brief bit: 11 Branch prediction enable */ + uint32_t I:1; /*!< \brief bit: 12 Instruction cache enable */ + uint32_t V:1; /*!< \brief bit: 13 Vectors bit */ + uint32_t RR:1; /*!< \brief bit: 14 Round Robin select */ + RESERVED(3:2, uint32_t) + uint32_t HA:1; /*!< \brief bit: 17 Hardware Access flag enable */ + RESERVED(4:1, uint32_t) + uint32_t WXN:1; /*!< \brief bit: 19 Write permission implies XN */ + uint32_t UWXN:1; /*!< \brief bit: 20 Unprivileged write permission implies PL1 XN */ + uint32_t FI:1; /*!< \brief bit: 21 Fast interrupts configuration enable */ + uint32_t U:1; /*!< \brief bit: 22 Alignment model */ + RESERVED(5:1, uint32_t) + uint32_t VE:1; /*!< \brief bit: 24 Interrupt Vectors Enable */ + uint32_t EE:1; /*!< \brief bit: 25 Exception Endianness */ + RESERVED(6:1, uint32_t) + uint32_t NMFI:1; /*!< \brief bit: 27 Non-maskable FIQ (NMFI) support */ + uint32_t TRE:1; /*!< \brief bit: 28 TEX remap enable. */ + uint32_t AFE:1; /*!< \brief bit: 29 Access flag enable */ + uint32_t TE:1; /*!< \brief bit: 30 Thumb Exception enable */ + RESERVED(7:1, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} SCTLR_Type; + +#define SCTLR_TE_Pos 30U /*!< \brief SCTLR: TE Position */ +#define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< \brief SCTLR: TE Mask */ + +#define SCTLR_AFE_Pos 29U /*!< \brief SCTLR: AFE Position */ +#define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< \brief SCTLR: AFE Mask */ + +#define SCTLR_TRE_Pos 28U /*!< \brief SCTLR: TRE Position */ +#define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< \brief SCTLR: TRE Mask */ + +#define SCTLR_NMFI_Pos 27U /*!< \brief SCTLR: NMFI Position */ +#define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< \brief SCTLR: NMFI Mask */ + +#define SCTLR_EE_Pos 25U /*!< \brief SCTLR: EE Position */ +#define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< \brief SCTLR: EE Mask */ + +#define SCTLR_VE_Pos 24U /*!< \brief SCTLR: VE Position */ +#define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< \brief SCTLR: VE Mask */ + +#define SCTLR_U_Pos 22U /*!< \brief SCTLR: U Position */ +#define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< \brief SCTLR: U Mask */ + +#define SCTLR_FI_Pos 21U /*!< \brief SCTLR: FI Position */ +#define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< \brief SCTLR: FI Mask */ + +#define SCTLR_UWXN_Pos 20U /*!< \brief SCTLR: UWXN Position */ +#define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< \brief SCTLR: UWXN Mask */ + +#define SCTLR_WXN_Pos 19U /*!< \brief SCTLR: WXN Position */ +#define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< \brief SCTLR: WXN Mask */ + +#define SCTLR_HA_Pos 17U /*!< \brief SCTLR: HA Position */ +#define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< \brief SCTLR: HA Mask */ + +#define SCTLR_RR_Pos 14U /*!< \brief SCTLR: RR Position */ +#define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< \brief SCTLR: RR Mask */ + +#define SCTLR_V_Pos 13U /*!< \brief SCTLR: V Position */ +#define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< \brief SCTLR: V Mask */ + +#define SCTLR_I_Pos 12U /*!< \brief SCTLR: I Position */ +#define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< \brief SCTLR: I Mask */ + +#define SCTLR_Z_Pos 11U /*!< \brief SCTLR: Z Position */ +#define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< \brief SCTLR: Z Mask */ + +#define SCTLR_SW_Pos 10U /*!< \brief SCTLR: SW Position */ +#define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< \brief SCTLR: SW Mask */ + +#define SCTLR_B_Pos 7U /*!< \brief SCTLR: B Position */ +#define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< \brief SCTLR: B Mask */ + +#define SCTLR_CP15BEN_Pos 5U /*!< \brief SCTLR: CP15BEN Position */ +#define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< \brief SCTLR: CP15BEN Mask */ + +#define SCTLR_C_Pos 2U /*!< \brief SCTLR: C Position */ +#define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< \brief SCTLR: C Mask */ + +#define SCTLR_A_Pos 1U /*!< \brief SCTLR: A Position */ +#define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< \brief SCTLR: A Mask */ + +#define SCTLR_M_Pos 0U /*!< \brief SCTLR: M Position */ +#define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< \brief SCTLR: M Mask */ + +/* CP15 Register ACTLR */ +typedef union +{ +#if __CORTEX_A == 5 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A5 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:5, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + RESERVED(1:2, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t DWBST:1; /*!< \brief bit: 11 AXI data write bursts to Normal memory */ + uint32_t RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t BP:2; /*!< \brief bit:16..15 Branch prediction policy */ + uint32_t RSDIS:1; /*!< \brief bit: 17 Disable return stack operation */ + uint32_t BTDIS:1; /*!< \brief bit: 18 Disable indirect Branch Target Address Cache (BTAC) */ + RESERVED(3:9, uint32_t) + uint32_t DBDI:1; /*!< \brief bit: 28 Disable branch dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 7 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A7 */ + struct + { + RESERVED(0:6, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + RESERVED(1:3, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t L2RADIS:1; /*!< \brief bit: 11 L2 Data Cache read-allocate mode disable */ + uint32_t L1RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t DDVM:1; /*!< \brief bit: 15 Disable Distributed Virtual Memory (DVM) transactions */ + RESERVED(3:12, uint32_t) + uint32_t DDI:1; /*!< \brief bit: 28 Disable dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 9 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A9 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:1, uint32_t) + uint32_t L1PE:1; /*!< \brief bit: 2 Dside prefetch */ + uint32_t WFLZM:1; /*!< \brief bit: 3 Cache and TLB maintenance broadcast */ + RESERVED(1:2, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + uint32_t AOW:1; /*!< \brief bit: 8 Enable allocation in one cache way only */ + uint32_t PARITY:1; /*!< \brief bit: 9 Support for parity checking, if implemented */ + RESERVED(7:22, uint32_t) + } b; +#endif + uint32_t w; /*!< \brief Type used for word access */ +} ACTLR_Type; + +#define ACTLR_DDI_Pos 28U /*!< \brief ACTLR: DDI Position */ +#define ACTLR_DDI_Msk (1UL << ACTLR_DDI_Pos) /*!< \brief ACTLR: DDI Mask */ + +#define ACTLR_DBDI_Pos 28U /*!< \brief ACTLR: DBDI Position */ +#define ACTLR_DBDI_Msk (1UL << ACTLR_DBDI_Pos) /*!< \brief ACTLR: DBDI Mask */ + +#define ACTLR_BTDIS_Pos 18U /*!< \brief ACTLR: BTDIS Position */ +#define ACTLR_BTDIS_Msk (1UL << ACTLR_BTDIS_Pos) /*!< \brief ACTLR: BTDIS Mask */ + +#define ACTLR_RSDIS_Pos 17U /*!< \brief ACTLR: RSDIS Position */ +#define ACTLR_RSDIS_Msk (1UL << ACTLR_RSDIS_Pos) /*!< \brief ACTLR: RSDIS Mask */ + +#define ACTLR_BP_Pos 15U /*!< \brief ACTLR: BP Position */ +#define ACTLR_BP_Msk (3UL << ACTLR_BP_Pos) /*!< \brief ACTLR: BP Mask */ + +#define ACTLR_DDVM_Pos 15U /*!< \brief ACTLR: DDVM Position */ +#define ACTLR_DDVM_Msk (1UL << ACTLR_DDVM_Pos) /*!< \brief ACTLR: DDVM Mask */ + +#define ACTLR_L1PCTL_Pos 13U /*!< \brief ACTLR: L1PCTL Position */ +#define ACTLR_L1PCTL_Msk (3UL << ACTLR_L1PCTL_Pos) /*!< \brief ACTLR: L1PCTL Mask */ + +#define ACTLR_RADIS_Pos 12U /*!< \brief ACTLR: RADIS Position */ +#define ACTLR_RADIS_Msk (1UL << ACTLR_RADIS_Pos) /*!< \brief ACTLR: RADIS Mask */ + +#define ACTLR_L1RADIS_Pos 12U /*!< \brief ACTLR: L1RADIS Position */ +#define ACTLR_L1RADIS_Msk (1UL << ACTLR_L1RADIS_Pos) /*!< \brief ACTLR: L1RADIS Mask */ + +#define ACTLR_DWBST_Pos 11U /*!< \brief ACTLR: DWBST Position */ +#define ACTLR_DWBST_Msk (1UL << ACTLR_DWBST_Pos) /*!< \brief ACTLR: DWBST Mask */ + +#define ACTLR_L2RADIS_Pos 11U /*!< \brief ACTLR: L2RADIS Position */ +#define ACTLR_L2RADIS_Msk (1UL << ACTLR_L2RADIS_Pos) /*!< \brief ACTLR: L2RADIS Mask */ + +#define ACTLR_DODMBS_Pos 10U /*!< \brief ACTLR: DODMBS Position */ +#define ACTLR_DODMBS_Msk (1UL << ACTLR_DODMBS_Pos) /*!< \brief ACTLR: DODMBS Mask */ + +#define ACTLR_PARITY_Pos 9U /*!< \brief ACTLR: PARITY Position */ +#define ACTLR_PARITY_Msk (1UL << ACTLR_PARITY_Pos) /*!< \brief ACTLR: PARITY Mask */ + +#define ACTLR_AOW_Pos 8U /*!< \brief ACTLR: AOW Position */ +#define ACTLR_AOW_Msk (1UL << ACTLR_AOW_Pos) /*!< \brief ACTLR: AOW Mask */ + +#define ACTLR_EXCL_Pos 7U /*!< \brief ACTLR: EXCL Position */ +#define ACTLR_EXCL_Msk (1UL << ACTLR_EXCL_Pos) /*!< \brief ACTLR: EXCL Mask */ + +#define ACTLR_SMP_Pos 6U /*!< \brief ACTLR: SMP Position */ +#define ACTLR_SMP_Msk (1UL << ACTLR_SMP_Pos) /*!< \brief ACTLR: SMP Mask */ + +#define ACTLR_WFLZM_Pos 3U /*!< \brief ACTLR: WFLZM Position */ +#define ACTLR_WFLZM_Msk (1UL << ACTLR_WFLZM_Pos) /*!< \brief ACTLR: WFLZM Mask */ + +#define ACTLR_L1PE_Pos 2U /*!< \brief ACTLR: L1PE Position */ +#define ACTLR_L1PE_Msk (1UL << ACTLR_L1PE_Pos) /*!< \brief ACTLR: L1PE Mask */ + +#define ACTLR_FW_Pos 0U /*!< \brief ACTLR: FW Position */ +#define ACTLR_FW_Msk (1UL << ACTLR_FW_Pos) /*!< \brief ACTLR: FW Mask */ + +/* CP15 Register CPACR */ +typedef union +{ + struct + { + uint32_t CP0:2; /*!< \brief bit: 0..1 Access rights for coprocessor 0 */ + uint32_t CP1:2; /*!< \brief bit: 2..3 Access rights for coprocessor 1 */ + uint32_t CP2:2; /*!< \brief bit: 4..5 Access rights for coprocessor 2 */ + uint32_t CP3:2; /*!< \brief bit: 6..7 Access rights for coprocessor 3 */ + uint32_t CP4:2; /*!< \brief bit: 8..9 Access rights for coprocessor 4 */ + uint32_t CP5:2; /*!< \brief bit:10..11 Access rights for coprocessor 5 */ + uint32_t CP6:2; /*!< \brief bit:12..13 Access rights for coprocessor 6 */ + uint32_t CP7:2; /*!< \brief bit:14..15 Access rights for coprocessor 7 */ + uint32_t CP8:2; /*!< \brief bit:16..17 Access rights for coprocessor 8 */ + uint32_t CP9:2; /*!< \brief bit:18..19 Access rights for coprocessor 9 */ + uint32_t CP10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ + uint32_t CP11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ + uint32_t CP12:2; /*!< \brief bit:24..25 Access rights for coprocessor 11 */ + uint32_t CP13:2; /*!< \brief bit:26..27 Access rights for coprocessor 11 */ + uint32_t TRCDIS:1; /*!< \brief bit: 28 Disable CP14 access to trace registers */ + RESERVED(0:1, uint32_t) + uint32_t D32DIS:1; /*!< \brief bit: 30 Disable use of registers D16-D31 of the VFP register file */ + uint32_t ASEDIS:1; /*!< \brief bit: 31 Disable Advanced SIMD Functionality */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPACR_Type; + +#define CPACR_ASEDIS_Pos 31U /*!< \brief CPACR: ASEDIS Position */ +#define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< \brief CPACR: ASEDIS Mask */ + +#define CPACR_D32DIS_Pos 30U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_TRCDIS_Pos 28U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_TRCDIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_CP_Pos_(n) (n*2U) /*!< \brief CPACR: CPn Position */ +#define CPACR_CP_Msk_(n) (3UL << CPACR_CP_Pos_(n)) /*!< \brief CPACR: CPn Mask */ + +#define CPACR_CP_NA 0U /*!< \brief CPACR CPn field: Access denied. */ +#define CPACR_CP_PL1 1U /*!< \brief CPACR CPn field: Accessible from PL1 only. */ +#define CPACR_CP_FA 3U /*!< \brief CPACR CPn field: Full access. */ + +/* CP15 Register DFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + uint32_t Domain:4; /*!< \brief bit: 4.. 7 Fault on which domain */ + RESERVED(0:1, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(1:18, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:5; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:1, uint32_t) + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(2:18, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ + uint32_t w; /*!< \brief Type used for word access */ +} DFSR_Type; + +#define DFSR_CM_Pos 13U /*!< \brief DFSR: CM Position */ +#define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< \brief DFSR: CM Mask */ + +#define DFSR_Ext_Pos 12U /*!< \brief DFSR: Ext Position */ +#define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< \brief DFSR: Ext Mask */ + +#define DFSR_WnR_Pos 11U /*!< \brief DFSR: WnR Position */ +#define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< \brief DFSR: WnR Mask */ + +#define DFSR_FS1_Pos 10U /*!< \brief DFSR: FS1 Position */ +#define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< \brief DFSR: FS1 Mask */ + +#define DFSR_LPAE_Pos 9U /*!< \brief DFSR: LPAE Position */ +#define DFSR_LPAE_Msk (1UL << DFSR_LPAE_Pos) /*!< \brief DFSR: LPAE Mask */ + +#define DFSR_Domain_Pos 4U /*!< \brief DFSR: Domain Position */ +#define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< \brief DFSR: Domain Mask */ + +#define DFSR_FS0_Pos 0U /*!< \brief DFSR: FS0 Position */ +#define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< \brief DFSR: FS0 Mask */ + +#define DFSR_STATUS_Pos 0U /*!< \brief DFSR: STATUS Position */ +#define DFSR_STATUS_Msk (0x3FUL << DFSR_STATUS_Pos) /*!< \brief DFSR: STATUS Mask */ + +/* CP15 Register IFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + RESERVED(0:5, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + RESERVED(1:1, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:6; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:2, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ + uint32_t w; /*!< \brief Type used for word access */ +} IFSR_Type; + +#define IFSR_ExT_Pos 12U /*!< \brief IFSR: ExT Position */ +#define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< \brief IFSR: ExT Mask */ + +#define IFSR_FS1_Pos 10U /*!< \brief IFSR: FS1 Position */ +#define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< \brief IFSR: FS1 Mask */ + +#define IFSR_LPAE_Pos 9U /*!< \brief IFSR: LPAE Position */ +#define IFSR_LPAE_Msk (0x1UL << IFSR_LPAE_Pos) /*!< \brief IFSR: LPAE Mask */ + +#define IFSR_FS0_Pos 0U /*!< \brief IFSR: FS0 Position */ +#define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< \brief IFSR: FS0 Mask */ + +#define IFSR_STATUS_Pos 0U /*!< \brief IFSR: STATUS Position */ +#define IFSR_STATUS_Msk (0x3FUL << IFSR_STATUS_Pos) /*!< \brief IFSR: STATUS Mask */ + +/* CP15 Register ISR */ +typedef union +{ + struct + { + RESERVED(0:6, uint32_t) + uint32_t F:1; /*!< \brief bit: 6 FIQ pending bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ pending bit */ + uint32_t A:1; /*!< \brief bit: 8 External abort pending bit */ + RESERVED(1:23, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} ISR_Type; + +#define ISR_A_Pos 13U /*!< \brief ISR: A Position */ +#define ISR_A_Msk (1UL << ISR_A_Pos) /*!< \brief ISR: A Mask */ + +#define ISR_I_Pos 12U /*!< \brief ISR: I Position */ +#define ISR_I_Msk (1UL << ISR_I_Pos) /*!< \brief ISR: I Mask */ + +#define ISR_F_Pos 11U /*!< \brief ISR: F Position */ +#define ISR_F_Msk (1UL << ISR_F_Pos) /*!< \brief ISR: F Mask */ + +/* DACR Register */ +#define DACR_D_Pos_(n) (2U*n) /*!< \brief DACR: Dn Position */ +#define DACR_D_Msk_(n) (3UL << DACR_D_Pos_(n)) /*!< \brief DACR: Dn Mask */ +#define DACR_Dn_NOACCESS 0U /*!< \brief DACR Dn field: No access */ +#define DACR_Dn_CLIENT 1U /*!< \brief DACR Dn field: Client */ +#define DACR_Dn_MANAGER 3U /*!< \brief DACR Dn field: Manager */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param [in] field Name of the register bit field. + \param [in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param [in] field Name of the register bit field. + \param [in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + + +/** + \brief Union type to access the L2C_310 Cache Controller. +*/ +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +typedef struct +{ + __IM uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 (R/ ) Cache ID Register */ + __IM uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 (R/ ) Cache Type Register */ + RESERVED(0[0x3e], uint32_t) + __IOM uint32_t CONTROL; /*!< \brief Offset: 0x0100 (R/W) Control Register */ + __IOM uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 (R/W) Auxiliary Control */ + RESERVED(1[0x3e], uint32_t) + __IOM uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 (R/W) Event Counter Control */ + __IOM uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 (R/W) Event Counter 1 Configuration */ + __IOM uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 (R/W) Event Counter 1 Configuration */ + RESERVED(2[0x2], uint32_t) + __IOM uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 (R/W) Interrupt Mask */ + __IM uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 (R/ ) Masked Interrupt Status */ + __IM uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c (R/ ) Raw Interrupt Status */ + __OM uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 ( /W) Interrupt Clear */ + RESERVED(3[0x143], uint32_t) + __IOM uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 (R/W) Cache Sync */ + RESERVED(4[0xf], uint32_t) + __IOM uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 (R/W) Invalidate Line By PA */ + RESERVED(6[2], uint32_t) + __IOM uint32_t INV_WAY; /*!< \brief Offset: 0x077c (R/W) Invalidate by Way */ + RESERVED(5[0xc], uint32_t) + __IOM uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 (R/W) Clean Line by PA */ + RESERVED(7[1], uint32_t) + __IOM uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 (R/W) Clean Line by Index/Way */ + __IOM uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc (R/W) Clean by Way */ + RESERVED(8[0xc], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 (R/W) Clean and Invalidate Line by PA */ + RESERVED(9[1], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 (R/W) Clean and Invalidate Line by Index/Way */ + __IOM uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc (R/W) Clean and Invalidate by Way */ + RESERVED(10[0x40], uint32_t) + __IOM uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 (R/W) Data Lockdown 0 by Way */ + __IOM uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 (R/W) Instruction Lockdown 0 by Way */ + __IOM uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 (R/W) Data Lockdown 1 by Way */ + __IOM uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c (R/W) Instruction Lockdown 1 by Way */ + __IOM uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 (R/W) Data Lockdown 2 by Way */ + __IOM uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 (R/W) Instruction Lockdown 2 by Way */ + __IOM uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 (R/W) Data Lockdown 3 by Way */ + __IOM uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c (R/W) Instruction Lockdown 3 by Way */ + __IOM uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 (R/W) Data Lockdown 4 by Way */ + __IOM uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 (R/W) Instruction Lockdown 4 by Way */ + __IOM uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 (R/W) Data Lockdown 6 by Way */ + __IOM uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c (R/W) Instruction Lockdown 6 by Way */ + RESERVED(11[0x4], uint32_t) + __IOM uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 (R/W) Lockdown by Line Enable */ + __IOM uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 (R/W) Unlock All Lines by Way */ + RESERVED(12[0xaa], uint32_t) + __IOM uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 (R/W) Address Filtering Start */ + __IOM uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 (R/W) Address Filtering End */ + RESERVED(13[0xce], uint32_t) + __IOM uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 (R/W) Debug Control Register */ +} L2C_310_TypeDef; + +#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 register set access pointer */ +#endif + +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + +/** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) +*/ +typedef struct +{ + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) Distributor Control Register */ + __IM uint32_t TYPER; /*!< \brief Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IM uint32_t IIDR; /*!< \brief Offset: 0x008 (R/ ) Distributor Implementer Identification Register */ + RESERVED(0, uint32_t) + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x010 (R/W) Error Reporting Status Register, optional */ + RESERVED(1[11], uint32_t) + __OM uint32_t SETSPI_NSR; /*!< \brief Offset: 0x040 ( /W) Set SPI Register */ + RESERVED(2, uint32_t) + __OM uint32_t CLRSPI_NSR; /*!< \brief Offset: 0x048 ( /W) Clear SPI Register */ + RESERVED(3, uint32_t) + __OM uint32_t SETSPI_SR; /*!< \brief Offset: 0x050 ( /W) Set SPI, Secure Register */ + RESERVED(4, uint32_t) + __OM uint32_t CLRSPI_SR; /*!< \brief Offset: 0x058 ( /W) Clear SPI, Secure Register */ + RESERVED(5[9], uint32_t) + __IOM uint32_t IGROUPR[32]; /*!< \brief Offset: 0x080 (R/W) Interrupt Group Registers */ + __IOM uint32_t ISENABLER[32]; /*!< \brief Offset: 0x100 (R/W) Interrupt Set-Enable Registers */ + __IOM uint32_t ICENABLER[32]; /*!< \brief Offset: 0x180 (R/W) Interrupt Clear-Enable Registers */ + __IOM uint32_t ISPENDR[32]; /*!< \brief Offset: 0x200 (R/W) Interrupt Set-Pending Registers */ + __IOM uint32_t ICPENDR[32]; /*!< \brief Offset: 0x280 (R/W) Interrupt Clear-Pending Registers */ + __IOM uint32_t ISACTIVER[32]; /*!< \brief Offset: 0x300 (R/W) Interrupt Set-Active Registers */ + __IOM uint32_t ICACTIVER[32]; /*!< \brief Offset: 0x380 (R/W) Interrupt Clear-Active Registers */ + __IOM uint32_t IPRIORITYR[255]; /*!< \brief Offset: 0x400 (R/W) Interrupt Priority Registers */ + RESERVED(6, uint32_t) + __IOM uint32_t ITARGETSR[255]; /*!< \brief Offset: 0x800 (R/W) Interrupt Targets Registers */ + RESERVED(7, uint32_t) + __IOM uint32_t ICFGR[64]; /*!< \brief Offset: 0xC00 (R/W) Interrupt Configuration Registers */ + __IOM uint32_t IGRPMODR[32]; /*!< \brief Offset: 0xD00 (R/W) Interrupt Group Modifier Registers */ + RESERVED(8[32], uint32_t) + __IOM uint32_t NSACR[64]; /*!< \brief Offset: 0xE00 (R/W) Non-secure Access Control Registers */ + __OM uint32_t SGIR; /*!< \brief Offset: 0xF00 ( /W) Software Generated Interrupt Register */ + RESERVED(9[3], uint32_t) + __IOM uint32_t CPENDSGIR[4]; /*!< \brief Offset: 0xF10 (R/W) SGI Clear-Pending Registers */ + __IOM uint32_t SPENDSGIR[4]; /*!< \brief Offset: 0xF20 (R/W) SGI Set-Pending Registers */ + RESERVED(10[5236], uint32_t) + __IOM uint64_t IROUTER[988]; /*!< \brief Offset: 0x6100(R/W) Interrupt Routing Registers */ +} GICDistributor_Type; + +#define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< \brief GIC Distributor register set access pointer */ + +/** \brief Structure type to access the Generic Interrupt Controller Interface (GICC) +*/ +typedef struct +{ + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) CPU Interface Control Register */ + __IOM uint32_t PMR; /*!< \brief Offset: 0x004 (R/W) Interrupt Priority Mask Register */ + __IOM uint32_t BPR; /*!< \brief Offset: 0x008 (R/W) Binary Point Register */ + __IM uint32_t IAR; /*!< \brief Offset: 0x00C (R/ ) Interrupt Acknowledge Register */ + __OM uint32_t EOIR; /*!< \brief Offset: 0x010 ( /W) End Of Interrupt Register */ + __IM uint32_t RPR; /*!< \brief Offset: 0x014 (R/ ) Running Priority Register */ + __IM uint32_t HPPIR; /*!< \brief Offset: 0x018 (R/ ) Highest Priority Pending Interrupt Register */ + __IOM uint32_t ABPR; /*!< \brief Offset: 0x01C (R/W) Aliased Binary Point Register */ + __IM uint32_t AIAR; /*!< \brief Offset: 0x020 (R/ ) Aliased Interrupt Acknowledge Register */ + __OM uint32_t AEOIR; /*!< \brief Offset: 0x024 ( /W) Aliased End Of Interrupt Register */ + __IM uint32_t AHPPIR; /*!< \brief Offset: 0x028 (R/ ) Aliased Highest Priority Pending Interrupt Register */ + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x02C (R/W) Error Reporting Status Register, optional */ + RESERVED(1[40], uint32_t) + __IOM uint32_t APR[4]; /*!< \brief Offset: 0x0D0 (R/W) Active Priority Register */ + __IOM uint32_t NSAPR[4]; /*!< \brief Offset: 0x0E0 (R/W) Non-secure Active Priority Register */ + RESERVED(2[3], uint32_t) + __IM uint32_t IIDR; /*!< \brief Offset: 0x0FC (R/ ) CPU Interface Identification Register */ + RESERVED(3[960], uint32_t) + __OM uint32_t DIR; /*!< \brief Offset: 0x1000( /W) Deactivate Interrupt Register */ +} GICInterface_Type; + +#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< \brief GIC Interface register set access pointer */ +#endif + +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Structure type to access the Private Timer +*/ +typedef struct +{ + __IOM uint32_t LOAD; //!< \brief Offset: 0x000 (R/W) Private Timer Load Register + __IOM uint32_t COUNTER; //!< \brief Offset: 0x004 (R/W) Private Timer Counter Register + __IOM uint32_t CONTROL; //!< \brief Offset: 0x008 (R/W) Private Timer Control Register + __IOM uint32_t ISR; //!< \brief Offset: 0x00C (R/W) Private Timer Interrupt Status Register + RESERVED(0[4], uint32_t) + __IOM uint32_t WLOAD; //!< \brief Offset: 0x020 (R/W) Watchdog Load Register + __IOM uint32_t WCOUNTER; //!< \brief Offset: 0x024 (R/W) Watchdog Counter Register + __IOM uint32_t WCONTROL; //!< \brief Offset: 0x028 (R/W) Watchdog Control Register + __IOM uint32_t WISR; //!< \brief Offset: 0x02C (R/W) Watchdog Interrupt Status Register + __IOM uint32_t WRESET; //!< \brief Offset: 0x030 (R/W) Watchdog Reset Status Register + __OM uint32_t WDISABLE; //!< \brief Offset: 0x034 ( /W) Watchdog Disable Register +} Timer_Type; +#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer register struct */ +#endif +#endif + + /******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - L1 Cache Functions + - L2C-310 Cache Controller Functions + - PL1 Timer Functions + - GIC Functions + - MMU Functions + ******************************************************************************/ + +/* ########################## L1 Cache functions ################################# */ + +/** \brief Enable Caches by setting I and C bits in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_EnableCaches(void) { + __set_SCTLR( __get_SCTLR() | SCTLR_I_Msk | SCTLR_C_Msk); + __ISB(); +} + +/** \brief Disable Caches by clearing I and C bits in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_DisableCaches(void) { + __set_SCTLR( __get_SCTLR() & (~SCTLR_I_Msk) & (~SCTLR_C_Msk)); + __ISB(); +} + +/** \brief Enable Branch Prediction by setting Z bit in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_EnableBTAC(void) { + __set_SCTLR( __get_SCTLR() | SCTLR_Z_Msk); + __ISB(); +} + +/** \brief Disable Branch Prediction by clearing Z bit in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_DisableBTAC(void) { + __set_SCTLR( __get_SCTLR() & (~SCTLR_Z_Msk)); + __ISB(); +} + +/** \brief Invalidate entire branch predictor array +*/ +__STATIC_FORCEINLINE void L1C_InvalidateBTAC(void) { + __set_BPIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + +/** \brief Invalidate the whole instruction cache +*/ +__STATIC_FORCEINLINE void L1C_InvalidateICacheAll(void) { + __set_ICIALLU(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new I cache state +} + +/** \brief Clean data cache line by address. +* \param [in] va Pointer to data to clear the cache for. +*/ +__STATIC_FORCEINLINE void L1C_CleanDCacheMVA(void *va) { + __set_DCCMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Invalidate data cache line by address. +* \param [in] va Pointer to data to invalidate the cache for. +*/ +__STATIC_FORCEINLINE void L1C_InvalidateDCacheMVA(void *va) { + __set_DCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Clean and Invalidate data cache by address. +* \param [in] va Pointer to data to invalidate the cache for. +*/ +__STATIC_FORCEINLINE void L1C_CleanInvalidateDCacheMVA(void *va) { + __set_DCCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Calculate log2 rounded up +* - log(0) => 0 +* - log(1) => 0 +* - log(2) => 1 +* - log(3) => 2 +* - log(4) => 2 +* - log(5) => 3 +* : : +* - log(16) => 4 +* - log(32) => 5 +* : : +* \param [in] n input value parameter +* \return log2(n) +*/ +__STATIC_FORCEINLINE uint8_t __log2_up(uint32_t n) +{ + if (n < 2U) { + return 0U; + } + uint8_t log = 0U; + uint32_t t = n; + while(t > 1U) + { + log++; + t >>= 1U; + } + if (n & 1U) { log++; } + return log; +} + +/** \brief Apply cache maintenance to given cache level. +* \param [in] level cache level to be maintained +* \param [in] maint 0 - invalidate, 1 - clean, otherwise - invalidate and clean +*/ +__STATIC_FORCEINLINE void __L1C_MaintainDCacheSetWay(uint32_t level, uint32_t maint) +{ + uint32_t Dummy; + uint32_t ccsidr; + uint32_t num_sets; + uint32_t num_ways; + uint32_t shift_way; + uint32_t log2_linesize; + int32_t log2_num_ways; + + Dummy = level << 1U; + /* set csselr, select ccsidr register */ + __set_CSSELR(Dummy); + /* get current ccsidr register */ + ccsidr = __get_CCSIDR(); + num_sets = ((ccsidr & 0x0FFFE000U) >> 13U) + 1U; + num_ways = ((ccsidr & 0x00001FF8U) >> 3U) + 1U; + log2_linesize = (ccsidr & 0x00000007U) + 2U + 2U; + log2_num_ways = __log2_up(num_ways); + if ((log2_num_ways < 0) || (log2_num_ways > 32)) { + return; // FATAL ERROR + } + shift_way = 32U - (uint32_t)log2_num_ways; + for(int32_t way = num_ways-1; way >= 0; way--) + { + for(int32_t set = num_sets-1; set >= 0; set--) + { + Dummy = (level << 1U) | (((uint32_t)set) << log2_linesize) | (((uint32_t)way) << shift_way); + switch (maint) + { + case 0U: __set_DCISW(Dummy); break; + case 1U: __set_DCCSW(Dummy); break; + default: __set_DCCISW(Dummy); break; + } + } + } + __DMB(); +} + +/** \brief Clean and Invalidate the entire data or unified cache +* Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +*/ +__STATIC_FORCEINLINE void L1C_CleanInvalidateCache(uint32_t op) { + uint32_t clidr; + uint32_t cache_type; + clidr = __get_CLIDR(); + for(uint32_t i = 0U; i<7U; i++) + { + cache_type = (clidr >> i*3U) & 0x7UL; + if ((cache_type >= 2U) && (cache_type <= 4U)) + { + __L1C_MaintainDCacheSetWay(i, op); + } + } +} + +/** \brief Clean and Invalidate the entire data or unified cache +* Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +* \deprecated Use generic L1C_CleanInvalidateCache instead. +*/ +CMSIS_DEPRECATED +__STATIC_FORCEINLINE void __L1C_CleanInvalidateCache(uint32_t op) { + L1C_CleanInvalidateCache(op); +} + +/** \brief Invalidate the whole data cache. +*/ +__STATIC_FORCEINLINE void L1C_InvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(0); +} + +/** \brief Clean the whole data cache. + */ +__STATIC_FORCEINLINE void L1C_CleanDCacheAll(void) { + L1C_CleanInvalidateCache(1); +} + +/** \brief Clean and invalidate the whole data cache. + */ +__STATIC_FORCEINLINE void L1C_CleanInvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(2); +} + +/* ########################## L2 Cache functions ################################# */ +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +/** \brief Cache Sync operation by writing CACHE_SYNC register. +*/ +__STATIC_INLINE void L2C_Sync(void) +{ + L2C_310->CACHE_SYNC = 0x0; +} + +/** \brief Read cache controller cache ID from CACHE_ID register. + * \return L2C_310_TypeDef::CACHE_ID + */ +__STATIC_INLINE int L2C_GetID (void) +{ + return L2C_310->CACHE_ID; +} + +/** \brief Read cache controller cache type from CACHE_TYPE register. +* \return L2C_310_TypeDef::CACHE_TYPE +*/ +__STATIC_INLINE int L2C_GetType (void) +{ + return L2C_310->CACHE_TYPE; +} + +/** \brief Invalidate all cache by way +*/ +__STATIC_INLINE void L2C_InvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->INV_WAY = (1U << assoc) - 1U; + while(L2C_310->INV_WAY & ((1U << assoc) - 1U)); //poll invalidate + + L2C_Sync(); +} + +/** \brief Clean and Invalidate all cache by way +*/ +__STATIC_INLINE void L2C_CleanInvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->CLEAN_INV_WAY = (1U << assoc) - 1U; + while(L2C_310->CLEAN_INV_WAY & ((1U << assoc) - 1U)); //poll invalidate + + L2C_Sync(); +} + +/** \brief Enable Level 2 Cache +*/ +__STATIC_INLINE void L2C_Enable(void) +{ + L2C_310->CONTROL = 0; + L2C_310->INTERRUPT_CLEAR = 0x000001FFuL; + L2C_310->DEBUG_CONTROL = 0; + L2C_310->DATA_LOCK_0_WAY = 0; + L2C_310->CACHE_SYNC = 0; + L2C_310->CONTROL = 0x01; + L2C_Sync(); +} + +/** \brief Disable Level 2 Cache +*/ +__STATIC_INLINE void L2C_Disable(void) +{ + L2C_310->CONTROL = 0x00; + L2C_Sync(); +} + +/** \brief Invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_InvPa (void *pa) +{ + L2C_310->INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +/** \brief Clean cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_CleanPa (void *pa) +{ + L2C_310->CLEAN_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +/** \brief Clean and invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_CleanInvPa (void *pa) +{ + L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} +#endif + +/* ########################## GIC functions ###################################### */ +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + +/** \brief Enable the interrupt distributor using the GIC's CTLR register. +*/ +__STATIC_INLINE void GIC_EnableDistributor(void) +{ + GICDistributor->CTLR |= 1U; +} + +/** \brief Disable the interrupt distributor using the GIC's CTLR register. +*/ +__STATIC_INLINE void GIC_DisableDistributor(void) +{ + GICDistributor->CTLR &=~1U; +} + +/** \brief Read the GIC's TYPER register. +* \return GICDistributor_Type::TYPER +*/ +__STATIC_INLINE uint32_t GIC_DistributorInfo(void) +{ + return (GICDistributor->TYPER); +} + +/** \brief Reads the GIC's IIDR register. +* \return GICDistributor_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_DistributorImplementer(void) +{ + return (GICDistributor->IIDR); +} + +/** \brief Sets the GIC's ITARGETSR register for the given interrupt. +* \param [in] IRQn Interrupt to be configured. +* \param [in] cpu_target CPU interfaces to assign this interrupt to. +*/ +__STATIC_INLINE void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target) +{ + uint32_t mask = GICDistributor->ITARGETSR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->ITARGETSR[IRQn / 4U] = mask | ((cpu_target & 0xFFUL) << ((IRQn % 4U) * 8U)); +} + +/** \brief Read the GIC's ITARGETSR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return GICDistributor_Type::ITARGETSR +*/ +__STATIC_INLINE uint32_t GIC_GetTarget(IRQn_Type IRQn) +{ + return (GICDistributor->ITARGETSR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; +} + +/** \brief Enable the CPU's interrupt interface. +*/ +__STATIC_INLINE void GIC_EnableInterface(void) +{ + GICInterface->CTLR |= 1U; //enable interface +} + +/** \brief Disable the CPU's interrupt interface. +*/ +__STATIC_INLINE void GIC_DisableInterface(void) +{ + GICInterface->CTLR &=~1U; //disable distributor +} + +/** \brief Read the CPU's IAR register. +* \return GICInterface_Type::IAR +*/ +__STATIC_INLINE IRQn_Type GIC_AcknowledgePending(void) +{ + return (IRQn_Type)(GICInterface->IAR); +} + +/** \brief Writes the given interrupt number to the CPU's EOIR register. +* \param [in] IRQn The interrupt to be signaled as finished. +*/ +__STATIC_INLINE void GIC_EndInterrupt(IRQn_Type IRQn) +{ + GICInterface->EOIR = IRQn; +} + +/** \brief Enables the given interrupt using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ISENABLER[IRQn / 32U] = 1U << (IRQn % 32U); +} + +/** \brief Get interrupt enable status using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not enabled, 1 - interrupt is enabled. +*/ +__STATIC_INLINE uint32_t GIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return (GICDistributor->ISENABLER[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} + +/** \brief Disables the given interrupt using GIC's ICENABLER register. +* \param [in] IRQn The interrupt to be disabled. +*/ +__STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICENABLER[IRQn / 32U] = 1U << (IRQn % 32U); +} + +/** \brief Get interrupt pending status from GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not pending, 1 - interrupt is pendig. +*/ +__STATIC_INLINE uint32_t GIC_GetPendingIRQ(IRQn_Type IRQn) +{ + uint32_t pend; + + if (IRQn >= 16U) { + pend = (GICDistributor->ISPENDR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; + } else { + // INTID 0-15 Software Generated Interrupt + pend = (GICDistributor->SPENDSGIR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; + // No CPU identification offered + if (pend != 0U) { + pend = 1U; + } else { + pend = 0U; + } + } + + return (pend); +} + +/** \brief Sets the given interrupt as pending using GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if (IRQn >= 16U) { + GICDistributor->ISPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + // Forward the interrupt to the CPU interface that requested it + GICDistributor->SGIR = (IRQn | 0x02000000U); + } +} + +/** \brief Clears the given interrupt from being pending using GIC's ICPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (IRQn >= 16U) { + GICDistributor->ICPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->CPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + } +} + +/** \brief Sets the interrupt configuration using GIC's ICFGR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] int_config Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE void GIC_SetConfiguration(IRQn_Type IRQn, uint32_t int_config) +{ + uint32_t icfgr = GICDistributor->ICFGR[IRQn / 16U]; + uint32_t shift = (IRQn % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= ( int_config << shift); + + GICDistributor->ICFGR[IRQn / 16U] = icfgr; +} + +/** \brief Get the interrupt configuration from the GIC's ICFGR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE uint32_t GIC_GetConfiguration(IRQn_Type IRQn) +{ + return (GICDistributor->ICFGR[IRQn / 16U] >> ((IRQn % 16U) >> 1U)); +} + +/** \brief Set the priority for the given interrupt in the GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] priority The priority for the interrupt, lower values denote higher priorities. +*/ +__STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + uint32_t mask = GICDistributor->IPRIORITYR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->IPRIORITYR[IRQn / 4U] = mask | ((priority & 0xFFUL) << ((IRQn % 4U) * 8U)); +} + +/** \brief Read the current interrupt priority from GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be queried. +*/ +__STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn) +{ + return (GICDistributor->IPRIORITYR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; +} + +/** \brief Set the interrupt priority mask using CPU's PMR register. +* \param [in] priority Priority mask to be set. +*/ +__STATIC_INLINE void GIC_SetInterfacePriorityMask(uint32_t priority) +{ + GICInterface->PMR = priority & 0xFFUL; //set priority mask +} + +/** \brief Read the current interrupt priority mask from CPU's PMR register. +* \result GICInterface_Type::PMR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfacePriorityMask(void) +{ + return GICInterface->PMR; +} + +/** \brief Configures the group priority and subpriority split point using CPU's BPR register. +* \param [in] binary_point Amount of bits used as subpriority. +*/ +__STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point) +{ + GICInterface->BPR = binary_point & 7U; //set binary point +} + +/** \brief Read the current group priority and subpriority split point from CPU's BPR register. +* \return GICInterface_Type::BPR +*/ +__STATIC_INLINE uint32_t GIC_GetBinaryPoint(void) +{ + return GICInterface->BPR; +} + +/** \brief Get the status for a given interrupt. +* \param [in] IRQn The interrupt to get status for. +* \return 0 - not pending/active, 1 - pending, 2 - active, 3 - pending and active +*/ +__STATIC_INLINE uint32_t GIC_GetIRQStatus(IRQn_Type IRQn) +{ + uint32_t pending, active; + + active = ((GICDistributor->ISACTIVER[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + pending = ((GICDistributor->ISPENDR[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + + return ((active<<1U) | pending); +} + +/** \brief Generate a software interrupt using GIC's SGIR register. +* \param [in] IRQn Software interrupt to be generated. +* \param [in] target_list List of CPUs the software interrupt should be forwarded to. +* \param [in] filter_list Filter to be applied to determine interrupt receivers. +*/ +__STATIC_INLINE void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list) +{ + GICDistributor->SGIR = ((filter_list & 3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (IRQn & 0x0FUL); +} + +/** \brief Get the interrupt number of the highest interrupt pending from CPU's HPPIR register. +* \return GICInterface_Type::HPPIR +*/ +__STATIC_INLINE uint32_t GIC_GetHighPendingIRQ(void) +{ + return GICInterface->HPPIR; +} + +/** \brief Provides information about the implementer and revision of the CPU interface. +* \return GICInterface_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfaceId(void) +{ + return GICInterface->IIDR; +} + +/** \brief Set the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \param [in] group Interrupt group number: 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE void GIC_SetGroup(IRQn_Type IRQn, uint32_t group) +{ + uint32_t igroupr = GICDistributor->IGROUPR[IRQn / 32U]; + uint32_t shift = (IRQn % 32U); + + igroupr &= (~(1U << shift)); + igroupr |= ( (group & 1U) << shift); + + GICDistributor->IGROUPR[IRQn / 32U] = igroupr; +} +#define GIC_SetSecurity GIC_SetGroup + +/** \brief Get the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE uint32_t GIC_GetGroup(IRQn_Type IRQn) +{ + return (GICDistributor->IGROUPR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} +#define GIC_GetSecurity GIC_GetGroup + +/** \brief Initialize the interrupt distributor. +*/ +__STATIC_INLINE void GIC_DistInit(void) +{ + uint32_t i; + uint32_t num_irq = 0U; + uint32_t priority_field; + + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableDistributor(); + //Get the maximum number of interrupts that the GIC supports + num_irq = 32U * ((GIC_DistributorInfo() & 0x1FU) + 1U); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0U, 0xFFU); + priority_field = GIC_GetPriority((IRQn_Type)0U); + + for (i = 32U; i < num_irq; i++) + { + //Disable the SPI interrupt + GIC_DisableIRQ((IRQn_Type)i); + //Set level-sensitive (and N-N model) + GIC_SetConfiguration((IRQn_Type)i, 0U); + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + //Set target list to CPU0 + GIC_SetTarget((IRQn_Type)i, 1U); + } + //Enable distributor + GIC_EnableDistributor(); +} + +/** \brief Initialize the CPU's interrupt interface +*/ +__STATIC_INLINE void GIC_CPUInterfaceInit(void) +{ + uint32_t i; + uint32_t priority_field; + + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableInterface(); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0U, 0xFFU); + priority_field = GIC_GetPriority((IRQn_Type)0U); + + //SGI and PPI + for (i = 0U; i < 32U; i++) + { + if(i > 15U) { + //Set level-sensitive (and N-N model) for PPI + GIC_SetConfiguration((IRQn_Type)i, 0U); + } + //Disable SGI and PPI interrupts + GIC_DisableIRQ((IRQn_Type)i); + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + } + //Enable interface + GIC_EnableInterface(); + //Set binary point to 0 + GIC_SetBinaryPoint(0U); + //Set priority mask + GIC_SetInterfacePriorityMask(0xFFU); +} + +/** \brief Initialize and enable the GIC +*/ +__STATIC_INLINE void GIC_Enable(void) +{ + GIC_DistInit(); + GIC_CPUInterfaceInit(); //per CPU +} +#endif + +/* ########################## Generic Timer functions ############################ */ +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) + +/* PL1 Physical Timer */ +#if (__CORTEX_A == 7U) || defined(DOXYGEN) + +/** \brief Physical Timer Control register */ +typedef union +{ + struct + { + uint32_t ENABLE:1; /*!< \brief bit: 0 Enables the timer. */ + uint32_t IMASK:1; /*!< \brief bit: 1 Timer output signal mask bit. */ + uint32_t ISTATUS:1; /*!< \brief bit: 2 The status of the timer. */ + RESERVED(0:29, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CNTP_CTL_Type; + +/** \brief Configures the frequency the timer shall run at. +* \param [in] value The timer frequency in Hz. +*/ +__STATIC_INLINE void PL1_SetCounterFrequency(uint32_t value) +{ + __set_CNTFRQ(value); + __ISB(); +} + +/** \brief Sets the reset value of the timer. +* \param [in] value The value the timer is loaded with. +*/ +__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) +{ + __set_CNTP_TVAL(value); + __ISB(); +} + +/** \brief Get the current counter value. +* \return Current counter value. +*/ +__STATIC_INLINE uint32_t PL1_GetCurrentValue(void) +{ + return(__get_CNTP_TVAL()); +} + +/** \brief Get the current physical counter value. +* \return Current physical counter value. +*/ +__STATIC_INLINE uint64_t PL1_GetCurrentPhysicalValue(void) +{ + return(__get_CNTPCT()); +} + +/** \brief Set the physical compare value. +* \param [in] value New physical timer compare value. +*/ +__STATIC_INLINE void PL1_SetPhysicalCompareValue(uint64_t value) +{ + __set_CNTP_CVAL(value); + __ISB(); +} + +/** \brief Get the physical compare value. +* \return Physical compare value. +*/ +__STATIC_INLINE uint64_t PL1_GetPhysicalCompareValue(void) +{ + return(__get_CNTP_CVAL()); +} + +/** \brief Configure the timer by setting the control value. +* \param [in] value New timer control value. +*/ +__STATIC_INLINE void PL1_SetControl(uint32_t value) +{ + __set_CNTP_CTL(value); + __ISB(); +} + +/** \brief Get the control value. +* \return Control value. +*/ +__STATIC_INLINE uint32_t PL1_GetControl(void) +{ + return(__get_CNTP_CTL()); +} +#endif + +/* Private Timer */ +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Set the load value to timers LOAD register. +* \param [in] value The load value to be set. +*/ +__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) +{ + PTIM->LOAD = value; +} + +/** \brief Get the load value from timers LOAD register. +* \return Timer_Type::LOAD +*/ +__STATIC_INLINE uint32_t PTIM_GetLoadValue(void) +{ + return(PTIM->LOAD); +} + +/** \brief Set current counter value from its COUNTER register. +*/ +__STATIC_INLINE void PTIM_SetCurrentValue(uint32_t value) +{ + PTIM->COUNTER = value; +} + +/** \brief Get current counter value from timers COUNTER register. +* \result Timer_Type::COUNTER +*/ +__STATIC_INLINE uint32_t PTIM_GetCurrentValue(void) +{ + return(PTIM->COUNTER); +} + +/** \brief Configure the timer using its CONTROL register. +* \param [in] value The new configuration value to be set. +*/ +__STATIC_INLINE void PTIM_SetControl(uint32_t value) +{ + PTIM->CONTROL = value; +} + +/** ref Timer_Type::CONTROL Get the current timer configuration from its CONTROL register. +* \return Timer_Type::CONTROL +*/ +__STATIC_INLINE uint32_t PTIM_GetControl(void) +{ + return(PTIM->CONTROL); +} + +/** ref Timer_Type::CONTROL Get the event flag in timers ISR register. +* \return 0 - flag is not set, 1- flag is set +*/ +__STATIC_INLINE uint32_t PTIM_GetEventFlag(void) +{ + return (PTIM->ISR & 1UL); +} + +/** ref Timer_Type::CONTROL Clears the event flag in timers ISR register. +*/ +__STATIC_INLINE void PTIM_ClearEventFlag(void) +{ + PTIM->ISR = 1; +} +#endif +#endif + +/* ########################## MMU functions ###################################### */ + +#define SECTION_DESCRIPTOR (0x2) +#define SECTION_MASK (0xFFFFFFFC) + +#define SECTION_TEXCB_MASK (0xFFFF8FF3) +#define SECTION_B_SHIFT (2) +#define SECTION_C_SHIFT (3) +#define SECTION_TEX0_SHIFT (12) +#define SECTION_TEX1_SHIFT (13) +#define SECTION_TEX2_SHIFT (14) + +#define SECTION_XN_MASK (0xFFFFFFEF) +#define SECTION_XN_SHIFT (4) + +#define SECTION_DOMAIN_MASK (0xFFFFFE1F) +#define SECTION_DOMAIN_SHIFT (5) + +#define SECTION_P_MASK (0xFFFFFDFF) +#define SECTION_P_SHIFT (9) + +#define SECTION_AP_MASK (0xFFFF73FF) +#define SECTION_AP_SHIFT (10) +#define SECTION_AP2_SHIFT (15) + +#define SECTION_S_MASK (0xFFFEFFFF) +#define SECTION_S_SHIFT (16) + +#define SECTION_NG_MASK (0xFFFDFFFF) +#define SECTION_NG_SHIFT (17) + +#define SECTION_NS_MASK (0xFFF7FFFF) +#define SECTION_NS_SHIFT (19) + +#define PAGE_L1_DESCRIPTOR (0x1) +#define PAGE_L1_MASK (0xFFFFFFFC) + +#define PAGE_L2_4K_DESC (0x2) +#define PAGE_L2_4K_MASK (0xFFFFFFFD) + +#define PAGE_L2_64K_DESC (0x1) +#define PAGE_L2_64K_MASK (0xFFFFFFFC) + +#define PAGE_4K_TEXCB_MASK (0xFFFFFE33) +#define PAGE_4K_B_SHIFT (2) +#define PAGE_4K_C_SHIFT (3) +#define PAGE_4K_TEX0_SHIFT (6) +#define PAGE_4K_TEX1_SHIFT (7) +#define PAGE_4K_TEX2_SHIFT (8) + +#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_64K_B_SHIFT (2) +#define PAGE_64K_C_SHIFT (3) +#define PAGE_64K_TEX0_SHIFT (12) +#define PAGE_64K_TEX1_SHIFT (13) +#define PAGE_64K_TEX2_SHIFT (14) + +#define PAGE_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_B_SHIFT (2) +#define PAGE_C_SHIFT (3) +#define PAGE_TEX_SHIFT (12) + +#define PAGE_XN_4K_MASK (0xFFFFFFFE) +#define PAGE_XN_4K_SHIFT (0) +#define PAGE_XN_64K_MASK (0xFFFF7FFF) +#define PAGE_XN_64K_SHIFT (15) + +#define PAGE_DOMAIN_MASK (0xFFFFFE1F) +#define PAGE_DOMAIN_SHIFT (5) + +#define PAGE_P_MASK (0xFFFFFDFF) +#define PAGE_P_SHIFT (9) + +#define PAGE_AP_MASK (0xFFFFFDCF) +#define PAGE_AP_SHIFT (4) +#define PAGE_AP2_SHIFT (9) + +#define PAGE_S_MASK (0xFFFFFBFF) +#define PAGE_S_SHIFT (10) + +#define PAGE_NG_MASK (0xFFFFF7FF) +#define PAGE_NG_SHIFT (11) + +#define PAGE_NS_MASK (0xFFFFFFF7) +#define PAGE_NS_SHIFT (3) + +#define OFFSET_1M (0x00100000) +#define OFFSET_64K (0x00010000) +#define OFFSET_4K (0x00001000) + +#define DESCRIPTOR_FAULT (0x00000000) + +/* Attributes enumerations */ + +/* Region size attributes */ +typedef enum +{ + SECTION, + PAGE_4k, + PAGE_64k, +} mmu_region_size_Type; + +/* Region type attributes */ +typedef enum +{ + NORMAL, + DEVICE, + SHARED_DEVICE, + NON_SHARED_DEVICE, + STRONGLY_ORDERED +} mmu_memory_Type; + +/* Region cacheability attributes */ +typedef enum +{ + NON_CACHEABLE, + WB_WA, + WT, + WB_NO_WA, +} mmu_cacheability_Type; + +/* Region parity check attributes */ +typedef enum +{ + ECC_DISABLED, + ECC_ENABLED, +} mmu_ecc_check_Type; + +/* Region execution attributes */ +typedef enum +{ + EXECUTE, + NON_EXECUTE, +} mmu_execute_Type; + +/* Region global attributes */ +typedef enum +{ + GLOBAL, + NON_GLOBAL, +} mmu_global_Type; + +/* Region shareability attributes */ +typedef enum +{ + NON_SHARED, + SHARED, +} mmu_shared_Type; + +/* Region security attributes */ +typedef enum +{ + SECURE, + NON_SECURE, +} mmu_secure_Type; + +/* Region access attributes */ +typedef enum +{ + NO_ACCESS, + RW, + READ, +} mmu_access_Type; + +/* Memory Region definition */ +typedef struct RegionStruct { + mmu_region_size_Type rg_t; + mmu_memory_Type mem_t; + uint8_t domain; + mmu_cacheability_Type inner_norm_t; + mmu_cacheability_Type outer_norm_t; + mmu_ecc_check_Type e_t; + mmu_execute_Type xn_t; + mmu_global_Type g_t; + mmu_secure_Type sec_t; + mmu_access_Type priv_t; + mmu_access_Type user_t; + mmu_shared_Type sh_t; + +} mmu_region_attributes_Type; + +//Following macros define the descriptors and attributes +//Sect_Normal. Outer & inner wb/wa, non-shareable, executable, rw, domain 0 +#define section_normal(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_NC. Outer & inner non-cacheable, non-shareable, executable, rw, domain 0 +#define section_normal_nc(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_Cod. Outer & inner wb/wa, non-shareable, executable, ro, domain 0 +#define section_normal_cod(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RO. Sect_Normal_Cod, but not executable +#define section_normal_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RW. Sect_Normal_Cod, but writeable and not executable +#define section_normal_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Sect_SO. Strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0 +#define section_so(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RO. Device, non-shareable, non-executable, ro, domain 0, base addr 0 +#define section_device_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RW. Sect_Device_RO, but writeable +#define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Page_4k_Device_RW. Shared device, not executable, rw, domain 0 +#define page4k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +//Page_64k_Device_RW. Shared device, not executable, rw, domain 0 +#define page64k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_64k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +/** \brief Set section execution-never attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. + + \return 0 +*/ +__STATIC_INLINE int MMU_XNSection(uint32_t *descriptor_l1, mmu_execute_Type xn) +{ + *descriptor_l1 &= SECTION_XN_MASK; + *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); + return 0; +} + +/** \brief Set section domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Section domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainSection(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= SECTION_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set section parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PSection(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set section access privileges + + \param [out] descriptor_l1 L1 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APSection(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l1 &= SECTION_AP_MASK; + *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; + *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; + + return 0; +} + +/** \brief Set section shareability + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedSection(uint32_t *descriptor_l1, mmu_shared_Type s_bit) +{ + *descriptor_l1 &= SECTION_S_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); + return 0; +} + +/** \brief Set section Global attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalSection(uint32_t *descriptor_l1, mmu_global_Type g_bit) +{ + *descriptor_l1 &= SECTION_NG_MASK; + *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); + return 0; +} + +/** \brief Set section Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecureSection(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= SECTION_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); + return 0; +} + +/* Page 4k or 64k */ +/** \brief Set 4k/64k page execution-never attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. + \param [in] page Page size: PAGE_4k, PAGE_64k, + + \return 0 +*/ +__STATIC_INLINE int MMU_XNPage(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) +{ + if (page == PAGE_4k) + { + *descriptor_l2 &= PAGE_XN_4K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); + } + else + { + *descriptor_l2 &= PAGE_XN_64K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); + } + return 0; +} + +/** \brief Set 4k/64k page domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Page domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainPage(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= PAGE_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PPage(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page access privileges + + \param [out] descriptor_l2 L2 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APPage(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x6; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l2 &= PAGE_AP_MASK; + *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; + *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; + + return 0; +} + +/** \brief Set 4k/64k page shareability + + \param [out] descriptor_l2 L2 descriptor. + \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedPage(uint32_t *descriptor_l2, mmu_shared_Type s_bit) +{ + *descriptor_l2 &= PAGE_S_MASK; + *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Global attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalPage(uint32_t *descriptor_l2, mmu_global_Type g_bit) +{ + *descriptor_l2 &= PAGE_NG_MASK; + *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecurePage(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= PAGE_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); + return 0; +} + +/** \brief Set Section memory attributes + + \param [out] descriptor_l1 L1 descriptor. + \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + + \return 0 +*/ +__STATIC_INLINE int MMU_MemorySection(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) +{ + *descriptor_l1 &= SECTION_TEXCB_MASK; + + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); + break; + } + } + return 0; +} + +/** \brief Set 4k/64k page memory attributes + + \param [out] descriptor_l2 L2 descriptor. + \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] page Page size + + \return 0 +*/ +__STATIC_INLINE int MMU_MemoryPage(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page) +{ + *descriptor_l2 &= PAGE_4K_TEXCB_MASK; + + if (page == PAGE_64k) + { + //same as section + MMU_MemorySection(descriptor_l2, mem, outer, inner); + } + else + { + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT); + break; + } + } + } + + return 0; +} + +/** \brief Create a L1 section descriptor + + \param [out] descriptor L1 descriptor + \param [in] reg Section attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetSectionDescriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + + MMU_MemorySection(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); + MMU_XNSection(descriptor,reg.xn_t); + MMU_DomainSection(descriptor, reg.domain); + MMU_PSection(descriptor, reg.e_t); + MMU_APSection(descriptor, reg.priv_t, reg.user_t, 1); + MMU_SharedSection(descriptor,reg.sh_t); + MMU_GlobalSection(descriptor,reg.g_t); + MMU_SecureSection(descriptor,reg.sec_t); + *descriptor &= SECTION_MASK; + *descriptor |= SECTION_DESCRIPTOR; + + return 0; +} + + +/** \brief Create a L1 and L2 4k/64k page descriptor + + \param [out] descriptor L1 descriptor + \param [out] descriptor2 L2 descriptor + \param [in] reg 4k/64k page attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetPageDescriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + *descriptor2 = 0; + + switch (reg.rg_t) + { + case PAGE_4k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_4k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_4K_MASK; + *descriptor2 |= PAGE_L2_4K_DESC; + break; + + case PAGE_64k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_64k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_64K_MASK; + *descriptor2 |= PAGE_L2_64K_DESC; + break; + + case SECTION: + //error + break; + } + + return 0; +} + +/** \brief Create a 1MB Section + + \param [in] ttb Translation table base address + \param [in] base_address Section base address + \param [in] count Number of sections to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) +{ + uint32_t offset; + uint32_t entry; + uint32_t i; + + offset = base_address >> 20; + entry = (base_address & 0xFFF00000) | descriptor_l1; + + //4 bytes aligned + ttb = ttb + offset; + + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *ttb++ = entry; + entry += OFFSET_1M; + } +} + +/** \brief Create a 4k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 4k base address + \param [in] count Number of 4k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i; + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFFF000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *ttb_l2++ = entry2; + entry2 += OFFSET_4K; + } +} + +/** \brief Create a 64k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 64k base address + \param [in] count Number of 64k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i,j; + + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFF0000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //create 16 entries + for (j = 0; j < 16; j++) + { + //4 bytes aligned + *ttb_l2++ = entry2; + } + entry2 += OFFSET_64K; + } +} + +/** \brief Enable MMU +*/ +__STATIC_INLINE void MMU_Enable(void) +{ + // Set M bit 0 to enable the MMU + // Set AFE bit to enable simplified access permissions model + // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking + __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); + __ISB(); +} + +/** \brief Disable MMU +*/ +__STATIC_INLINE void MMU_Disable(void) +{ + // Clear M bit 0 to disable the MMU + __set_SCTLR( __get_SCTLR() & ~1); + __ISB(); +} + +/** \brief Invalidate entire unified TLB +*/ + +__STATIC_INLINE void MMU_InvalidateTLB(void) +{ + __set_TLBIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Core_A/Include/irq_ctrl.h b/Drivers/CMSIS/Core_A/Include/irq_ctrl.h new file mode 100644 index 0000000..e52e14a --- /dev/null +++ b/Drivers/CMSIS/Core_A/Include/irq_ctrl.h @@ -0,0 +1,192 @@ +/**************************************************************************//** + * @file irq_ctrl.h + * @brief Interrupt Controller API header file + * @version V1.1.0 + * @date 03. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef IRQ_CTRL_H_ +#define IRQ_CTRL_H_ + +#include + +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +/// Interrupt handler data type +typedef void (*IRQHandler_t) (void); +#endif + +#ifndef IRQN_ID_T +#define IRQN_ID_T +/// Interrupt ID number data type +typedef int32_t IRQn_ID_t; +#endif + +/* Interrupt mode bit-masks */ +#define IRQ_MODE_TRIG_Pos (0U) +#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) +#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt +#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt + +#define IRQ_MODE_TYPE_Pos (3U) +#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos) +#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line +#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line + +#define IRQ_MODE_DOMAIN_Pos (4U) +#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos) +#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain +#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain + +#define IRQ_MODE_CPU_Pos (5U) +#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos) +#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs +#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0 +#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1 +#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2 +#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3 +#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4 +#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5 +#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6 +#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7 + +// Encoding in some early GIC implementations +#define IRQ_MODE_MODEL_Pos (13U) +#define IRQ_MODE_MODEL_Msk (0x1UL << IRQ_MODE_MODEL_Pos) +#define IRQ_MODE_MODEL_NN (0x0UL << IRQ_MODE_MODEL_Pos) ///< Corresponding interrupt is handled using the N-N model +#define IRQ_MODE_MODEL_1N (0x1UL << IRQ_MODE_MODEL_Pos) ///< Corresponding interrupt is handled using the 1-N model + +#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error + +/* Interrupt priority bit-masks */ +#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask +#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error + +/// Initialize interrupt controller. +/// \return 0 on success, -1 on error. +int32_t IRQ_Initialize (void); + +/// Register interrupt handler. +/// \param[in] irqn interrupt ID number +/// \param[in] handler interrupt handler function address +/// \return 0 on success, -1 on error. +int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler); + +/// Get the registered interrupt handler. +/// \param[in] irqn interrupt ID number +/// \return registered interrupt handler function address. +IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn); + +/// Enable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Enable (IRQn_ID_t irqn); + +/// Disable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Disable (IRQn_ID_t irqn); + +/// Get interrupt enable state. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is disabled, 1 - interrupt is enabled. +uint32_t IRQ_GetEnableState (IRQn_ID_t irqn); + +/// Configure interrupt request mode. +/// \param[in] irqn interrupt ID number +/// \param[in] mode mode configuration +/// \return 0 on success, -1 on error. +int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode); + +/// Get interrupt mode configuration. +/// \param[in] irqn interrupt ID number +/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set. +uint32_t IRQ_GetMode (IRQn_ID_t irqn); + +/// Get ID number of current interrupt request (IRQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveIRQ (void); + +/// Get ID number of current fast interrupt request (FIQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveFIQ (void); + +/// Signal end of interrupt processing. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn); + +/// Set interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPending (IRQn_ID_t irqn); + +/// Get interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is not pending, 1 - interrupt is pending. +uint32_t IRQ_GetPending (IRQn_ID_t irqn); + +/// Clear interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_ClearPending (IRQn_ID_t irqn); + +/// Set interrupt priority value. +/// \param[in] irqn interrupt ID number +/// \param[in] priority interrupt priority value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority); + +/// Get interrupt priority. +/// \param[in] irqn interrupt ID number +/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriority (IRQn_ID_t irqn); + +/// Set priority masking threshold. +/// \param[in] priority priority masking threshold value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityMask (uint32_t priority); + +/// Get priority masking threshold +/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityMask (void); + +/// Set priority grouping field split point +/// \param[in] bits number of MSB bits included in the group priority field comparison +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityGroupBits (uint32_t bits); + +/// Get priority grouping field split point +/// \return current number of MSB bits included in the group priority field comparison with +/// optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityGroupBits (void); + +#endif // IRQ_CTRL_H_ diff --git a/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c b/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c new file mode 100644 index 0000000..affaf81 --- /dev/null +++ b/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c @@ -0,0 +1,418 @@ +/**************************************************************************//** + * @file irq_ctrl_gic.c + * @brief Interrupt controller handling implementation for GIC + * @version V1.1.1 + * @date 29. March 2021 + ******************************************************************************/ +/* + * Copyright (c) 2017-2021 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#include + +#include "RTE_Components.h" +#include CMSIS_device_header + +#include "irq_ctrl.h" + +#if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U) + +/// Number of implemented interrupt lines +#ifndef IRQ_GIC_LINE_COUNT +#define IRQ_GIC_LINE_COUNT (1020U) +#endif + +static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U }; +static uint32_t IRQ_ID0; + +/// Initialize interrupt controller. +__WEAK int32_t IRQ_Initialize (void) { + uint32_t i; + + for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) { + IRQTable[i] = (IRQHandler_t)NULL; + } + GIC_Enable(); + return (0); +} + + +/// Register interrupt handler. +__WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + IRQTable[irqn] = handler; + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get the registered interrupt handler. +__WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) { + IRQHandler_t h; + + // Ignore CPUID field (software generated interrupts) + irqn &= 0x3FFU; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + h = IRQTable[irqn]; + } else { + h = (IRQHandler_t)0; + } + + return (h); +} + + +/// Enable interrupt. +__WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_EnableIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Disable interrupt. +__WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_DisableIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get interrupt enable state. +__WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) { + uint32_t enable; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + enable = GIC_GetEnableIRQ((IRQn_Type)irqn); + } else { + enable = 0U; + } + + return (enable); +} + + +/// Configure interrupt request mode. +__WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) { + uint32_t val; + uint8_t cfg; + uint8_t secure; + uint8_t cpu; + int32_t status = 0; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + // Check triggering mode + val = (mode & IRQ_MODE_TRIG_Msk); + + if (val == IRQ_MODE_TRIG_LEVEL) { + cfg = 0x00U; + } else if (val == IRQ_MODE_TRIG_EDGE) { + cfg = 0x02U; + } else { + cfg = 0x00U; + status = -1; + } + + val = (mode & IRQ_MODE_MODEL_Msk); + if (val == IRQ_MODE_MODEL_1N) { + cfg |= 1; // 1-N model + } + + // Check interrupt type + val = mode & IRQ_MODE_TYPE_Msk; + + if (val != IRQ_MODE_TYPE_IRQ) { + status = -1; + } + + // Check interrupt domain + val = mode & IRQ_MODE_DOMAIN_Msk; + + if (val == IRQ_MODE_DOMAIN_NONSECURE) { + secure = 0U; + } else { + // Check security extensions support + val = GIC_DistributorInfo() & (1UL << 10U); + + if (val != 0U) { + // Security extensions are supported + secure = 1U; + } else { + secure = 0U; + status = -1; + } + } + + // Check interrupt CPU targets + val = mode & IRQ_MODE_CPU_Msk; + + if (val == IRQ_MODE_CPU_ALL) { + cpu = 0xFFU; + } else { + cpu = (uint8_t)(val >> IRQ_MODE_CPU_Pos); + } + + // Apply configuration if no mode error + if (status == 0) { + GIC_SetConfiguration((IRQn_Type)irqn, cfg); + GIC_SetTarget ((IRQn_Type)irqn, cpu); + + if (secure != 0U) { + GIC_SetGroup ((IRQn_Type)irqn, secure); + } + } + } + + return (status); +} + + +/// Get interrupt mode configuration. +__WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) { + uint32_t mode; + uint32_t val; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + mode = IRQ_MODE_TYPE_IRQ; + + // Get trigger mode + val = GIC_GetConfiguration((IRQn_Type)irqn); + + if ((val & 2U) != 0U) { + // Corresponding interrupt is edge triggered + mode |= IRQ_MODE_TRIG_EDGE; + } else { + // Corresponding interrupt is level triggered + mode |= IRQ_MODE_TRIG_LEVEL; + } + + if (val & 1U) { + mode |= IRQ_MODE_MODEL_1N; + } + // Get interrupt CPU targets + mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos; + + } else { + mode = IRQ_MODE_ERROR; + } + + return (mode); +} + + +/// Get ID number of current interrupt request (IRQ). +__WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) { + IRQn_ID_t irqn; + uint32_t prio; + + /* Dummy read to avoid GIC 390 errata 801120 */ + GIC_GetHighPendingIRQ(); + + irqn = GIC_AcknowledgePending(); + + __DSB(); + + /* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */ + /* The following workaround code is for a single-core system. It would be */ + /* different in a multi-core system. */ + /* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */ + /* so unlock it, otherwise service the interrupt as normal. */ + /* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */ + /* so will not occur here. */ + + if ((irqn == 0) || (irqn >= 0x3FE)) { + /* Unlock the CPU interface with a dummy write to Interrupt Priority Register */ + prio = GIC_GetPriority((IRQn_Type)0); + GIC_SetPriority ((IRQn_Type)0, prio); + + __DSB(); + + if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) { + /* If the ID is 0, is active and has not been seen before */ + IRQ_ID0 = 1U; + } + /* End of Workaround GIC 390 errata 733075 */ + } + + return (irqn); +} + + +/// Get ID number of current fast interrupt request (FIQ). +__WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) { + return ((IRQn_ID_t)-1); +} + + +/// Signal end of interrupt processing. +__WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) { + int32_t status; + IRQn_Type irq = (IRQn_Type)irqn; + + irqn &= 0x3FFU; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_EndInterrupt (irq); + + if (irqn == 0) { + IRQ_ID0 = 0U; + } + + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Set interrupt pending flag. +__WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_SetPendingIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + +/// Get interrupt pending flag. +__WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) { + uint32_t pending; + + if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + pending = GIC_GetPendingIRQ ((IRQn_Type)irqn); + } else { + pending = 0U; + } + + return (pending & 1U); +} + + +/// Clear interrupt pending flag. +__WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) { + int32_t status; + + if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_ClearPendingIRQ ((IRQn_Type)irqn); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Set interrupt priority value. +__WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) { + int32_t status; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + GIC_SetPriority ((IRQn_Type)irqn, priority); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get interrupt priority. +__WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) { + uint32_t priority; + + if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) { + priority = GIC_GetPriority ((IRQn_Type)irqn); + } else { + priority = IRQ_PRIORITY_ERROR; + } + + return (priority); +} + + +/// Set priority masking threshold. +__WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) { + GIC_SetInterfacePriorityMask (priority); + return (0); +} + + +/// Get priority masking threshold +__WEAK uint32_t IRQ_GetPriorityMask (void) { + return GIC_GetInterfacePriorityMask(); +} + + +/// Set priority grouping field split point +__WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) { + int32_t status; + + if (bits == IRQ_PRIORITY_Msk) { + bits = 7U; + } + + if (bits < 8U) { + GIC_SetBinaryPoint (7U - bits); + status = 0; + } else { + status = -1; + } + + return (status); +} + + +/// Get priority grouping field split point +__WEAK uint32_t IRQ_GetPriorityGroupBits (void) { + uint32_t bp; + + bp = GIC_GetBinaryPoint() & 0x07U; + + return (7U - bp); +} + +#endif diff --git a/Drivers/CMSIS/DAP/Firmware/Config/DAP_config.h b/Drivers/CMSIS/DAP/Firmware/Config/DAP_config.h new file mode 100644 index 0000000..d4de40f --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Config/DAP_config.h @@ -0,0 +1,561 @@ +/* + * Copyright (c) 2013-2021 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 16. June 2021 + * $Revision: V2.1.0 + * + * Project: CMSIS-DAP Configuration + * Title: DAP_config.h CMSIS-DAP Configuration File (Template) + * + *---------------------------------------------------------------------------*/ + +#ifndef __DAP_CONFIG_H__ +#define __DAP_CONFIG_H__ + + +//************************************************************************************************** +/** +\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information +\ingroup DAP_ConfigIO_gr +@{ +Provides definitions about the hardware and configuration of the Debug Unit. + +This information includes: + - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit. + - Debug Unit Identification strings (Vendor, Product, Serial Number). + - Debug Unit communication packet size. + - Debug Access Port supported modes and settings (JTAG/SWD and SWO). + - Optional information about a connected Target Device (for Evaluation Boards). +*/ + +#ifdef _RTE_ +#include "RTE_Components.h" +#include CMSIS_device_header +#else +#include "device.h" // Debug Unit Cortex-M Processor Header File +#endif + +/// Processor Clock of the Cortex-M MCU used in the Debug Unit. +/// This value is used to calculate the SWD/JTAG clock speed. +#define CPU_CLOCK 100000000U ///< Specifies the CPU Clock in Hz. + +/// Number of processor cycles for I/O Port write operations. +/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O +/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors +/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses +/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be +/// required. +#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0. + +/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available. + +/// Indicate that JTAG communication mode is available at the Debug Port. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available. + +/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port. +/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255. +#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain. + +/// Default communication mode on the Debug Access Port. +/// Used for the command \ref DAP_Connect when Port Default mode is selected. +#define DAP_DEFAULT_PORT 1U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG. + +/// Default communication speed on the Debug Access Port for SWD and JTAG mode. +/// Used to initialize the default SWD/JTAG clock frequency. +/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting. +#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz. + +/// Maximum Package Size for Command and Response data. +/// This configuration settings is used to optimize the communication performance with the +/// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or WinUSB, +/// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB. +#define DAP_PACKET_SIZE 512U ///< Specifies Packet Size in bytes. + +/// Maximum Package Buffers for Command and Response data. +/// This configuration settings is used to optimize the communication performance with the +/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the +/// setting can be reduced (valid range is 1 .. 255). +#define DAP_PACKET_COUNT 8U ///< Specifies number of packets buffered. + +/// Indicate that UART Serial Wire Output (SWO) trace is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define SWO_UART 1 ///< SWO UART: 1 = available, 0 = not available. + +/// USART Driver instance number for the UART SWO. +#define SWO_UART_DRIVER 0 ///< USART Driver instance number (Driver_USART#). + +/// Maximum SWO UART Baudrate. +#define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz. + +/// Indicate that Manchester Serial Wire Output (SWO) trace is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available. + +/// SWO Trace Buffer Size. +#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n). + +/// SWO Streaming Trace. +#define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available. + +/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET. +#define TIMESTAMP_CLOCK 100000000U ///< Timestamp clock in Hz (0 = timestamps not supported). + +/// Indicate that UART Communication Port is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_UART 1 ///< DAP UART: 1 = available, 0 = not available. + +/// USART Driver instance number for the UART Communication Port. +#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#). + +/// UART Receive Buffer Size. +#define DAP_UART_RX_BUFFER_SIZE 1024U ///< Uart Receive Buffer Size in bytes (must be 2^n). + +/// UART Transmit Buffer Size. +#define DAP_UART_TX_BUFFER_SIZE 1024U ///< Uart Transmit Buffer Size in bytes (must be 2^n). + +/// Indicate that UART Communication via USB COM Port is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_UART_USB_COM_PORT 1 ///< USB COM Port: 1 = available, 0 = not available. + +/// Debug Unit is connected to fixed Target Device. +/// The Debug Unit may be part of an evaluation board and always connected to a fixed +/// known device. In this case a Device Vendor, Device Name, Board Vendor and Board Name strings +/// are stored and may be used by the debugger or IDE to configure device parameters. +#define TARGET_FIXED 0 ///< Target: 1 = known, 0 = unknown; + +#define TARGET_DEVICE_VENDOR "Arm" ///< String indicating the Silicon Vendor +#define TARGET_DEVICE_NAME "Cortex-M" ///< String indicating the Target Device +#define TARGET_BOARD_VENDOR "Arm" ///< String indicating the Board Vendor +#define TARGET_BOARD_NAME "Arm board" ///< String indicating the Board Name + +#if TARGET_FIXED != 0 +#include +static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR; +static const char TargetDeviceName [] = TARGET_DEVICE_NAME; +static const char TargetBoardVendor [] = TARGET_BOARD_VENDOR; +static const char TargetBoardName [] = TARGET_BOARD_NAME; +#endif + +/** Get Vendor Name string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetVendorString (char *str) { + (void)str; + return (0U); +} + +/** Get Product Name string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetProductString (char *str) { + (void)str; + return (0U); +} + +/** Get Serial Number string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetSerNumString (char *str) { + (void)str; + return (0U); +} + +/** Get Target Device Vendor string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetDeviceVendor); + len = (uint8_t)(strlen(TargetDeviceVendor) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** Get Target Device Name string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetDeviceName); + len = (uint8_t)(strlen(TargetDeviceName) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** Get Target Board Vendor string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetBoardVendor); + len = (uint8_t)(strlen(TargetBoardVendor) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** Get Target Board Name string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString (char *str) { +#if TARGET_FIXED != 0 + uint8_t len; + + strcpy(str, TargetBoardName); + len = (uint8_t)(strlen(TargetBoardName) + 1U); + return (len); +#else + (void)str; + return (0U); +#endif +} + +/** Get Product Firmware Version string. +\param str Pointer to buffer to store the string (max 60 characters). +\return String length (including terminating NULL character) or 0 (no string). +*/ +__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString (char *str) { + (void)str; + return (0U); +} + +///@} + + +//************************************************************************************************** +/** +\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access +\ingroup DAP_ConfigIO_gr +@{ + +Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode +and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug +interface of a device. The following I/O Pins are provided: + +JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode +---------------------------- | -------------------- | --------------------------------------------- +TCK: Test Clock | SWCLK: Clock | Output Push/Pull +TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data) +TDI: Test Data Input | | Output Push/Pull +TDO: Test Data Output | | Input +nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor +nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor + + +DAP Hardware I/O Pin Access Functions +------------------------------------- +The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to +these I/O Pins. + +For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only. +This functions are provided to achieve faster I/O that is possible with some advanced GPIO +peripherals that can independently write/read a single I/O pin without affecting any other pins +of the same I/O port. The following SWDIO I/O Pin functions are provided: + - \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware. + - \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware. + - \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed. + - \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed. +*/ + + +// Configure DAP I/O pins ------------------------------ + +/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET. +Configures the DAP Hardware I/O pins for JTAG mode: + - TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level. + - TDO to input mode. +*/ +__STATIC_INLINE void PORT_JTAG_SETUP (void) { + ; +} + +/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET. +Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode: + - SWCLK, SWDIO, nRESET to output mode and set to default high level. + - TDI, nTRST to HighZ mode (pins are unused in SWD mode). +*/ +__STATIC_INLINE void PORT_SWD_SETUP (void) { + ; +} + +/** Disable JTAG/SWD I/O Pins. +Disables the DAP Hardware I/O pins which configures: + - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode. +*/ +__STATIC_INLINE void PORT_OFF (void) { + ; +} + + +// SWCLK/TCK I/O pin ------------------------------------- + +/** SWCLK/TCK I/O pin: Get Input. +\return Current status of the SWCLK/TCK DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) { + return (0U); +} + +/** SWCLK/TCK I/O pin: Set Output to High. +Set the SWCLK/TCK DAP hardware I/O pin to high level. +*/ +__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) { + ; +} + +/** SWCLK/TCK I/O pin: Set Output to Low. +Set the SWCLK/TCK DAP hardware I/O pin to low level. +*/ +__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) { + ; +} + + +// SWDIO/TMS Pin I/O -------------------------------------- + +/** SWDIO/TMS I/O pin: Get Input. +\return Current status of the SWDIO/TMS DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) { + return (0U); +} + +/** SWDIO/TMS I/O pin: Set Output to High. +Set the SWDIO/TMS DAP hardware I/O pin to high level. +*/ +__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) { + ; +} + +/** SWDIO/TMS I/O pin: Set Output to Low. +Set the SWDIO/TMS DAP hardware I/O pin to low level. +*/ +__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) { + ; +} + +/** SWDIO I/O pin: Get Input (used in SWD mode only). +\return Current status of the SWDIO DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) { + return (0U); +} + +/** SWDIO I/O pin: Set Output (used in SWD mode only). +\param bit Output value for the SWDIO DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) { + ; +} + +/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only). +Configure the SWDIO DAP hardware I/O pin to output mode. This function is +called prior \ref PIN_SWDIO_OUT function calls. +*/ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) { + ; +} + +/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only). +Configure the SWDIO DAP hardware I/O pin to input mode. This function is +called prior \ref PIN_SWDIO_IN function calls. +*/ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) { + ; +} + + +// TDI Pin I/O --------------------------------------------- + +/** TDI I/O pin: Get Input. +\return Current status of the TDI DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) { + return (0U); +} + +/** TDI I/O pin: Set Output. +\param bit Output value for the TDI DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) { + ; +} + + +// TDO Pin I/O --------------------------------------------- + +/** TDO I/O pin: Get Input. +\return Current status of the TDO DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) { + return (0U); +} + + +// nTRST Pin I/O ------------------------------------------- + +/** nTRST I/O pin: Get Input. +\return Current status of the nTRST DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) { + return (0U); +} + +/** nTRST I/O pin: Set Output. +\param bit JTAG TRST Test Reset pin status: + - 0: issue a JTAG TRST Test Reset. + - 1: release JTAG TRST Test Reset. +*/ +__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) { + ; +} + +// nRESET Pin I/O------------------------------------------ + +/** nRESET I/O pin: Get Input. +\return Current status of the nRESET DAP hardware I/O pin. +*/ +__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) { + return (0U); +} + +/** nRESET I/O pin: Set Output. +\param bit target device hardware reset pin status: + - 0: issue a device hardware reset. + - 1: release device hardware reset. +*/ +__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) { + ; +} + +///@} + + +//************************************************************************************************** +/** +\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs +\ingroup DAP_ConfigIO_gr +@{ + +CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit. + +It is recommended to provide the following LEDs for status indication: + - Connect LED: is active when the DAP hardware is connected to a debugger. + - Running LED: is active when the debugger has put the target device into running state. +*/ + +/** Debug Unit: Set status of Connected LED. +\param bit status of the Connect LED. + - 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit. + - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit. +*/ +__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {} + +/** Debug Unit: Set status Target Running LED. +\param bit status of the Target Running LED. + - 1: Target Running LED ON: program execution in target started. + - 0: Target Running LED OFF: program execution in target stopped. +*/ +__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {} + +///@} + + +//************************************************************************************************** +/** +\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp +\ingroup DAP_ConfigIO_gr +@{ +Access function for Test Domain Timer. + +The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET. By +default, the DWT timer is used. The frequency of this timer is configured with \ref TIMESTAMP_CLOCK. + +*/ + +/** Get timestamp of Test Domain Timer. +\return Current timestamp value. +*/ +__STATIC_INLINE uint32_t TIMESTAMP_GET (void) { + return (DWT->CYCCNT); +} + +///@} + + +//************************************************************************************************** +/** +\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization +\ingroup DAP_ConfigIO_gr +@{ + +CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP. +*/ + +/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized). +This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the +Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set: + - I/O clock system enabled. + - all I/O pins: input buffer enabled, output pins are set to HighZ mode. + - for nTRST, nRESET a weak pull-up (if available) is enabled. + - LED output pins are enabled and LEDs are turned off. +*/ +__STATIC_INLINE void DAP_SETUP (void) { + ; +} + +/** Reset Target Device with custom specific I/O pin or command sequence. +This function allows the optional implementation of a device specific reset sequence. +It is called when the command \ref DAP_ResetTarget and is for example required +when a device needs a time-critical unlock sequence that enables the debug port. +\return 0 = no device specific reset sequence is implemented.\n + 1 = a device specific reset sequence is implemented. +*/ +__STATIC_INLINE uint8_t RESET_TARGET (void) { + return (0U); // change to '1' when a device reset sequence is implemented +} + +///@} + + +#endif /* __DAP_CONFIG_H__ */ diff --git a/Drivers/CMSIS/DAP/Firmware/Include/DAP.h b/Drivers/CMSIS/DAP/Firmware/Include/DAP.h new file mode 100644 index 0000000..7fc78b0 --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Include/DAP.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2013-2022 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 26. April 2022 + * $Revision: V2.1.1 + * + * Project: CMSIS-DAP Include + * Title: DAP.h Definitions + * + *---------------------------------------------------------------------------*/ + +#ifndef __DAP_H__ +#define __DAP_H__ + + +// DAP Firmware Version +#ifdef DAP_FW_V1 +#define DAP_FW_VER "1.3.0" +#else +#define DAP_FW_VER "2.1.1" +#endif + +// DAP Command IDs +#define ID_DAP_Info 0x00U +#define ID_DAP_HostStatus 0x01U +#define ID_DAP_Connect 0x02U +#define ID_DAP_Disconnect 0x03U +#define ID_DAP_TransferConfigure 0x04U +#define ID_DAP_Transfer 0x05U +#define ID_DAP_TransferBlock 0x06U +#define ID_DAP_TransferAbort 0x07U +#define ID_DAP_WriteABORT 0x08U +#define ID_DAP_Delay 0x09U +#define ID_DAP_ResetTarget 0x0AU +#define ID_DAP_SWJ_Pins 0x10U +#define ID_DAP_SWJ_Clock 0x11U +#define ID_DAP_SWJ_Sequence 0x12U +#define ID_DAP_SWD_Configure 0x13U +#define ID_DAP_SWD_Sequence 0x1DU +#define ID_DAP_JTAG_Sequence 0x14U +#define ID_DAP_JTAG_Configure 0x15U +#define ID_DAP_JTAG_IDCODE 0x16U +#define ID_DAP_SWO_Transport 0x17U +#define ID_DAP_SWO_Mode 0x18U +#define ID_DAP_SWO_Baudrate 0x19U +#define ID_DAP_SWO_Control 0x1AU +#define ID_DAP_SWO_Status 0x1BU +#define ID_DAP_SWO_ExtendedStatus 0x1EU +#define ID_DAP_SWO_Data 0x1CU +#define ID_DAP_UART_Transport 0x1FU +#define ID_DAP_UART_Configure 0x20U +#define ID_DAP_UART_Control 0x22U +#define ID_DAP_UART_Status 0x23U +#define ID_DAP_UART_Transfer 0x21U + +#define ID_DAP_QueueCommands 0x7EU +#define ID_DAP_ExecuteCommands 0x7FU + +// DAP Vendor Command IDs +#define ID_DAP_Vendor0 0x80U +#define ID_DAP_Vendor1 0x81U +#define ID_DAP_Vendor2 0x82U +#define ID_DAP_Vendor3 0x83U +#define ID_DAP_Vendor4 0x84U +#define ID_DAP_Vendor5 0x85U +#define ID_DAP_Vendor6 0x86U +#define ID_DAP_Vendor7 0x87U +#define ID_DAP_Vendor8 0x88U +#define ID_DAP_Vendor9 0x89U +#define ID_DAP_Vendor10 0x8AU +#define ID_DAP_Vendor11 0x8BU +#define ID_DAP_Vendor12 0x8CU +#define ID_DAP_Vendor13 0x8DU +#define ID_DAP_Vendor14 0x8EU +#define ID_DAP_Vendor15 0x8FU +#define ID_DAP_Vendor16 0x90U +#define ID_DAP_Vendor17 0x91U +#define ID_DAP_Vendor18 0x92U +#define ID_DAP_Vendor19 0x93U +#define ID_DAP_Vendor20 0x94U +#define ID_DAP_Vendor21 0x95U +#define ID_DAP_Vendor22 0x96U +#define ID_DAP_Vendor23 0x97U +#define ID_DAP_Vendor24 0x98U +#define ID_DAP_Vendor25 0x99U +#define ID_DAP_Vendor26 0x9AU +#define ID_DAP_Vendor27 0x9BU +#define ID_DAP_Vendor28 0x9CU +#define ID_DAP_Vendor29 0x9DU +#define ID_DAP_Vendor30 0x9EU +#define ID_DAP_Vendor31 0x9FU + +#define ID_DAP_Invalid 0xFFU + +// DAP Status Code +#define DAP_OK 0U +#define DAP_ERROR 0xFFU + +// DAP ID +#define DAP_ID_VENDOR 1U +#define DAP_ID_PRODUCT 2U +#define DAP_ID_SER_NUM 3U +#define DAP_ID_DAP_FW_VER 4U +#define DAP_ID_DEVICE_VENDOR 5U +#define DAP_ID_DEVICE_NAME 6U +#define DAP_ID_BOARD_VENDOR 7U +#define DAP_ID_BOARD_NAME 8U +#define DAP_ID_PRODUCT_FW_VER 9U +#define DAP_ID_CAPABILITIES 0xF0U +#define DAP_ID_TIMESTAMP_CLOCK 0xF1U +#define DAP_ID_UART_RX_BUFFER_SIZE 0xFBU +#define DAP_ID_UART_TX_BUFFER_SIZE 0xFCU +#define DAP_ID_SWO_BUFFER_SIZE 0xFDU +#define DAP_ID_PACKET_COUNT 0xFEU +#define DAP_ID_PACKET_SIZE 0xFFU + +// DAP Host Status +#define DAP_DEBUGGER_CONNECTED 0U +#define DAP_TARGET_RUNNING 1U + +// DAP Port +#define DAP_PORT_AUTODETECT 0U // Autodetect Port +#define DAP_PORT_DISABLED 0U // Port Disabled (I/O pins in High-Z) +#define DAP_PORT_SWD 1U // SWD Port (SWCLK, SWDIO) + nRESET +#define DAP_PORT_JTAG 2U // JTAG Port (TCK, TMS, TDI, TDO, nTRST) + nRESET + +// DAP SWJ Pins +#define DAP_SWJ_SWCLK_TCK 0 // SWCLK/TCK +#define DAP_SWJ_SWDIO_TMS 1 // SWDIO/TMS +#define DAP_SWJ_TDI 2 // TDI +#define DAP_SWJ_TDO 3 // TDO +#define DAP_SWJ_nTRST 5 // nTRST +#define DAP_SWJ_nRESET 7 // nRESET + +// DAP Transfer Request +#define DAP_TRANSFER_APnDP (1U<<0) +#define DAP_TRANSFER_RnW (1U<<1) +#define DAP_TRANSFER_A2 (1U<<2) +#define DAP_TRANSFER_A3 (1U<<3) +#define DAP_TRANSFER_MATCH_VALUE (1U<<4) +#define DAP_TRANSFER_MATCH_MASK (1U<<5) +#define DAP_TRANSFER_TIMESTAMP (1U<<7) + +// DAP Transfer Response +#define DAP_TRANSFER_OK (1U<<0) +#define DAP_TRANSFER_WAIT (1U<<1) +#define DAP_TRANSFER_FAULT (1U<<2) +#define DAP_TRANSFER_ERROR (1U<<3) +#define DAP_TRANSFER_MISMATCH (1U<<4) + +// DAP SWO Trace Mode +#define DAP_SWO_OFF 0U +#define DAP_SWO_UART 1U +#define DAP_SWO_MANCHESTER 2U + +// DAP SWO Trace Status +#define DAP_SWO_CAPTURE_ACTIVE (1U<<0) +#define DAP_SWO_CAPTURE_PAUSED (1U<<1) +#define DAP_SWO_STREAM_ERROR (1U<<6) +#define DAP_SWO_BUFFER_OVERRUN (1U<<7) + +// DAP UART Transport +#define DAP_UART_TRANSPORT_NONE 0U +#define DAP_UART_TRANSPORT_USB_COM_PORT 1U +#define DAP_UART_TRANSPORT_DAP_COMMAND 2U + +// DAP UART Control +#define DAP_UART_CONTROL_RX_ENABLE (1U<<0) +#define DAP_UART_CONTROL_RX_DISABLE (1U<<1) +#define DAP_UART_CONTROL_RX_BUF_FLUSH (1U<<2) +#define DAP_UART_CONTROL_TX_ENABLE (1U<<4) +#define DAP_UART_CONTROL_TX_DISABLE (1U<<5) +#define DAP_UART_CONTROL_TX_BUF_FLUSH (1U<<6) + +// DAP UART Status +#define DAP_UART_STATUS_RX_ENABLED (1U<<0) +#define DAP_UART_STATUS_RX_DATA_LOST (1U<<1) +#define DAP_UART_STATUS_FRAMING_ERROR (1U<<2) +#define DAP_UART_STATUS_PARITY_ERROR (1U<<3) +#define DAP_UART_STATUS_TX_ENABLED (1U<<4) + +// DAP UART Configure Error +#define DAP_UART_CFG_ERROR_DATA_BITS (1U<<0) +#define DAP_UART_CFG_ERROR_PARITY (1U<<1) +#define DAP_UART_CFG_ERROR_STOP_BITS (1U<<2) + +// Debug Port Register Addresses +#define DP_IDCODE 0x00U // IDCODE Register (SW Read only) +#define DP_ABORT 0x00U // Abort Register (SW Write only) +#define DP_CTRL_STAT 0x04U // Control & Status +#define DP_WCR 0x04U // Wire Control Register (SW Only) +#define DP_SELECT 0x08U // Select Register (JTAG R/W & SW W) +#define DP_RESEND 0x08U // Resend (SW Read Only) +#define DP_RDBUFF 0x0CU // Read Buffer (Read Only) + +// JTAG IR Codes +#define JTAG_ABORT 0x08U +#define JTAG_DPACC 0x0AU +#define JTAG_APACC 0x0BU +#define JTAG_IDCODE 0x0EU +#define JTAG_BYPASS 0x0FU + +// JTAG Sequence Info +#define JTAG_SEQUENCE_TCK 0x3FU // TCK count +#define JTAG_SEQUENCE_TMS 0x40U // TMS value +#define JTAG_SEQUENCE_TDO 0x80U // TDO capture + +// SWD Sequence Info +#define SWD_SEQUENCE_CLK 0x3FU // SWCLK count +#define SWD_SEQUENCE_DIN 0x80U // SWDIO capture + + +#include +#include +#include "cmsis_compiler.h" + +// DAP Data structure +typedef struct { + uint8_t debug_port; // Debug Port + uint8_t fast_clock; // Fast Clock Flag + uint8_t padding[2]; + uint32_t clock_delay; // Clock Delay + uint32_t timestamp; // Last captured Timestamp + struct { // Transfer Configuration + uint8_t idle_cycles; // Idle cycles after transfer + uint8_t padding[3]; + uint16_t retry_count; // Number of retries after WAIT response + uint16_t match_retry; // Number of retries if read value does not match + uint32_t match_mask; // Match Mask + } transfer; +#if (DAP_SWD != 0) + struct { // SWD Configuration + uint8_t turnaround; // Turnaround period + uint8_t data_phase; // Always generate Data Phase + } swd_conf; +#endif +#if (DAP_JTAG != 0) + struct { // JTAG Device Chain + uint8_t count; // Number of devices + uint8_t index; // Device index (device at TDO has index 0) +#if (DAP_JTAG_DEV_CNT != 0) + uint8_t ir_length[DAP_JTAG_DEV_CNT]; // IR Length in bits + uint16_t ir_before[DAP_JTAG_DEV_CNT]; // Bits before IR + uint16_t ir_after [DAP_JTAG_DEV_CNT]; // Bits after IR +#endif + } jtag_dev; +#endif +} DAP_Data_t; + +extern DAP_Data_t DAP_Data; // DAP Data +extern volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag + + +#ifdef __cplusplus +extern "C" +{ +#endif + +// Functions +extern void SWJ_Sequence (uint32_t count, const uint8_t *data); +extern void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi); +extern void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo); +extern void JTAG_IR (uint32_t ir); +extern uint32_t JTAG_ReadIDCode (void); +extern void JTAG_WriteAbort (uint32_t data); +extern uint8_t JTAG_Transfer (uint32_t request, uint32_t *data); +extern uint8_t SWD_Transfer (uint32_t request, uint32_t *data); + +extern void Delayms (uint32_t delay); + +extern uint32_t SWO_Transport (const uint8_t *request, uint8_t *response); +extern uint32_t SWO_Mode (const uint8_t *request, uint8_t *response); +extern uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response); +extern uint32_t SWO_Control (const uint8_t *request, uint8_t *response); +extern uint32_t SWO_Status (uint8_t *response); +extern uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response); +extern uint32_t SWO_Data (const uint8_t *request, uint8_t *response); + +extern void SWO_QueueTransfer (uint8_t *buf, uint32_t num); +extern void SWO_AbortTransfer (void); +extern void SWO_TransferComplete (void); + +extern uint32_t SWO_Mode_UART (uint32_t enable); +extern uint32_t SWO_Baudrate_UART (uint32_t baudrate); +extern uint32_t SWO_Control_UART (uint32_t active); +extern void SWO_Capture_UART (uint8_t *buf, uint32_t num); +extern uint32_t SWO_GetCount_UART (void); + +extern uint32_t SWO_Mode_Manchester (uint32_t enable); +extern uint32_t SWO_Baudrate_Manchester (uint32_t baudrate); +extern uint32_t SWO_Control_Manchester (uint32_t active); +extern void SWO_Capture_Manchester (uint8_t *buf, uint32_t num); +extern uint32_t SWO_GetCount_Manchester (void); + +extern uint32_t UART_Transport (const uint8_t *request, uint8_t *response); +extern uint32_t UART_Configure (const uint8_t *request, uint8_t *response); +extern uint32_t UART_Control (const uint8_t *request, uint8_t *response); +extern uint32_t UART_Status (uint8_t *response); +extern uint32_t UART_Transfer (const uint8_t *request, uint8_t *response); + +extern uint8_t USB_COM_PORT_Activate (uint32_t cmd); + +extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response); +extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response); +extern uint32_t DAP_ExecuteCommand (const uint8_t *request, uint8_t *response); + +extern void DAP_Setup (void); + +// Configurable delay for clock generation +#ifndef DELAY_SLOW_CYCLES +#define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration +#endif +#if defined(__CC_ARM) +__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) { + uint32_t count = delay; + while (--count); +} +#else +__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) { + __ASM volatile ( + ".syntax unified\n" + "0:\n\t" + "subs %0,%0,#1\n\t" + "bne 0b\n" + : "+l" (delay) : : "cc" + ); +} +#endif + +// Fixed delay for fast clock generation +#ifndef DELAY_FAST_CYCLES +#define DELAY_FAST_CYCLES 0U // Number of cycles: 0..3 +#endif +__STATIC_FORCEINLINE void PIN_DELAY_FAST (void) { +#if (DELAY_FAST_CYCLES >= 1U) + __NOP(); +#endif +#if (DELAY_FAST_CYCLES >= 2U) + __NOP(); +#endif +#if (DELAY_FAST_CYCLES >= 3U) + __NOP(); +#endif +} + +#ifdef __cplusplus +} +#endif + + +#endif /* __DAP_H__ */ diff --git a/Drivers/CMSIS/DAP/Firmware/Source/DAP.c b/Drivers/CMSIS/DAP/Firmware/Source/DAP.c new file mode 100644 index 0000000..4a76bb0 --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Source/DAP.c @@ -0,0 +1,1812 @@ +/* + * Copyright (c) 2013-2022 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 26. April 2022 + * $Revision: V2.1.1 + * + * Project: CMSIS-DAP Source + * Title: DAP.c CMSIS-DAP Commands + * + *---------------------------------------------------------------------------*/ + +#include +#include "DAP_config.h" +#include "DAP.h" + + +#if (DAP_PACKET_SIZE < 64U) +#error "Minimum Packet Size is 64!" +#endif +#if (DAP_PACKET_SIZE > 32768U) +#error "Maximum Packet Size is 32768!" +#endif +#if (DAP_PACKET_COUNT < 1U) +#error "Minimum Packet Count is 1!" +#endif +#if (DAP_PACKET_COUNT > 255U) +#error "Maximum Packet Count is 255!" +#endif + + +// Clock Macros +#define MAX_SWJ_CLOCK(delay_cycles) \ + ((CPU_CLOCK/2U) / (IO_PORT_WRITE_CYCLES + delay_cycles)) + + + DAP_Data_t DAP_Data; // DAP Data +volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag + + +static const char DAP_FW_Ver [] = DAP_FW_VER; + + +// Common clock delay calculation routine +// clock: requested SWJ frequency in Hertz +static void Set_Clock_Delay(uint32_t clock) { + uint32_t delay; + + if (clock >= MAX_SWJ_CLOCK(DELAY_FAST_CYCLES)) { + DAP_Data.fast_clock = 1U; + DAP_Data.clock_delay = 1U; + } else { + DAP_Data.fast_clock = 0U; + + delay = ((CPU_CLOCK/2U) + (clock - 1U)) / clock; + if (delay > IO_PORT_WRITE_CYCLES) { + delay -= IO_PORT_WRITE_CYCLES; + delay = (delay + (DELAY_SLOW_CYCLES - 1U)) / DELAY_SLOW_CYCLES; + } else { + delay = 1U; + } + + DAP_Data.clock_delay = delay; + } +} + + +// Get DAP Information +// id: info identifier +// info: pointer to info data +// return: number of bytes in info data +static uint8_t DAP_Info(uint8_t id, uint8_t *info) { + uint8_t length = 0U; + + switch (id) { + case DAP_ID_VENDOR: + length = DAP_GetVendorString((char *)info); + break; + case DAP_ID_PRODUCT: + length = DAP_GetProductString((char *)info); + break; + case DAP_ID_SER_NUM: + length = DAP_GetSerNumString((char *)info); + break; + case DAP_ID_DAP_FW_VER: + length = (uint8_t)sizeof(DAP_FW_Ver); + memcpy(info, DAP_FW_Ver, length); + break; + case DAP_ID_DEVICE_VENDOR: + length = DAP_GetTargetDeviceVendorString((char *)info); + break; + case DAP_ID_DEVICE_NAME: + length = DAP_GetTargetDeviceNameString((char *)info); + break; + case DAP_ID_BOARD_VENDOR: + length = DAP_GetTargetBoardVendorString((char *)info); + break; + case DAP_ID_BOARD_NAME: + length = DAP_GetTargetBoardNameString((char *)info); + break; + case DAP_ID_PRODUCT_FW_VER: + length = DAP_GetProductFirmwareVersionString((char *)info); + break; + case DAP_ID_CAPABILITIES: + info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) | + ((DAP_JTAG != 0) ? (1U << 1) : 0U) | + ((SWO_UART != 0) ? (1U << 2) : 0U) | + ((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) | + /* Atomic Commands */ (1U << 4) | + ((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) | + ((SWO_STREAM != 0U) ? (1U << 6) : 0U) | + ((DAP_UART != 0U) ? (1U << 7) : 0U); + + info[1] = ((DAP_UART_USB_COM_PORT != 0) ? (1U << 0) : 0U); + length = 2U; + break; + case DAP_ID_TIMESTAMP_CLOCK: +#if (TIMESTAMP_CLOCK != 0U) + info[0] = (uint8_t)(TIMESTAMP_CLOCK >> 0); + info[1] = (uint8_t)(TIMESTAMP_CLOCK >> 8); + info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16); + info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24); + length = 4U; +#endif + break; + case DAP_ID_UART_RX_BUFFER_SIZE: +#if (DAP_UART != 0) + info[0] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 0); + info[1] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 8); + info[2] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 16); + info[3] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 24); + length = 4U; +#endif + break; + case DAP_ID_UART_TX_BUFFER_SIZE: +#if (DAP_UART != 0) + info[0] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 0); + info[1] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 8); + info[2] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 16); + info[3] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 24); + length = 4U; +#endif + break; + case DAP_ID_SWO_BUFFER_SIZE: +#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) + info[0] = (uint8_t)(SWO_BUFFER_SIZE >> 0); + info[1] = (uint8_t)(SWO_BUFFER_SIZE >> 8); + info[2] = (uint8_t)(SWO_BUFFER_SIZE >> 16); + info[3] = (uint8_t)(SWO_BUFFER_SIZE >> 24); + length = 4U; +#endif + break; + case DAP_ID_PACKET_SIZE: + info[0] = (uint8_t)(DAP_PACKET_SIZE >> 0); + info[1] = (uint8_t)(DAP_PACKET_SIZE >> 8); + length = 2U; + break; + case DAP_ID_PACKET_COUNT: + info[0] = DAP_PACKET_COUNT; + length = 1U; + break; + default: + break; + } + + return (length); +} + + +// Delay for specified time +// delay: delay time in ms +void Delayms(uint32_t delay) { + delay *= ((CPU_CLOCK/1000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES; + PIN_DELAY_SLOW(delay); +} + + +// Process Delay command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_Delay(const uint8_t *request, uint8_t *response) { + uint32_t delay; + + delay = (uint32_t)(*(request+0)) | + (uint32_t)(*(request+1) << 8); + delay *= ((CPU_CLOCK/1000000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES; + + PIN_DELAY_SLOW(delay); + + *response = DAP_OK; + return ((2U << 16) | 1U); +} + + +// Process Host Status command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_HostStatus(const uint8_t *request, uint8_t *response) { + + switch (*request) { + case DAP_DEBUGGER_CONNECTED: + LED_CONNECTED_OUT((*(request+1) & 1U)); + break; + case DAP_TARGET_RUNNING: + LED_RUNNING_OUT((*(request+1) & 1U)); + break; + default: + *response = DAP_ERROR; + return ((2U << 16) | 1U); + } + + *response = DAP_OK; + return ((2U << 16) | 1U); +} + + +// Process Connect command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_Connect(const uint8_t *request, uint8_t *response) { + uint32_t port; + + if (*request == DAP_PORT_AUTODETECT) { + port = DAP_DEFAULT_PORT; + } else { + port = *request; + } + + switch (port) { +#if (DAP_SWD != 0) + case DAP_PORT_SWD: + DAP_Data.debug_port = DAP_PORT_SWD; + PORT_SWD_SETUP(); + break; +#endif +#if (DAP_JTAG != 0) + case DAP_PORT_JTAG: + DAP_Data.debug_port = DAP_PORT_JTAG; + PORT_JTAG_SETUP(); + break; +#endif + default: + port = DAP_PORT_DISABLED; + break; + } + + *response = (uint8_t)port; + return ((1U << 16) | 1U); +} + + +// Process Disconnect command and prepare response +// response: pointer to response data +// return: number of bytes in response +static uint32_t DAP_Disconnect(uint8_t *response) { + + DAP_Data.debug_port = DAP_PORT_DISABLED; + PORT_OFF(); + + *response = DAP_OK; + return (1U); +} + + +// Process Reset Target command and prepare response +// response: pointer to response data +// return: number of bytes in response +static uint32_t DAP_ResetTarget(uint8_t *response) { + + *(response+1) = RESET_TARGET(); + *(response+0) = DAP_OK; + return (2U); +} + + +// Process SWJ Pins command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) { +#if ((DAP_SWD != 0) || (DAP_JTAG != 0)) + uint32_t value; + uint32_t select; + uint32_t wait; + uint32_t timestamp; + + value = (uint32_t) *(request+0); + select = (uint32_t) *(request+1); + wait = (uint32_t)(*(request+2) << 0) | + (uint32_t)(*(request+3) << 8) | + (uint32_t)(*(request+4) << 16) | + (uint32_t)(*(request+5) << 24); + + if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) { + if ((value & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) { + PIN_SWCLK_TCK_SET(); + } else { + PIN_SWCLK_TCK_CLR(); + } + } + if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) { + if ((value & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) { + PIN_SWDIO_TMS_SET(); + } else { + PIN_SWDIO_TMS_CLR(); + } + } + if ((select & (1U << DAP_SWJ_TDI)) != 0U) { + PIN_TDI_OUT(value >> DAP_SWJ_TDI); + } + if ((select & (1U << DAP_SWJ_nTRST)) != 0U) { + PIN_nTRST_OUT(value >> DAP_SWJ_nTRST); + } + if ((select & (1U << DAP_SWJ_nRESET)) != 0U){ + PIN_nRESET_OUT(value >> DAP_SWJ_nRESET); + } + + if (wait != 0U) { +#if (TIMESTAMP_CLOCK != 0U) + if (wait > 3000000U) { + wait = 3000000U; + } +#if (TIMESTAMP_CLOCK >= 1000000U) + wait *= TIMESTAMP_CLOCK / 1000000U; +#else + wait /= 1000000U / TIMESTAMP_CLOCK; +#endif +#else + wait = 1U; +#endif + timestamp = TIMESTAMP_GET(); + do { + if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) { + if ((value >> DAP_SWJ_SWCLK_TCK) ^ PIN_SWCLK_TCK_IN()) { + continue; + } + } + if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) { + if ((value >> DAP_SWJ_SWDIO_TMS) ^ PIN_SWDIO_TMS_IN()) { + continue; + } + } + if ((select & (1U << DAP_SWJ_TDI)) != 0U) { + if ((value >> DAP_SWJ_TDI) ^ PIN_TDI_IN()) { + continue; + } + } + if ((select & (1U << DAP_SWJ_nTRST)) != 0U) { + if ((value >> DAP_SWJ_nTRST) ^ PIN_nTRST_IN()) { + continue; + } + } + if ((select & (1U << DAP_SWJ_nRESET)) != 0U) { + if ((value >> DAP_SWJ_nRESET) ^ PIN_nRESET_IN()) { + continue; + } + } + break; + } while ((TIMESTAMP_GET() - timestamp) < wait); + } + + value = (PIN_SWCLK_TCK_IN() << DAP_SWJ_SWCLK_TCK) | + (PIN_SWDIO_TMS_IN() << DAP_SWJ_SWDIO_TMS) | + (PIN_TDI_IN() << DAP_SWJ_TDI) | + (PIN_TDO_IN() << DAP_SWJ_TDO) | + (PIN_nTRST_IN() << DAP_SWJ_nTRST) | + (PIN_nRESET_IN() << DAP_SWJ_nRESET); + + *response = (uint8_t)value; +#else + *response = 0U; +#endif + + return ((6U << 16) | 1U); +} + + +// Process SWJ Clock command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) { +#if ((DAP_SWD != 0) || (DAP_JTAG != 0)) + uint32_t clock; + uint32_t delay; + + clock = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + + if (clock == 0U) { + *response = DAP_ERROR; + return ((4U << 16) | 1U); + } + + Set_Clock_Delay(clock); + + *response = DAP_OK; +#else + *response = DAP_ERROR; +#endif + + return ((4U << 16) | 1U); +} + + +// Process SWJ Sequence command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_SWJ_Sequence(const uint8_t *request, uint8_t *response) { + uint32_t count; + + count = *request++; + if (count == 0U) { + count = 256U; + } + +#if ((DAP_SWD != 0) || (DAP_JTAG != 0)) + SWJ_Sequence(count, request); + *response = DAP_OK; +#else + *response = DAP_ERROR; +#endif + + count = (count + 7U) >> 3; + + return (((count + 1U) << 16) | 1U); +} + + +// Process SWD Configure command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_SWD_Configure(const uint8_t *request, uint8_t *response) { +#if (DAP_SWD != 0) + uint8_t value; + + value = *request; + DAP_Data.swd_conf.turnaround = (value & 0x03U) + 1U; + DAP_Data.swd_conf.data_phase = (value & 0x04U) ? 1U : 0U; + + *response = DAP_OK; +#else + *response = DAP_ERROR; +#endif + + return ((1U << 16) | 1U); +} + + +// Process SWD Sequence command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_SWD_Sequence(const uint8_t *request, uint8_t *response) { + uint32_t sequence_info; + uint32_t sequence_count; + uint32_t request_count; + uint32_t response_count; + uint32_t count; + +#if (DAP_SWD != 0) + *response++ = DAP_OK; +#else + *response++ = DAP_ERROR; +#endif + request_count = 1U; + response_count = 1U; + + sequence_count = *request++; + while (sequence_count--) { + sequence_info = *request++; + count = sequence_info & SWD_SEQUENCE_CLK; + if (count == 0U) { + count = 64U; + } + count = (count + 7U) / 8U; +#if (DAP_SWD != 0) + if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { + PIN_SWDIO_OUT_DISABLE(); + } else { + PIN_SWDIO_OUT_ENABLE(); + } + SWD_Sequence(sequence_info, request, response); + if (sequence_count == 0U) { + PIN_SWDIO_OUT_ENABLE(); + } +#endif + if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) { + request_count++; +#if (DAP_SWD != 0) + response += count; + response_count += count; +#endif + } else { + request += count; + request_count += count + 1U; + } + } + + return ((request_count << 16) | response_count); +} + + +// Process JTAG Sequence command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_JTAG_Sequence(const uint8_t *request, uint8_t *response) { + uint32_t sequence_info; + uint32_t sequence_count; + uint32_t request_count; + uint32_t response_count; + uint32_t count; + +#if (DAP_JTAG != 0) + *response++ = DAP_OK; +#else + *response++ = DAP_ERROR; +#endif + request_count = 1U; + response_count = 1U; + + sequence_count = *request++; + while (sequence_count--) { + sequence_info = *request++; + count = sequence_info & JTAG_SEQUENCE_TCK; + if (count == 0U) { + count = 64U; + } + count = (count + 7U) / 8U; +#if (DAP_JTAG != 0) + JTAG_Sequence(sequence_info, request, response); +#endif + request += count; + request_count += count + 1U; +#if (DAP_JTAG != 0) + if ((sequence_info & JTAG_SEQUENCE_TDO) != 0U) { + response += count; + response_count += count; + } +#endif + } + + return ((request_count << 16) | response_count); +} + + +// Process JTAG Configure command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_JTAG_Configure(const uint8_t *request, uint8_t *response) { + uint32_t count; +#if (DAP_JTAG != 0) + uint32_t length; + uint32_t bits; + uint32_t n; + + count = *request++; + DAP_Data.jtag_dev.count = (uint8_t)count; + + bits = 0U; + for (n = 0U; n < count; n++) { + length = *request++; + DAP_Data.jtag_dev.ir_length[n] = (uint8_t)length; + DAP_Data.jtag_dev.ir_before[n] = (uint16_t)bits; + bits += length; + } + for (n = 0U; n < count; n++) { + bits -= DAP_Data.jtag_dev.ir_length[n]; + DAP_Data.jtag_dev.ir_after[n] = (uint16_t)bits; + } + + *response = DAP_OK; +#else + count = *request; + *response = DAP_ERROR; +#endif + + return (((count + 1U) << 16) | 1U); +} + + +// Process JTAG IDCODE command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_JTAG_IDCode(const uint8_t *request, uint8_t *response) { +#if (DAP_JTAG != 0) + uint32_t data; + + if (DAP_Data.debug_port != DAP_PORT_JTAG) { + goto id_error; + } + + // Device index (JTAP TAP) + DAP_Data.jtag_dev.index = *request; + if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) { + goto id_error; + } + + // Select JTAG chain + JTAG_IR(JTAG_IDCODE); + + // Read IDCODE register + data = JTAG_ReadIDCode(); + + // Store Data + *(response+0) = DAP_OK; + *(response+1) = (uint8_t)(data >> 0); + *(response+2) = (uint8_t)(data >> 8); + *(response+3) = (uint8_t)(data >> 16); + *(response+4) = (uint8_t)(data >> 24); + + return ((1U << 16) | 5U); + +id_error: +#endif + *response = DAP_ERROR; + return ((1U << 16) | 1U); +} + + +// Process Transfer Configure command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_TransferConfigure(const uint8_t *request, uint8_t *response) { + + DAP_Data.transfer.idle_cycles = *(request+0); + DAP_Data.transfer.retry_count = (uint16_t) *(request+1) | + (uint16_t)(*(request+2) << 8); + DAP_Data.transfer.match_retry = (uint16_t) *(request+3) | + (uint16_t)(*(request+4) << 8); + + *response = DAP_OK; + return ((5U << 16) | 1U); +} + + +// Process SWD Transfer command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +#if (DAP_SWD != 0) +static uint32_t DAP_SWD_Transfer(const uint8_t *request, uint8_t *response) { + const + uint8_t *request_head; + uint32_t request_count; + uint32_t request_value; + uint8_t *response_head; + uint32_t response_count; + uint32_t response_value; + uint32_t post_read; + uint32_t check_write; + uint32_t match_value; + uint32_t match_retry; + uint32_t retry; + uint32_t data; +#if (TIMESTAMP_CLOCK != 0U) + uint32_t timestamp; +#endif + + request_head = request; + + response_count = 0U; + response_value = 0U; + response_head = response; + response += 2; + + DAP_TransferAbort = 0U; + + post_read = 0U; + check_write = 0U; + + request++; // Ignore DAP index + + request_count = *request++; + + for (; request_count != 0U; request_count--) { + request_value = *request++; + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Read register + if (post_read) { + // Read was posted before + retry = DAP_Data.transfer.retry_count; + if ((request_value & (DAP_TRANSFER_APnDP | DAP_TRANSFER_MATCH_VALUE)) == DAP_TRANSFER_APnDP) { + // Read previous AP data and post next AP read + do { + response_value = SWD_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + } else { + // Read previous AP data + do { + response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + post_read = 0U; + } + if (response_value != DAP_TRANSFER_OK) { + break; + } + // Store previous AP data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); +#if (TIMESTAMP_CLOCK != 0U) + if (post_read) { + // Store Timestamp of next AP read + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } + } +#endif + } + if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) { + // Read with value match + match_value = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + request += 4; + match_retry = DAP_Data.transfer.match_retry; + if ((request_value & DAP_TRANSFER_APnDP) != 0U) { + // Post AP read + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(request_value, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } + } + do { + // Read register until its value matches or retry counter expires + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } + } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort); + if ((data & DAP_Data.transfer.match_mask) != match_value) { + response_value |= DAP_TRANSFER_MISMATCH; + } + if (response_value != DAP_TRANSFER_OK) { + break; + } + } else { + // Normal read + retry = DAP_Data.transfer.retry_count; + if ((request_value & DAP_TRANSFER_APnDP) != 0U) { + // Read AP register + if (post_read == 0U) { + // Post AP read + do { + response_value = SWD_Transfer(request_value, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } +#if (TIMESTAMP_CLOCK != 0U) + // Store Timestamp + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } +#endif + post_read = 1U; + } + } else { + // Read DP register + do { + response_value = SWD_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } +#if (TIMESTAMP_CLOCK != 0U) + // Store Timestamp + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } +#endif + // Store data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + } + } + check_write = 0U; + } else { + // Write register + if (post_read) { + // Read previous data + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } + // Store previous data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + post_read = 0U; + } + // Load data + data = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + request += 4; + if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) { + // Write match mask + DAP_Data.transfer.match_mask = data; + response_value = DAP_TRANSFER_OK; + } else { + // Write DP/AP register + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } +#if (TIMESTAMP_CLOCK != 0U) + // Store Timestamp + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } +#endif + check_write = 1U; + } + } + response_count++; + if (DAP_TransferAbort) { + break; + } + } + + for (; request_count != 0U; request_count--) { + // Process canceled requests + request_value = *request++; + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Read register + if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) { + // Read with value match + request += 4; + } + } else { + // Write register + request += 4; + } + } + + if (response_value == DAP_TRANSFER_OK) { + if (post_read) { + // Read previous data + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + // Store previous data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + } else if (check_write) { + // Check last write + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + } + } + +end: + *(response_head+0) = (uint8_t)response_count; + *(response_head+1) = (uint8_t)response_value; + + return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head)); +} +#endif + + +// Process JTAG Transfer command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +#if (DAP_JTAG != 0) +static uint32_t DAP_JTAG_Transfer(const uint8_t *request, uint8_t *response) { + const + uint8_t *request_head; + uint32_t request_count; + uint32_t request_value; + uint32_t request_ir; + uint8_t *response_head; + uint32_t response_count; + uint32_t response_value; + uint32_t post_read; + uint32_t match_value; + uint32_t match_retry; + uint32_t retry; + uint32_t data; + uint32_t ir; +#if (TIMESTAMP_CLOCK != 0U) + uint32_t timestamp; +#endif + + request_head = request; + + response_count = 0U; + response_value = 0U; + response_head = response; + response += 2; + + DAP_TransferAbort = 0U; + + ir = 0U; + post_read = 0U; + + // Device index (JTAP TAP) + DAP_Data.jtag_dev.index = *request++; + if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) { + goto end; + } + + request_count = *request++; + + for (; request_count != 0U; request_count--) { + request_value = *request++; + request_ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC; + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Read register + if (post_read) { + // Read was posted before + retry = DAP_Data.transfer.retry_count; + if ((ir == request_ir) && ((request_value & DAP_TRANSFER_MATCH_VALUE) == 0U)) { + // Read previous data and post next read + do { + response_value = JTAG_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + } else { + // Select JTAG chain + if (ir != JTAG_DPACC) { + ir = JTAG_DPACC; + JTAG_IR(ir); + } + // Read previous data + do { + response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + post_read = 0U; + } + if (response_value != DAP_TRANSFER_OK) { + break; + } + // Store previous data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); +#if (TIMESTAMP_CLOCK != 0U) + if (post_read) { + // Store Timestamp of next AP read + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } + } +#endif + } + if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) { + // Read with value match + match_value = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + request += 4; + match_retry = DAP_Data.transfer.match_retry; + // Select JTAG chain + if (ir != request_ir) { + ir = request_ir; + JTAG_IR(ir); + } + // Post DP/AP read + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } + do { + // Read register until its value matches or retry counter expires + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } + } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort); + if ((data & DAP_Data.transfer.match_mask) != match_value) { + response_value |= DAP_TRANSFER_MISMATCH; + } + if (response_value != DAP_TRANSFER_OK) { + break; + } + } else { + // Normal read + if (post_read == 0U) { + // Select JTAG chain + if (ir != request_ir) { + ir = request_ir; + JTAG_IR(ir); + } + // Post DP/AP read + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } +#if (TIMESTAMP_CLOCK != 0U) + // Store Timestamp + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } +#endif + post_read = 1U; + } + } + } else { + // Write register + if (post_read) { + // Select JTAG chain + if (ir != JTAG_DPACC) { + ir = JTAG_DPACC; + JTAG_IR(ir); + } + // Read previous data + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } + // Store previous data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + post_read = 0U; + } + // Load data + data = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + request += 4; + if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) { + // Write match mask + DAP_Data.transfer.match_mask = data; + response_value = DAP_TRANSFER_OK; + } else { + // Select JTAG chain + if (ir != request_ir) { + ir = request_ir; + JTAG_IR(ir); + } + // Write DP/AP register + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + break; + } +#if (TIMESTAMP_CLOCK != 0U) + // Store Timestamp + if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) { + timestamp = DAP_Data.timestamp; + *response++ = (uint8_t) timestamp; + *response++ = (uint8_t)(timestamp >> 8); + *response++ = (uint8_t)(timestamp >> 16); + *response++ = (uint8_t)(timestamp >> 24); + } +#endif + } + } + response_count++; + if (DAP_TransferAbort) { + break; + } + } + + for (; request_count != 0U; request_count--) { + // Process canceled requests + request_value = *request++; + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Read register + if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) { + // Read with value match + request += 4; + } + } else { + // Write register + request += 4; + } + } + + if (response_value == DAP_TRANSFER_OK) { + // Select JTAG chain + if (ir != JTAG_DPACC) { + ir = JTAG_DPACC; + JTAG_IR(ir); + } + if (post_read) { + // Read previous data + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + // Store previous data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + } else { + // Check last write + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + } + } + +end: + *(response_head+0) = (uint8_t)response_count; + *(response_head+1) = (uint8_t)response_value; + + return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head)); +} +#endif + + +// Process Dummy Transfer command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_Dummy_Transfer(const uint8_t *request, uint8_t *response) { + const + uint8_t *request_head; + uint32_t request_count; + uint32_t request_value; + + request_head = request; + + request++; // Ignore DAP index + + request_count = *request++; + + for (; request_count != 0U; request_count--) { + // Process dummy requests + request_value = *request++; + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Read register + if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) { + // Read with value match + request += 4; + } + } else { + // Write register + request += 4; + } + } + + *(response+0) = 0U; // Response count + *(response+1) = 0U; // Response value + + return (((uint32_t)(request - request_head) << 16) | 2U); +} + + +// Process Transfer command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_Transfer(const uint8_t *request, uint8_t *response) { + uint32_t num; + + switch (DAP_Data.debug_port) { +#if (DAP_SWD != 0) + case DAP_PORT_SWD: + num = DAP_SWD_Transfer(request, response); + break; +#endif +#if (DAP_JTAG != 0) + case DAP_PORT_JTAG: + num = DAP_JTAG_Transfer(request, response); + break; +#endif + default: + num = DAP_Dummy_Transfer(request, response); + break; + } + + return (num); +} + + +// Process SWD Transfer Block command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response +#if (DAP_SWD != 0) +static uint32_t DAP_SWD_TransferBlock(const uint8_t *request, uint8_t *response) { + uint32_t request_count; + uint32_t request_value; + uint32_t response_count; + uint32_t response_value; + uint8_t *response_head; + uint32_t retry; + uint32_t data; + + response_count = 0U; + response_value = 0U; + response_head = response; + response += 3; + + DAP_TransferAbort = 0U; + + request++; // Ignore DAP index + + request_count = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8); + request += 2; + if (request_count == 0U) { + goto end; + } + + request_value = *request++; + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Read register block + if ((request_value & DAP_TRANSFER_APnDP) != 0U) { + // Post AP read + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(request_value, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + } + while (request_count--) { + // Read DP/AP register + if ((request_count == 0U) && ((request_value & DAP_TRANSFER_APnDP) != 0U)) { + // Last AP read + request_value = DP_RDBUFF | DAP_TRANSFER_RnW; + } + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + // Store data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + response_count++; + } + } else { + // Write register block + while (request_count--) { + // Load data + data = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + request += 4; + // Write DP/AP register + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + response_count++; + } + // Check last write + retry = DAP_Data.transfer.retry_count; + do { + response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + } + +end: + *(response_head+0) = (uint8_t)(response_count >> 0); + *(response_head+1) = (uint8_t)(response_count >> 8); + *(response_head+2) = (uint8_t) response_value; + + return ((uint32_t)(response - response_head)); +} +#endif + + +// Process JTAG Transfer Block command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response +#if (DAP_JTAG != 0) +static uint32_t DAP_JTAG_TransferBlock(const uint8_t *request, uint8_t *response) { + uint32_t request_count; + uint32_t request_value; + uint32_t response_count; + uint32_t response_value; + uint8_t *response_head; + uint32_t retry; + uint32_t data; + uint32_t ir; + + response_count = 0U; + response_value = 0U; + response_head = response; + response += 3; + + DAP_TransferAbort = 0U; + + // Device index (JTAP TAP) + DAP_Data.jtag_dev.index = *request++; + if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) { + goto end; + } + + request_count = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8); + request += 2; + if (request_count == 0U) { + goto end; + } + + request_value = *request++; + + // Select JTAG chain + ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC; + JTAG_IR(ir); + + if ((request_value & DAP_TRANSFER_RnW) != 0U) { + // Post read + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + // Read register block + while (request_count--) { + // Read DP/AP register + if (request_count == 0U) { + // Last read + if (ir != JTAG_DPACC) { + JTAG_IR(JTAG_DPACC); + } + request_value = DP_RDBUFF | DAP_TRANSFER_RnW; + } + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + // Store data + *response++ = (uint8_t) data; + *response++ = (uint8_t)(data >> 8); + *response++ = (uint8_t)(data >> 16); + *response++ = (uint8_t)(data >> 24); + response_count++; + } + } else { + // Write register block + while (request_count--) { + // Load data + data = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + request += 4; + // Write DP/AP register + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(request_value, &data); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + if (response_value != DAP_TRANSFER_OK) { + goto end; + } + response_count++; + } + // Check last write + if (ir != JTAG_DPACC) { + JTAG_IR(JTAG_DPACC); + } + retry = DAP_Data.transfer.retry_count; + do { + response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL); + } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort); + } + +end: + *(response_head+0) = (uint8_t)(response_count >> 0); + *(response_head+1) = (uint8_t)(response_count >> 8); + *(response_head+2) = (uint8_t) response_value; + + return ((uint32_t)(response - response_head)); +} +#endif + + +// Process Transfer Block command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_TransferBlock(const uint8_t *request, uint8_t *response) { + uint32_t num; + + switch (DAP_Data.debug_port) { +#if (DAP_SWD != 0) + case DAP_PORT_SWD: + num = DAP_SWD_TransferBlock (request, response); + break; +#endif +#if (DAP_JTAG != 0) + case DAP_PORT_JTAG: + num = DAP_JTAG_TransferBlock(request, response); + break; +#endif + default: + *(response+0) = 0U; // Response count [7:0] + *(response+1) = 0U; // Response count[15:8] + *(response+2) = 0U; // Response value + num = 3U; + break; + } + + if ((*(request+3) & DAP_TRANSFER_RnW) != 0U) { + // Read register block + num |= 4U << 16; + } else { + // Write register block + num |= (4U + (((uint32_t)(*(request+1)) | (uint32_t)(*(request+2) << 8)) * 4)) << 16; + } + + return (num); +} + + +// Process SWD Write ABORT command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response +#if (DAP_SWD != 0) +static uint32_t DAP_SWD_WriteAbort(const uint8_t *request, uint8_t *response) { + uint32_t data; + + // Load data (Ignore DAP index) + data = (uint32_t)(*(request+1) << 0) | + (uint32_t)(*(request+2) << 8) | + (uint32_t)(*(request+3) << 16) | + (uint32_t)(*(request+4) << 24); + + // Write Abort register + SWD_Transfer(DP_ABORT, &data); + + *response = DAP_OK; + return (1U); +} +#endif + + +// Process JTAG Write ABORT command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response +#if (DAP_JTAG != 0) +static uint32_t DAP_JTAG_WriteAbort(const uint8_t *request, uint8_t *response) { + uint32_t data; + + // Device index (JTAP TAP) + DAP_Data.jtag_dev.index = *request; + if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) { + *response = DAP_ERROR; + return (1U); + } + + // Select JTAG chain + JTAG_IR(JTAG_ABORT); + + // Load data + data = (uint32_t)(*(request+1) << 0) | + (uint32_t)(*(request+2) << 8) | + (uint32_t)(*(request+3) << 16) | + (uint32_t)(*(request+4) << 24); + + // Write Abort register + JTAG_WriteAbort(data); + + *response = DAP_OK; + return (1U); +} +#endif + + +// Process Write ABORT command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +static uint32_t DAP_WriteAbort(const uint8_t *request, uint8_t *response) { + uint32_t num; + + switch (DAP_Data.debug_port) { +#if (DAP_SWD != 0) + case DAP_PORT_SWD: + num = DAP_SWD_WriteAbort (request, response); + break; +#endif +#if (DAP_JTAG != 0) + case DAP_PORT_JTAG: + num = DAP_JTAG_WriteAbort(request, response); + break; +#endif + default: + *response = DAP_ERROR; + num = 1U; + break; + } + return ((5U << 16) | num); +} + + +// Process DAP Vendor command request and prepare response +// Default function (can be overridden) +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +__WEAK uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) { + (void)request; + *response = ID_DAP_Invalid; + return ((1U << 16) | 1U); +} + + +// Process DAP command request and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t DAP_ProcessCommand(const uint8_t *request, uint8_t *response) { + uint32_t num; + + if ((*request >= ID_DAP_Vendor0) && (*request <= ID_DAP_Vendor31)) { + return DAP_ProcessVendorCommand(request, response); + } + + *response++ = *request; + + switch (*request++) { + case ID_DAP_Info: + num = DAP_Info(*request, response+1); + *response = (uint8_t)num; + return ((2U << 16) + 2U + num); + + case ID_DAP_HostStatus: + num = DAP_HostStatus(request, response); + break; + + case ID_DAP_Connect: + num = DAP_Connect(request, response); + break; + case ID_DAP_Disconnect: + num = DAP_Disconnect(response); + break; + + case ID_DAP_Delay: + num = DAP_Delay(request, response); + break; + + case ID_DAP_ResetTarget: + num = DAP_ResetTarget(response); + break; + + case ID_DAP_SWJ_Pins: + num = DAP_SWJ_Pins(request, response); + break; + case ID_DAP_SWJ_Clock: + num = DAP_SWJ_Clock(request, response); + break; + case ID_DAP_SWJ_Sequence: + num = DAP_SWJ_Sequence(request, response); + break; + + case ID_DAP_SWD_Configure: + num = DAP_SWD_Configure(request, response); + break; + case ID_DAP_SWD_Sequence: + num = DAP_SWD_Sequence(request, response); + break; + + case ID_DAP_JTAG_Sequence: + num = DAP_JTAG_Sequence(request, response); + break; + case ID_DAP_JTAG_Configure: + num = DAP_JTAG_Configure(request, response); + break; + case ID_DAP_JTAG_IDCODE: + num = DAP_JTAG_IDCode(request, response); + break; + + case ID_DAP_TransferConfigure: + num = DAP_TransferConfigure(request, response); + break; + case ID_DAP_Transfer: + num = DAP_Transfer(request, response); + break; + case ID_DAP_TransferBlock: + num = DAP_TransferBlock(request, response); + break; + + case ID_DAP_WriteABORT: + num = DAP_WriteAbort(request, response); + break; + +#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) + case ID_DAP_SWO_Transport: + num = SWO_Transport(request, response); + break; + case ID_DAP_SWO_Mode: + num = SWO_Mode(request, response); + break; + case ID_DAP_SWO_Baudrate: + num = SWO_Baudrate(request, response); + break; + case ID_DAP_SWO_Control: + num = SWO_Control(request, response); + break; + case ID_DAP_SWO_Status: + num = SWO_Status(response); + break; + case ID_DAP_SWO_ExtendedStatus: + num = SWO_ExtendedStatus(request, response); + break; + case ID_DAP_SWO_Data: + num = SWO_Data(request, response); + break; +#endif + +#if (DAP_UART != 0) + case ID_DAP_UART_Transport: + num = UART_Transport(request, response); + break; + case ID_DAP_UART_Configure: + num = UART_Configure(request, response); + break; + case ID_DAP_UART_Control: + num = UART_Control(request, response); + break; + case ID_DAP_UART_Status: + num = UART_Status(response); + break; + case ID_DAP_UART_Transfer: + num = UART_Transfer(request, response); + break; +#endif + + default: + *(response-1) = ID_DAP_Invalid; + return ((1U << 16) | 1U); + } + + return ((1U << 16) + 1U + num); +} + + +// Execute DAP command (process request and prepare response) +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t DAP_ExecuteCommand(const uint8_t *request, uint8_t *response) { + uint32_t cnt, num, n; + + if (*request == ID_DAP_ExecuteCommands) { + *response++ = *request++; + cnt = *request++; + *response++ = (uint8_t)cnt; + num = (2U << 16) | 2U; + while (cnt--) { + n = DAP_ProcessCommand(request, response); + num += n; + request += (uint16_t)(n >> 16); + response += (uint16_t) n; + } + return (num); + } + + return DAP_ProcessCommand(request, response); +} + + +// Setup DAP +void DAP_Setup(void) { + + // Default settings + DAP_Data.debug_port = 0U; + DAP_Data.transfer.idle_cycles = 0U; + DAP_Data.transfer.retry_count = 100U; + DAP_Data.transfer.match_retry = 0U; + DAP_Data.transfer.match_mask = 0x00000000U; +#if (DAP_SWD != 0) + DAP_Data.swd_conf.turnaround = 1U; + DAP_Data.swd_conf.data_phase = 0U; +#endif +#if (DAP_JTAG != 0) + DAP_Data.jtag_dev.count = 0U; +#endif + + // Sets DAP_Data.fast_clock and DAP_Data.clock_delay. + Set_Clock_Delay(DAP_DEFAULT_SWJ_CLOCK); + + DAP_SETUP(); // Device specific setup +} diff --git a/Drivers/CMSIS/DAP/Firmware/Source/DAP_vendor.c b/Drivers/CMSIS/DAP/Firmware/Source/DAP_vendor.c new file mode 100644 index 0000000..2d8b486 --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Source/DAP_vendor.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. December 2017 + * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Source + * Title: DAP_vendor.c CMSIS-DAP Vendor Commands + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" + +//************************************************************************************************** +/** +\defgroup DAP_Vendor_Adapt_gr Adapt Vendor Commands +\ingroup DAP_Vendor_gr +@{ + +The file DAP_vendor.c provides template source code for extension of a Debug Unit with +Vendor Commands. Copy this file to the project folder of the Debug Unit and add the +file to the MDK-ARM project under the file group Configuration. +*/ + +/** Process DAP Vendor Command and prepare Response Data +\param request pointer to request data +\param response pointer to response data +\return number of bytes in response (lower 16 bits) + number of bytes in request (upper 16 bits) +*/ +uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) { + uint32_t num = (1U << 16) | 1U; + + *response++ = *request; // copy Command ID + + switch (*request++) { // first byte in request is Command ID + case ID_DAP_Vendor0: +#if 0 // example user command + num += 1U << 16; // increment request count + if (*request == 1U) { // when first command data byte is 1 + *response++ = 'X'; // send 'X' as response + num++; // increment response count + } +#endif + break; + + case ID_DAP_Vendor1: break; + case ID_DAP_Vendor2: break; + case ID_DAP_Vendor3: break; + case ID_DAP_Vendor4: break; + case ID_DAP_Vendor5: break; + case ID_DAP_Vendor6: break; + case ID_DAP_Vendor7: break; + case ID_DAP_Vendor8: break; + case ID_DAP_Vendor9: break; + case ID_DAP_Vendor10: break; + case ID_DAP_Vendor11: break; + case ID_DAP_Vendor12: break; + case ID_DAP_Vendor13: break; + case ID_DAP_Vendor14: break; + case ID_DAP_Vendor15: break; + case ID_DAP_Vendor16: break; + case ID_DAP_Vendor17: break; + case ID_DAP_Vendor18: break; + case ID_DAP_Vendor19: break; + case ID_DAP_Vendor20: break; + case ID_DAP_Vendor21: break; + case ID_DAP_Vendor22: break; + case ID_DAP_Vendor23: break; + case ID_DAP_Vendor24: break; + case ID_DAP_Vendor25: break; + case ID_DAP_Vendor26: break; + case ID_DAP_Vendor27: break; + case ID_DAP_Vendor28: break; + case ID_DAP_Vendor29: break; + case ID_DAP_Vendor30: break; + case ID_DAP_Vendor31: break; + } + + return (num); +} + +///@} diff --git a/Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c b/Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c new file mode 100644 index 0000000..1bb89e5 --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. December 2017 + * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Source + * Title: JTAG_DP.c CMSIS-DAP JTAG DP I/O + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" + + +// JTAG Macros + +#define PIN_TCK_SET PIN_SWCLK_TCK_SET +#define PIN_TCK_CLR PIN_SWCLK_TCK_CLR +#define PIN_TMS_SET PIN_SWDIO_TMS_SET +#define PIN_TMS_CLR PIN_SWDIO_TMS_CLR + +#define JTAG_CYCLE_TCK() \ + PIN_TCK_CLR(); \ + PIN_DELAY(); \ + PIN_TCK_SET(); \ + PIN_DELAY() + +#define JTAG_CYCLE_TDI(tdi) \ + PIN_TDI_OUT(tdi); \ + PIN_TCK_CLR(); \ + PIN_DELAY(); \ + PIN_TCK_SET(); \ + PIN_DELAY() + +#define JTAG_CYCLE_TDO(tdo) \ + PIN_TCK_CLR(); \ + PIN_DELAY(); \ + tdo = PIN_TDO_IN(); \ + PIN_TCK_SET(); \ + PIN_DELAY() + +#define JTAG_CYCLE_TDIO(tdi,tdo) \ + PIN_TDI_OUT(tdi); \ + PIN_TCK_CLR(); \ + PIN_DELAY(); \ + tdo = PIN_TDO_IN(); \ + PIN_TCK_SET(); \ + PIN_DELAY() + +#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) + + +#if (DAP_JTAG != 0) + + +// Generate JTAG Sequence +// info: sequence information +// tdi: pointer to TDI generated data +// tdo: pointer to TDO captured data +// return: none +void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) { + uint32_t i_val; + uint32_t o_val; + uint32_t bit; + uint32_t n, k; + + n = info & JTAG_SEQUENCE_TCK; + if (n == 0U) { + n = 64U; + } + + if (info & JTAG_SEQUENCE_TMS) { + PIN_TMS_SET(); + } else { + PIN_TMS_CLR(); + } + + while (n) { + i_val = *tdi++; + o_val = 0U; + for (k = 8U; k && n; k--, n--) { + JTAG_CYCLE_TDIO(i_val, bit); + i_val >>= 1; + o_val >>= 1; + o_val |= bit << 7; + } + o_val >>= k; + if (info & JTAG_SEQUENCE_TDO) { + *tdo++ = (uint8_t)o_val; + } + } +} + + +// JTAG Set IR +// ir: IR value +// return: none +#define JTAG_IR_Function(speed) /**/ \ +static void JTAG_IR_##speed (uint32_t ir) { \ + uint32_t n; \ + \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ + JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \ + PIN_TMS_CLR(); \ + JTAG_CYCLE_TCK(); /* Capture-IR */ \ + JTAG_CYCLE_TCK(); /* Shift-IR */ \ + \ + PIN_TDI_OUT(1U); \ + for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \ + JTAG_CYCLE_TCK(); /* Bypass before data */ \ + } \ + for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \ + JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \ + ir >>= 1; \ + } \ + n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \ + if (n) { \ + JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \ + PIN_TDI_OUT(1U); \ + for (--n; n; n--) { \ + JTAG_CYCLE_TCK(); /* Bypass after data */ \ + } \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \ + } else { \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \ + } \ + \ + JTAG_CYCLE_TCK(); /* Update-IR */ \ + PIN_TMS_CLR(); \ + JTAG_CYCLE_TCK(); /* Idle */ \ + PIN_TDI_OUT(1U); \ +} + + +// JTAG Transfer I/O +// request: A[3:2] RnW APnDP +// data: DATA[31:0] +// return: ACK[2:0] +#define JTAG_TransferFunction(speed) /**/ \ +static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \ + uint32_t ack; \ + uint32_t bit; \ + uint32_t val; \ + uint32_t n; \ + \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \ + PIN_TMS_CLR(); \ + JTAG_CYCLE_TCK(); /* Capture-DR */ \ + JTAG_CYCLE_TCK(); /* Shift-DR */ \ + \ + for (n = DAP_Data.jtag_dev.index; n; n--) { \ + JTAG_CYCLE_TCK(); /* Bypass before data */ \ + } \ + \ + JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \ + ack = bit << 1; \ + JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \ + ack |= bit << 0; \ + JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \ + ack |= bit << 2; \ + \ + if (ack != DAP_TRANSFER_OK) { \ + /* Exit on error */ \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TCK(); /* Exit1-DR */ \ + goto exit; \ + } \ + \ + if (request & DAP_TRANSFER_RnW) { \ + /* Read Transfer */ \ + val = 0U; \ + for (n = 31U; n; n--) { \ + JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \ + val |= bit << 31; \ + val >>= 1; \ + } \ + n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ + if (n) { \ + JTAG_CYCLE_TDO(bit); /* Get D31 */ \ + for (--n; n; n--) { \ + JTAG_CYCLE_TCK(); /* Bypass after data */ \ + } \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ + } else { \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \ + } \ + val |= bit << 31; \ + if (data) { *data = val; } \ + } else { \ + /* Write Transfer */ \ + val = *data; \ + for (n = 31U; n; n--) { \ + JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \ + val >>= 1; \ + } \ + n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \ + if (n) { \ + JTAG_CYCLE_TDI(val); /* Set D31 */ \ + for (--n; n; n--) { \ + JTAG_CYCLE_TCK(); /* Bypass after data */ \ + } \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \ + } else { \ + PIN_TMS_SET(); \ + JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \ + } \ + } \ + \ +exit: \ + JTAG_CYCLE_TCK(); /* Update-DR */ \ + PIN_TMS_CLR(); \ + JTAG_CYCLE_TCK(); /* Idle */ \ + PIN_TDI_OUT(1U); \ + \ + /* Capture Timestamp */ \ + if (request & DAP_TRANSFER_TIMESTAMP) { \ + DAP_Data.timestamp = TIMESTAMP_GET(); \ + } \ + \ + /* Idle cycles */ \ + n = DAP_Data.transfer.idle_cycles; \ + while (n--) { \ + JTAG_CYCLE_TCK(); /* Idle */ \ + } \ + \ + return ((uint8_t)ack); \ +} + + +#undef PIN_DELAY +#define PIN_DELAY() PIN_DELAY_FAST() +JTAG_IR_Function(Fast) +JTAG_TransferFunction(Fast) + +#undef PIN_DELAY +#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) +JTAG_IR_Function(Slow) +JTAG_TransferFunction(Slow) + + +// JTAG Read IDCODE register +// return: value read +uint32_t JTAG_ReadIDCode (void) { + uint32_t bit; + uint32_t val; + uint32_t n; + + PIN_TMS_SET(); + JTAG_CYCLE_TCK(); /* Select-DR-Scan */ + PIN_TMS_CLR(); + JTAG_CYCLE_TCK(); /* Capture-DR */ + JTAG_CYCLE_TCK(); /* Shift-DR */ + + for (n = DAP_Data.jtag_dev.index; n; n--) { + JTAG_CYCLE_TCK(); /* Bypass before data */ + } + + val = 0U; + for (n = 31U; n; n--) { + JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ + val |= bit << 31; + val >>= 1; + } + PIN_TMS_SET(); + JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ + val |= bit << 31; + + JTAG_CYCLE_TCK(); /* Update-DR */ + PIN_TMS_CLR(); + JTAG_CYCLE_TCK(); /* Idle */ + + return (val); +} + + +// JTAG Write ABORT register +// data: value to write +// return: none +void JTAG_WriteAbort (uint32_t data) { + uint32_t n; + + PIN_TMS_SET(); + JTAG_CYCLE_TCK(); /* Select-DR-Scan */ + PIN_TMS_CLR(); + JTAG_CYCLE_TCK(); /* Capture-DR */ + JTAG_CYCLE_TCK(); /* Shift-DR */ + + for (n = DAP_Data.jtag_dev.index; n; n--) { + JTAG_CYCLE_TCK(); /* Bypass before data */ + } + + PIN_TDI_OUT(0U); + JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */ + JTAG_CYCLE_TCK(); /* Set A2=0 */ + JTAG_CYCLE_TCK(); /* Set A3=0 */ + + for (n = 31U; n; n--) { + JTAG_CYCLE_TDI(data); /* Set D0..D30 */ + data >>= 1; + } + n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; + if (n) { + JTAG_CYCLE_TDI(data); /* Set D31 */ + for (--n; n; n--) { + JTAG_CYCLE_TCK(); /* Bypass after data */ + } + PIN_TMS_SET(); + JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ + } else { + PIN_TMS_SET(); + JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */ + } + + JTAG_CYCLE_TCK(); /* Update-DR */ + PIN_TMS_CLR(); + JTAG_CYCLE_TCK(); /* Idle */ + PIN_TDI_OUT(1U); +} + + +// JTAG Set IR +// ir: IR value +// return: none +void JTAG_IR (uint32_t ir) { + if (DAP_Data.fast_clock) { + JTAG_IR_Fast(ir); + } else { + JTAG_IR_Slow(ir); + } +} + + +// JTAG Transfer I/O +// request: A[3:2] RnW APnDP +// data: DATA[31:0] +// return: ACK[2:0] +uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) { + if (DAP_Data.fast_clock) { + return JTAG_TransferFast(request, data); + } else { + return JTAG_TransferSlow(request, data); + } +} + + +#endif /* (DAP_JTAG != 0) */ diff --git a/Drivers/CMSIS/DAP/Firmware/Source/SWO.c b/Drivers/CMSIS/DAP/Firmware/Source/SWO.c new file mode 100644 index 0000000..3785921 --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Source/SWO.c @@ -0,0 +1,798 @@ +/* + * Copyright (c) 2013-2021 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 29. March 2021 + * $Revision: V2.0.1 + * + * Project: CMSIS-DAP Source + * Title: SWO.c CMSIS-DAP SWO I/O + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" +#if (SWO_UART != 0) +#include "Driver_USART.h" +#endif +#if (SWO_STREAM != 0) +#include "cmsis_os2.h" +#define osObjectsExternal +#include "osObjects.h" +#endif + +#if (SWO_STREAM != 0) +#ifdef DAP_FW_V1 +#error "SWO Streaming Trace not supported in DAP V1!" +#endif +#endif + +#if (SWO_UART != 0) + +// USART Driver +#define _USART_Driver_(n) Driver_USART##n +#define USART_Driver_(n) _USART_Driver_(n) +extern ARM_DRIVER_USART USART_Driver_(SWO_UART_DRIVER); +#define pUSART (&USART_Driver_(SWO_UART_DRIVER)) + +static uint8_t USART_Ready = 0U; + +#endif /* (SWO_UART != 0) */ + + +#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) + + +#define SWO_STREAM_TIMEOUT 50U /* Stream timeout in ms */ + +#define USB_BLOCK_SIZE 512U /* USB Block Size */ +#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */ + +// Trace State +static uint8_t TraceTransport = 0U; /* Trace Transport */ +static uint8_t TraceMode = 0U; /* Trace Mode */ +static uint8_t TraceStatus = 0U; /* Trace Status without Errors */ +static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */ +static uint8_t TraceError_n = 0U; /* Active Trace Error bank */ + +// Trace Buffer +static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */ +static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */ +static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */ +static volatile uint8_t TraceUpdate; /* Trace Update Flag */ +static uint32_t TraceBlockSize; /* Current Trace Block Size */ + +#if (TIMESTAMP_CLOCK != 0U) +// Trace Timestamp +static volatile struct { + uint32_t index; + uint32_t tick; +} TraceTimestamp; +#endif + +// Trace Helper functions +static void ClearTrace (void); +static void ResumeTrace (void); +static uint32_t GetTraceCount (void); +static uint8_t GetTraceStatus (void); +static void SetTraceError (uint8_t flag); + +#if (SWO_STREAM != 0) +extern osThreadId_t SWO_ThreadId; +static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */ +static uint32_t TransferSize; /* Current Transfer Size */ +#endif + + +#if (SWO_UART != 0) + +// USART Driver Callback function +// event: event mask +static void USART_Callback (uint32_t event) { + uint32_t index_i; + uint32_t index_o; + uint32_t count; + uint32_t num; + + if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.tick = TIMESTAMP_GET(); +#endif + index_o = TraceIndexO; + index_i = TraceIndexI; + index_i += TraceBlockSize; + TraceIndexI = index_i; +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.index = index_i; +#endif + num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U)); + count = index_i - index_o; + if (count <= (SWO_BUFFER_SIZE - num)) { + index_i &= SWO_BUFFER_SIZE - 1U; + TraceBlockSize = num; + pUSART->Receive(&TraceBuf[index_i], num); + } else { + TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED; + } + TraceUpdate = 1U; +#if (SWO_STREAM != 0) + if (TraceTransport == 2U) { + if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) { + osThreadFlagsSet(SWO_ThreadId, 1U); + } + } +#endif + } + if (event & ARM_USART_EVENT_RX_OVERFLOW) { + SetTraceError(DAP_SWO_BUFFER_OVERRUN); + } + if (event & (ARM_USART_EVENT_RX_BREAK | + ARM_USART_EVENT_RX_FRAMING_ERROR | + ARM_USART_EVENT_RX_PARITY_ERROR)) { + SetTraceError(DAP_SWO_STREAM_ERROR); + } +} + +// Enable or disable SWO Mode (UART) +// enable: enable flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t SWO_Mode_UART (uint32_t enable) { + int32_t status; + + USART_Ready = 0U; + + if (enable != 0U) { + status = pUSART->Initialize(USART_Callback); + if (status != ARM_DRIVER_OK) { + return (0U); + } + status = pUSART->PowerControl(ARM_POWER_FULL); + if (status != ARM_DRIVER_OK) { + pUSART->Uninitialize(); + return (0U); + } + } else { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + pUSART->PowerControl(ARM_POWER_OFF); + pUSART->Uninitialize(); + } + return (1U); +} + +// Configure SWO Baudrate (UART) +// baudrate: requested baudrate +// return: actual baudrate or 0 when not configured +__WEAK uint32_t SWO_Baudrate_UART (uint32_t baudrate) { + int32_t status; + uint32_t index; + uint32_t num; + + if (baudrate > SWO_UART_MAX_BAUDRATE) { + baudrate = SWO_UART_MAX_BAUDRATE; + } + + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + if (pUSART->GetStatus().rx_busy) { + TraceIndexI += pUSART->GetRxCount(); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + } + } + + status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS | + ARM_USART_DATA_BITS_8 | + ARM_USART_PARITY_NONE | + ARM_USART_STOP_BITS_1, + baudrate); + + if (status == ARM_DRIVER_OK) { + USART_Ready = 1U; + } else { + USART_Ready = 0U; + return (0U); + } + + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) { + index = TraceIndexI & (SWO_BUFFER_SIZE - 1U); + num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U)); + TraceBlockSize = num; + pUSART->Receive(&TraceBuf[index], num); + } + pUSART->Control(ARM_USART_CONTROL_RX, 1U); + } + + return (baudrate); +} + +// Control SWO Capture (UART) +// active: active flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t SWO_Control_UART (uint32_t active) { + int32_t status; + + if (active) { + if (!USART_Ready) { + return (0U); + } + TraceBlockSize = 1U; + status = pUSART->Receive(&TraceBuf[0], 1U); + if (status != ARM_DRIVER_OK) { + return (0U); + } + status = pUSART->Control(ARM_USART_CONTROL_RX, 1U); + if (status != ARM_DRIVER_OK) { + return (0U); + } + } else { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + if (pUSART->GetStatus().rx_busy) { + TraceIndexI += pUSART->GetRxCount(); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + } + } + return (1U); +} + +// Start SWO Capture (UART) +// buf: pointer to buffer for capturing +// num: number of bytes to capture +__WEAK void SWO_Capture_UART (uint8_t *buf, uint32_t num) { + TraceBlockSize = num; + pUSART->Receive(buf, num); +} + +// Get SWO Pending Trace Count (UART) +// return: number of pending trace data bytes +__WEAK uint32_t SWO_GetCount_UART (void) { + uint32_t count; + + if (pUSART->GetStatus().rx_busy) { + count = pUSART->GetRxCount(); + } else { + count = 0U; + } + return (count); +} + +#endif /* (SWO_UART != 0) */ + + +#if (SWO_MANCHESTER != 0) + +// Enable or disable SWO Mode (Manchester) +// enable: enable flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t SWO_Mode_Manchester (uint32_t enable) { + return (0U); +} + +// Configure SWO Baudrate (Manchester) +// baudrate: requested baudrate +// return: actual baudrate or 0 when not configured +__WEAK uint32_t SWO_Baudrate_Manchester (uint32_t baudrate) { + return (0U); +} + +// Control SWO Capture (Manchester) +// active: active flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t SWO_Control_Manchester (uint32_t active) { + return (0U); +} + +// Start SWO Capture (Manchester) +// buf: pointer to buffer for capturing +// num: number of bytes to capture +__WEAK void SWO_Capture_Manchester (uint8_t *buf, uint32_t num) { +} + +// Get SWO Pending Trace Count (Manchester) +// return: number of pending trace data bytes +__WEAK uint32_t SWO_GetCount_Manchester (void) { +} + +#endif /* (SWO_MANCHESTER != 0) */ + + +// Clear Trace Errors and Data +static void ClearTrace (void) { + +#if (SWO_STREAM != 0) + if (TraceTransport == 2U) { + if (TransferBusy != 0U) { + SWO_AbortTransfer(); + TransferBusy = 0U; + } + } +#endif + + TraceError[0] = 0U; + TraceError[1] = 0U; + TraceError_n = 0U; + TraceIndexI = 0U; + TraceIndexO = 0U; + +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.index = 0U; + TraceTimestamp.tick = 0U; +#endif +} + +// Resume Trace Capture +static void ResumeTrace (void) { + uint32_t index_i; + uint32_t index_o; + + if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) { + index_i = TraceIndexI; + index_o = TraceIndexO; + if ((index_i - index_o) < SWO_BUFFER_SIZE) { + index_i &= SWO_BUFFER_SIZE - 1U; + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; + SWO_Capture_UART(&TraceBuf[index_i], 1U); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; + SWO_Capture_Manchester(&TraceBuf[index_i], 1U); + break; +#endif + default: + break; + } + } + } +} + +// Get Trace Count +// return: number of available data bytes in trace buffer +static uint32_t GetTraceCount (void) { + uint32_t count; + + if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) { + do { + TraceUpdate = 0U; + count = TraceIndexI - TraceIndexO; + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + count += SWO_GetCount_UART(); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + count += SWO_GetCount_Manchester(); + break; +#endif + default: + break; + } + } while (TraceUpdate != 0U); + } else { + count = TraceIndexI - TraceIndexO; + } + + return (count); +} + +// Get Trace Status (clear Error flags) +// return: Trace Status (Active flag and Error flags) +static uint8_t GetTraceStatus (void) { + uint8_t status; + uint32_t n; + + n = TraceError_n; + TraceError_n ^= 1U; + status = TraceStatus | TraceError[n]; + TraceError[n] = 0U; + + return (status); +} + +// Set Trace Error flag(s) +// flag: error flag(s) to set +static void SetTraceError (uint8_t flag) { + TraceError[TraceError_n] |= flag; +} + + +// Process SWO Transport command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) { + uint8_t transport; + uint32_t result; + + if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) { + transport = *request; + switch (transport) { + case 0U: + case 1U: +#if (SWO_STREAM != 0) + case 2U: +#endif + TraceTransport = transport; + result = 1U; + break; + default: + result = 0U; + break; + } + } else { + result = 0U; + } + + if (result != 0U) { + *response = DAP_OK; + } else { + *response = DAP_ERROR; + } + + return ((1U << 16) | 1U); +} + + +// Process SWO Mode command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) { + uint8_t mode; + uint32_t result; + + mode = *request; + + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + SWO_Mode_UART(0U); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + SWO_Mode_Manchester(0U); + break; +#endif + default: + break; + } + + switch (mode) { + case DAP_SWO_OFF: + result = 1U; + break; +#if (SWO_UART != 0) + case DAP_SWO_UART: + result = SWO_Mode_UART(1U); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + result = SWO_Mode_Manchester(1U); + break; +#endif + default: + result = 0U; + break; + } + if (result != 0U) { + TraceMode = mode; + } else { + TraceMode = DAP_SWO_OFF; + } + + TraceStatus = 0U; + + if (result != 0U) { + *response = DAP_OK; + } else { + *response = DAP_ERROR; + } + + return ((1U << 16) | 1U); +} + + +// Process SWO Baudrate command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) { + uint32_t baudrate; + + baudrate = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + baudrate = SWO_Baudrate_UART(baudrate); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + baudrate = SWO_Baudrate_Manchester(baudrate); + break; +#endif + default: + baudrate = 0U; + break; + } + + if (baudrate == 0U) { + TraceStatus = 0U; + } + + *response++ = (uint8_t)(baudrate >> 0); + *response++ = (uint8_t)(baudrate >> 8); + *response++ = (uint8_t)(baudrate >> 16); + *response = (uint8_t)(baudrate >> 24); + + return ((4U << 16) | 4U); +} + + +// Process SWO Control command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Control (const uint8_t *request, uint8_t *response) { + uint8_t active; + uint32_t result; + + active = *request & DAP_SWO_CAPTURE_ACTIVE; + + if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) { + if (active) { + ClearTrace(); + } + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + result = SWO_Control_UART(active); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + result = SWO_Control_Manchester(active); + break; +#endif + default: + result = 0U; + break; + } + if (result != 0U) { + TraceStatus = active; +#if (SWO_STREAM != 0) + if (TraceTransport == 2U) { + osThreadFlagsSet(SWO_ThreadId, 1U); + } +#endif + } + } else { + result = 1U; + } + + if (result != 0U) { + *response = DAP_OK; + } else { + *response = DAP_ERROR; + } + + return ((1U << 16) | 1U); +} + + +// Process SWO Status command and prepare response +// response: pointer to response data +// return: number of bytes in response +uint32_t SWO_Status (uint8_t *response) { + uint8_t status; + uint32_t count; + + status = GetTraceStatus(); + count = GetTraceCount(); + + *response++ = status; + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); + *response++ = (uint8_t)(count >> 16); + *response = (uint8_t)(count >> 24); + + return (5U); +} + + +// Process SWO Extended Status command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) { + uint8_t cmd; + uint8_t status; + uint32_t count; +#if (TIMESTAMP_CLOCK != 0U) + uint32_t index; + uint32_t tick; +#endif + uint32_t num; + + num = 0U; + cmd = *request; + + if (cmd & 0x01U) { + status = GetTraceStatus(); + *response++ = status; + num += 1U; + } + + if (cmd & 0x02U) { + count = GetTraceCount(); + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); + *response++ = (uint8_t)(count >> 16); + *response++ = (uint8_t)(count >> 24); + num += 4U; + } + +#if (TIMESTAMP_CLOCK != 0U) + if (cmd & 0x04U) { + do { + TraceUpdate = 0U; + index = TraceTimestamp.index; + tick = TraceTimestamp.tick; + } while (TraceUpdate != 0U); + *response++ = (uint8_t)(index >> 0); + *response++ = (uint8_t)(index >> 8); + *response++ = (uint8_t)(index >> 16); + *response++ = (uint8_t)(index >> 24); + *response++ = (uint8_t)(tick >> 0); + *response++ = (uint8_t)(tick >> 8); + *response++ = (uint8_t)(tick >> 16); + *response++ = (uint8_t)(tick >> 24); + num += 4U; + } +#endif + + return ((1U << 16) | num); +} + + +// Process SWO Data command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Data (const uint8_t *request, uint8_t *response) { + uint8_t status; + uint32_t count; + uint32_t index; + uint32_t n, i; + + status = GetTraceStatus(); + count = GetTraceCount(); + + if (TraceTransport == 1U) { + n = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8); + if (n > (DAP_PACKET_SIZE - 4U)) { + n = DAP_PACKET_SIZE - 4U; + } + if (count > n) { + count = n; + } + } else { + count = 0U; + } + + *response++ = status; + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); + + if (TraceTransport == 1U) { + index = TraceIndexO; + for (i = index, n = count; n; n--) { + i &= SWO_BUFFER_SIZE - 1U; + *response++ = TraceBuf[i++]; + } + TraceIndexO = index + count; + ResumeTrace(); + } + + return ((2U << 16) | (3U + count)); +} + + +#if (SWO_STREAM != 0) + +// SWO Data Transfer complete callback +void SWO_TransferComplete (void) { + TraceIndexO += TransferSize; + TransferBusy = 0U; + ResumeTrace(); + osThreadFlagsSet(SWO_ThreadId, 1U); +} + +// SWO Thread +__NO_RETURN void SWO_Thread (void *argument) { + uint32_t timeout; + uint32_t flags; + uint32_t count; + uint32_t index; + uint32_t i, n; + (void) argument; + + timeout = osWaitForever; + + for (;;) { + flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout); + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + timeout = SWO_STREAM_TIMEOUT; + } else { + timeout = osWaitForever; + flags = osFlagsErrorTimeout; + } + if (TransferBusy == 0U) { + count = GetTraceCount(); + if (count != 0U) { + index = TraceIndexO & (SWO_BUFFER_SIZE - 1U); + n = SWO_BUFFER_SIZE - index; + if (count > n) { + count = n; + } + if (flags != osFlagsErrorTimeout) { + i = index & (USB_BLOCK_SIZE - 1U); + if (i == 0U) { + count &= ~(USB_BLOCK_SIZE - 1U); + } else { + n = USB_BLOCK_SIZE - i; + if (count >= n) { + count = n; + } else { + count = 0U; + } + } + } + if (count != 0U) { + TransferSize = count; + TransferBusy = 1U; + SWO_QueueTransfer(&TraceBuf[index], count); + } + } + } + } +} + +#endif /* (SWO_STREAM != 0) */ + + +#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */ diff --git a/Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c b/Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c new file mode 100644 index 0000000..a2ad59c --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. December 2017 + * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Source + * Title: SW_DP.c CMSIS-DAP SW DP I/O + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" + + +// SW Macros + +#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET +#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR + +#define SW_CLOCK_CYCLE() \ + PIN_SWCLK_CLR(); \ + PIN_DELAY(); \ + PIN_SWCLK_SET(); \ + PIN_DELAY() + +#define SW_WRITE_BIT(bit) \ + PIN_SWDIO_OUT(bit); \ + PIN_SWCLK_CLR(); \ + PIN_DELAY(); \ + PIN_SWCLK_SET(); \ + PIN_DELAY() + +#define SW_READ_BIT(bit) \ + PIN_SWCLK_CLR(); \ + PIN_DELAY(); \ + bit = PIN_SWDIO_IN(); \ + PIN_SWCLK_SET(); \ + PIN_DELAY() + +#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) + + +// Generate SWJ Sequence +// count: sequence bit count +// data: pointer to sequence bit data +// return: none +#if ((DAP_SWD != 0) || (DAP_JTAG != 0)) +void SWJ_Sequence (uint32_t count, const uint8_t *data) { + uint32_t val; + uint32_t n; + + val = 0U; + n = 0U; + while (count--) { + if (n == 0U) { + val = *data++; + n = 8U; + } + if (val & 1U) { + PIN_SWDIO_TMS_SET(); + } else { + PIN_SWDIO_TMS_CLR(); + } + SW_CLOCK_CYCLE(); + val >>= 1; + n--; + } +} +#endif + + +// Generate SWD Sequence +// info: sequence information +// swdo: pointer to SWDIO generated data +// swdi: pointer to SWDIO captured data +// return: none +#if (DAP_SWD != 0) +void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { + uint32_t val; + uint32_t bit; + uint32_t n, k; + + n = info & SWD_SEQUENCE_CLK; + if (n == 0U) { + n = 64U; + } + + if (info & SWD_SEQUENCE_DIN) { + while (n) { + val = 0U; + for (k = 8U; k && n; k--, n--) { + SW_READ_BIT(bit); + val >>= 1; + val |= bit << 7; + } + val >>= k; + *swdi++ = (uint8_t)val; + } + } else { + while (n) { + val = *swdo++; + for (k = 8U; k && n; k--, n--) { + SW_WRITE_BIT(val); + val >>= 1; + } + } + } +} +#endif + + +#if (DAP_SWD != 0) + + +// SWD Transfer I/O +// request: A[3:2] RnW APnDP +// data: DATA[31:0] +// return: ACK[2:0] +#define SWD_TransferFunction(speed) /**/ \ +static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \ + uint32_t ack; \ + uint32_t bit; \ + uint32_t val; \ + uint32_t parity; \ + \ + uint32_t n; \ + \ + /* Packet Request */ \ + parity = 0U; \ + SW_WRITE_BIT(1U); /* Start Bit */ \ + bit = request >> 0; \ + SW_WRITE_BIT(bit); /* APnDP Bit */ \ + parity += bit; \ + bit = request >> 1; \ + SW_WRITE_BIT(bit); /* RnW Bit */ \ + parity += bit; \ + bit = request >> 2; \ + SW_WRITE_BIT(bit); /* A2 Bit */ \ + parity += bit; \ + bit = request >> 3; \ + SW_WRITE_BIT(bit); /* A3 Bit */ \ + parity += bit; \ + SW_WRITE_BIT(parity); /* Parity Bit */ \ + SW_WRITE_BIT(0U); /* Stop Bit */ \ + SW_WRITE_BIT(1U); /* Park Bit */ \ + \ + /* Turnaround */ \ + PIN_SWDIO_OUT_DISABLE(); \ + for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ + SW_CLOCK_CYCLE(); \ + } \ + \ + /* Acknowledge response */ \ + SW_READ_BIT(bit); \ + ack = bit << 0; \ + SW_READ_BIT(bit); \ + ack |= bit << 1; \ + SW_READ_BIT(bit); \ + ack |= bit << 2; \ + \ + if (ack == DAP_TRANSFER_OK) { /* OK response */ \ + /* Data transfer */ \ + if (request & DAP_TRANSFER_RnW) { \ + /* Read data */ \ + val = 0U; \ + parity = 0U; \ + for (n = 32U; n; n--) { \ + SW_READ_BIT(bit); /* Read RDATA[0:31] */ \ + parity += bit; \ + val >>= 1; \ + val |= bit << 31; \ + } \ + SW_READ_BIT(bit); /* Read Parity */ \ + if ((parity ^ bit) & 1U) { \ + ack = DAP_TRANSFER_ERROR; \ + } \ + if (data) { *data = val; } \ + /* Turnaround */ \ + for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ + SW_CLOCK_CYCLE(); \ + } \ + PIN_SWDIO_OUT_ENABLE(); \ + } else { \ + /* Turnaround */ \ + for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ + SW_CLOCK_CYCLE(); \ + } \ + PIN_SWDIO_OUT_ENABLE(); \ + /* Write data */ \ + val = *data; \ + parity = 0U; \ + for (n = 32U; n; n--) { \ + SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \ + parity += val; \ + val >>= 1; \ + } \ + SW_WRITE_BIT(parity); /* Write Parity Bit */ \ + } \ + /* Capture Timestamp */ \ + if (request & DAP_TRANSFER_TIMESTAMP) { \ + DAP_Data.timestamp = TIMESTAMP_GET(); \ + } \ + /* Idle cycles */ \ + n = DAP_Data.transfer.idle_cycles; \ + if (n) { \ + PIN_SWDIO_OUT(0U); \ + for (; n; n--) { \ + SW_CLOCK_CYCLE(); \ + } \ + } \ + PIN_SWDIO_OUT(1U); \ + return ((uint8_t)ack); \ + } \ + \ + if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \ + /* WAIT or FAULT response */ \ + if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \ + for (n = 32U+1U; n; n--) { \ + SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \ + } \ + } \ + /* Turnaround */ \ + for (n = DAP_Data.swd_conf.turnaround; n; n--) { \ + SW_CLOCK_CYCLE(); \ + } \ + PIN_SWDIO_OUT_ENABLE(); \ + if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \ + PIN_SWDIO_OUT(0U); \ + for (n = 32U+1U; n; n--) { \ + SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \ + } \ + } \ + PIN_SWDIO_OUT(1U); \ + return ((uint8_t)ack); \ + } \ + \ + /* Protocol error */ \ + for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \ + SW_CLOCK_CYCLE(); /* Back off data phase */ \ + } \ + PIN_SWDIO_OUT_ENABLE(); \ + PIN_SWDIO_OUT(1U); \ + return ((uint8_t)ack); \ +} + + +#undef PIN_DELAY +#define PIN_DELAY() PIN_DELAY_FAST() +SWD_TransferFunction(Fast) + +#undef PIN_DELAY +#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) +SWD_TransferFunction(Slow) + + +// SWD Transfer I/O +// request: A[3:2] RnW APnDP +// data: DATA[31:0] +// return: ACK[2:0] +uint8_t SWD_Transfer(uint32_t request, uint32_t *data) { + if (DAP_Data.fast_clock) { + return SWD_TransferFast(request, data); + } else { + return SWD_TransferSlow(request, data); + } +} + + +#endif /* (DAP_SWD != 0) */ diff --git a/Drivers/CMSIS/DAP/Firmware/Source/UART.c b/Drivers/CMSIS/DAP/Firmware/Source/UART.c new file mode 100644 index 0000000..5720b39 --- /dev/null +++ b/Drivers/CMSIS/DAP/Firmware/Source/UART.c @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2021 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. March 2021 + * $Revision: V1.0.0 + * + * Project: CMSIS-DAP Source + * Title: UART.c CMSIS-DAP UART + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" + +#if (DAP_UART != 0) + +#ifdef DAP_FW_V1 +#error "UART Communication Port not supported in DAP V1!" +#endif + +#include "Driver_USART.h" + +#include "cmsis_os2.h" +#include + +#define UART_RX_BLOCK_SIZE 32U /* Uart Rx Block Size (must be 2^n) */ + +// USART Driver +#define _USART_Driver_(n) Driver_USART##n +#define USART_Driver_(n) _USART_Driver_(n) +extern ARM_DRIVER_USART USART_Driver_(DAP_UART_DRIVER); +#define pUSART (&USART_Driver_(DAP_UART_DRIVER)) + +// UART Configuration +#if (DAP_UART_USB_COM_PORT != 0) +static uint8_t UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; +#else +static uint8_t UartTransport = DAP_UART_TRANSPORT_NONE; +#endif + +// UART Flags +static uint8_t UartConfigured = 0U; +static uint8_t UartReceiveEnabled = 0U; +static uint8_t UartTransmitEnabled = 0U; +static uint8_t UartTransmitActive = 0U; + +// UART TX Buffer +static uint8_t UartTxBuf[DAP_UART_TX_BUFFER_SIZE]; +static volatile uint32_t UartTxIndexI = 0U; +static volatile uint32_t UartTxIndexO = 0U; + +// UART RX Buffer +static uint8_t UartRxBuf[DAP_UART_RX_BUFFER_SIZE]; +static volatile uint32_t UartRxIndexI = 0U; +static volatile uint32_t UartRxIndexO = 0U; + +// Uart Errors +static volatile uint8_t UartErrorRxDataLost = 0U; +static volatile uint8_t UartErrorFraming = 0U; +static volatile uint8_t UartErrorParity = 0U; + +// UART Transmit +static uint32_t UartTxNum = 0U; + +// Function prototypes +static uint8_t UART_Init (void); +static void UART_Uninit (void); +static uint8_t UART_Get_Status (void); +static uint8_t UART_Receive_Enable (void); +static uint8_t UART_Transmit_Enable (void); +static void UART_Receive_Disable (void); +static void UART_Transmit_Disable (void); +static void UART_Receive_Flush (void); +static void UART_Transmit_Flush (void); +static void UART_Receive (void); +static void UART_Transmit (void); + + +// USART Driver Callback function +// event: event mask +static void USART_Callback (uint32_t event) { + if (event & ARM_USART_EVENT_SEND_COMPLETE) { + UartTxIndexO += UartTxNum; + UartTransmitActive = 0U; + UART_Transmit(); + } + if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { + UartRxIndexI += UART_RX_BLOCK_SIZE; + UART_Receive(); + } + if (event & ARM_USART_EVENT_RX_OVERFLOW) { + UartErrorRxDataLost = 1U; + } + if (event & ARM_USART_EVENT_RX_FRAMING_ERROR) { + UartErrorFraming = 1U; + } + if (event & ARM_USART_EVENT_RX_PARITY_ERROR) { + UartErrorParity = 1U; + } +} + +// Init UART +// return: DAP_OK or DAP_ERROR +static uint8_t UART_Init (void) { + int32_t status; + uint8_t ret = DAP_ERROR; + + UartConfigured = 0U; + UartReceiveEnabled = 0U; + UartTransmitEnabled = 0U; + UartTransmitActive = 0U; + UartErrorRxDataLost = 0U; + UartErrorFraming = 0U; + UartErrorParity = 0U; + UartTxIndexI = 0U; + UartTxIndexO = 0U; + UartRxIndexI = 0U; + UartRxIndexO = 0U; + UartTxNum = 0U; + + status = pUSART->Initialize(USART_Callback); + if (status == ARM_DRIVER_OK) { + status = pUSART->PowerControl(ARM_POWER_FULL); + } + if (status == ARM_DRIVER_OK) { + ret = DAP_OK; + } + + return (ret); +} + +// Un-Init UART +static void UART_Uninit (void) { + UartConfigured = 0U; + + pUSART->PowerControl(ARM_POWER_OFF); + pUSART->Uninitialize(); +} + +// Get UART Status +// return: status +static uint8_t UART_Get_Status (void) { + uint8_t status = 0U; + + if (UartReceiveEnabled != 0U) { + status |= DAP_UART_STATUS_RX_ENABLED; + } + if (UartErrorRxDataLost != 0U) { + UartErrorRxDataLost = 0U; + status |= DAP_UART_STATUS_RX_DATA_LOST; + } + if (UartErrorFraming != 0U) { + UartErrorFraming = 0U; + status |= DAP_UART_STATUS_FRAMING_ERROR; + } + if (UartErrorParity != 0U) { + UartErrorParity = 0U; + status |= DAP_UART_STATUS_PARITY_ERROR; + } + if (UartTransmitEnabled != 0U) { + status |= DAP_UART_STATUS_TX_ENABLED; + } + + return (status); +} + +// Enable UART Receive +// return: DAP_OK or DAP_ERROR +static uint8_t UART_Receive_Enable (void) { + int32_t status; + uint8_t ret = DAP_ERROR; + + if (UartReceiveEnabled == 0U) { + // Flush Buffers + UartRxIndexI = 0U; + UartRxIndexO = 0U; + + UART_Receive(); + status = pUSART->Control(ARM_USART_CONTROL_RX, 1U); + if (status == ARM_DRIVER_OK) { + UartReceiveEnabled = 1U; + ret = DAP_OK; + } + } else { + ret = DAP_OK; + } + + return (ret); +} + +// Enable UART Transmit +// return: DAP_OK or DAP_ERROR +static uint8_t UART_Transmit_Enable (void) { + int32_t status; + uint8_t ret = DAP_ERROR; + + if (UartTransmitEnabled == 0U) { + // Flush Buffers + UartTransmitActive = 0U; + UartTxIndexI = 0U; + UartTxIndexO = 0U; + UartTxNum = 0U; + + status = pUSART->Control(ARM_USART_CONTROL_TX, 1U); + if (status == ARM_DRIVER_OK) { + UartTransmitEnabled = 1U; + ret = DAP_OK; + } + } else { + ret = DAP_OK; + } + + return (ret); +} + +// Disable UART Receive +static void UART_Receive_Disable (void) { + if (UartReceiveEnabled != 0U) { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + UartReceiveEnabled = 0U; + } +} + +// Disable UART Transmit +static void UART_Transmit_Disable (void) { + if (UartTransmitEnabled != 0U) { + pUSART->Control(ARM_USART_ABORT_SEND, 0U); + pUSART->Control(ARM_USART_CONTROL_TX, 0U); + UartTransmitActive = 0U; + UartTransmitEnabled = 0U; + } +} + +// Flush UART Receive buffer +static void UART_Receive_Flush (void) { + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + UartRxIndexI = 0U; + UartRxIndexO = 0U; + if (UartReceiveEnabled != 0U) { + UART_Receive(); + } +} + +// Flush UART Transmit buffer +static void UART_Transmit_Flush (void) { + pUSART->Control(ARM_USART_ABORT_SEND, 0U); + UartTransmitActive = 0U; + UartTxIndexI = 0U; + UartTxIndexO = 0U; + UartTxNum = 0U; +} + +// Receive data from target via UART +static void UART_Receive (void) { + uint32_t index; + + index = UartRxIndexI & (DAP_UART_RX_BUFFER_SIZE - 1U); + pUSART->Receive(&UartRxBuf[index], UART_RX_BLOCK_SIZE); +} + +// Transmit available data to target via UART +static void UART_Transmit (void) { + uint32_t count; + uint32_t index; + + count = UartTxIndexI - UartTxIndexO; + index = UartTxIndexO & (DAP_UART_TX_BUFFER_SIZE - 1U); + + if (count != 0U) { + if ((index + count) <= DAP_UART_TX_BUFFER_SIZE) { + UartTxNum = count; + } else { + UartTxNum = DAP_UART_TX_BUFFER_SIZE - index; + } + UartTransmitActive = 1U; + pUSART->Send(&UartTxBuf[index], UartTxNum); + } +} + +// Process UART Transport command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Transport (const uint8_t *request, uint8_t *response) { + uint8_t transport; + uint8_t ret = DAP_ERROR; + + transport = *request; + switch (transport) { + case DAP_UART_TRANSPORT_NONE: + switch (UartTransport) { + case DAP_UART_TRANSPORT_NONE: + ret = DAP_OK; + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: +#if (DAP_UART_USB_COM_PORT != 0) + USB_COM_PORT_Activate(0U); + UartTransport = DAP_UART_TRANSPORT_NONE; + ret = DAP_OK; +#endif + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + UART_Receive_Disable(); + UART_Transmit_Disable(); + UART_Uninit(); + UartTransport = DAP_UART_TRANSPORT_NONE; + ret= DAP_OK; + break; + } + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: + switch (UartTransport) { + case DAP_UART_TRANSPORT_NONE: +#if (DAP_UART_USB_COM_PORT != 0) + if (USB_COM_PORT_Activate(1U) == 0U) { + UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; + ret = DAP_OK; + } +#endif + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: + ret = DAP_OK; + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + UART_Receive_Disable(); + UART_Transmit_Disable(); + UART_Uninit(); + UartTransport = DAP_UART_TRANSPORT_NONE; +#if (DAP_UART_USB_COM_PORT != 0) + if (USB_COM_PORT_Activate(1U) == 0U) { + UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; + ret = DAP_OK; + } +#endif + break; + } + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + switch (UartTransport) { + case DAP_UART_TRANSPORT_NONE: + ret = UART_Init(); + if (ret == DAP_OK) { + UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND; + } + break; + case DAP_UART_TRANSPORT_USB_COM_PORT: +#if (DAP_UART_USB_COM_PORT != 0) + USB_COM_PORT_Activate(0U); + UartTransport = DAP_UART_TRANSPORT_NONE; +#endif + ret = UART_Init(); + if (ret == DAP_OK) { + UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND; + } + break; + case DAP_UART_TRANSPORT_DAP_COMMAND: + ret = DAP_OK; + break; + } + break; + default: + break; + } + + *response = ret; + + return ((1U << 16) | 1U); +} + +// Process UART Configure command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Configure (const uint8_t *request, uint8_t *response) { + uint8_t control, status; + uint32_t baudrate; + int32_t result; + + if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) { + status = DAP_UART_CFG_ERROR_DATA_BITS | + DAP_UART_CFG_ERROR_PARITY | + DAP_UART_CFG_ERROR_STOP_BITS; + baudrate = 0U; // baudrate error + } else { + + status = 0U; + control = *request; + baudrate = (uint32_t)(*(request+1) << 0) | + (uint32_t)(*(request+2) << 8) | + (uint32_t)(*(request+3) << 16) | + (uint32_t)(*(request+4) << 24); + + result = pUSART->Control(control | + ARM_USART_MODE_ASYNCHRONOUS | + ARM_USART_FLOW_CONTROL_NONE, + baudrate); + if (result == ARM_DRIVER_OK) { + UartConfigured = 1U; + } else { + UartConfigured = 0U; + switch (result) { + case ARM_USART_ERROR_BAUDRATE: + status = 0U; + baudrate = 0U; + break; + case ARM_USART_ERROR_DATA_BITS: + status = DAP_UART_CFG_ERROR_DATA_BITS; + break; + case ARM_USART_ERROR_PARITY: + status = DAP_UART_CFG_ERROR_PARITY; + break; + case ARM_USART_ERROR_STOP_BITS: + status = DAP_UART_CFG_ERROR_STOP_BITS; + break; + default: + status = DAP_UART_CFG_ERROR_DATA_BITS | + DAP_UART_CFG_ERROR_PARITY | + DAP_UART_CFG_ERROR_STOP_BITS; + baudrate = 0U; + break; + } + } + } + + *response++ = status; + *response++ = (uint8_t)(baudrate >> 0); + *response++ = (uint8_t)(baudrate >> 8); + *response++ = (uint8_t)(baudrate >> 16); + *response = (uint8_t)(baudrate >> 24); + + return ((5U << 16) | 5U); +} + +// Process UART Control command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Control (const uint8_t *request, uint8_t *response) { + uint8_t control; + uint8_t result; + uint8_t ret = DAP_OK; + + if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) { + ret = DAP_ERROR; + } else { + + control = *request; + + if ((control & DAP_UART_CONTROL_RX_DISABLE) != 0U) { + // Receive disable + UART_Receive_Disable(); + } else if ((control & DAP_UART_CONTROL_RX_ENABLE) != 0U) { + // Receive enable + if (UartConfigured != 0U) { + result = UART_Receive_Enable(); + if (result != DAP_OK) { + ret = DAP_ERROR; + } + } else { + ret = DAP_ERROR; + } + } + if ((control & DAP_UART_CONTROL_RX_BUF_FLUSH) != 0U) { + UART_Receive_Flush(); + } + + if ((control & DAP_UART_CONTROL_TX_DISABLE) != 0U) { + // Transmit disable + UART_Transmit_Disable(); + } else if ((control & DAP_UART_CONTROL_TX_ENABLE) != 0U) { + // Transmit enable + if (UartConfigured != 0U) { + result = UART_Transmit_Enable(); + if (result != DAP_OK) { + ret = DAP_ERROR; + } + } else { + ret = DAP_ERROR; + } + } + if ((control & DAP_UART_CONTROL_TX_BUF_FLUSH) != 0U) { + UART_Transmit_Flush(); + } + } + + *response = ret; + + return ((1U << 16) | 1U); +} + +// Process UART Status command and prepare response +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Status (uint8_t *response) { + uint32_t rx_cnt, tx_cnt; + uint32_t cnt; + uint8_t status; + + if ((UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) || + (UartConfigured == 0U)) { + rx_cnt = 0U; + tx_cnt = 0U; + status = 0U; + } else { + + rx_cnt = UartRxIndexI - UartRxIndexO; + rx_cnt += pUSART->GetRxCount(); + if (rx_cnt > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) { + // Overflow + UartErrorRxDataLost = 1U; + rx_cnt = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2)); + UartRxIndexO = UartRxIndexI - rx_cnt; + } + + tx_cnt = UartTxIndexI - UartTxIndexO; + cnt = pUSART->GetTxCount(); + if (UartTransmitActive != 0U) { + tx_cnt -= cnt; + } + + status = UART_Get_Status(); + } + + *response++ = status; + *response++ = (uint8_t)(rx_cnt >> 0); + *response++ = (uint8_t)(rx_cnt >> 8); + *response++ = (uint8_t)(rx_cnt >> 16); + *response++ = (uint8_t)(rx_cnt >> 24); + *response++ = (uint8_t)(tx_cnt >> 0); + *response++ = (uint8_t)(tx_cnt >> 8); + *response++ = (uint8_t)(tx_cnt >> 16); + *response = (uint8_t)(tx_cnt >> 24); + + return ((0U << 16) | 9U); +} + +// Process UART Transfer command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t UART_Transfer (const uint8_t *request, uint8_t *response) { + uint32_t rx_cnt, tx_cnt; + uint32_t rx_num, tx_num; + uint8_t *rx_data; + const + uint8_t *tx_data; + uint32_t num; + uint32_t index; + uint8_t status; + + if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) { + status = 0U; + rx_cnt = 0U; + tx_cnt = 0U; + } else { + + // RX Data + rx_cnt = ((uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8)); + + if (rx_cnt > (DAP_PACKET_SIZE - 6U)) { + rx_cnt = (DAP_PACKET_SIZE - 6U); + } + rx_num = UartRxIndexI - UartRxIndexO; + rx_num += pUSART->GetRxCount(); + if (rx_num > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) { + // Overflow + UartErrorRxDataLost = 1U; + rx_num = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2)); + UartRxIndexO = UartRxIndexI - rx_num; + } + if (rx_cnt > rx_num) { + rx_cnt = rx_num; + } + + rx_data = (response+5); + index = UartRxIndexO & (DAP_UART_RX_BUFFER_SIZE - 1U); + if ((index + rx_cnt) <= DAP_UART_RX_BUFFER_SIZE) { + memcpy( rx_data, &UartRxBuf[index], rx_cnt); + } else { + num = DAP_UART_RX_BUFFER_SIZE - index; + memcpy( rx_data, &UartRxBuf[index], num); + memcpy(&rx_data[num], &UartRxBuf[0], rx_cnt - num); + } + UartRxIndexO += rx_cnt; + + // TX Data + tx_cnt = ((uint32_t)(*(request+2) << 0) | + (uint32_t)(*(request+3) << 8)); + tx_data = (request+4); + + if (tx_cnt > (DAP_PACKET_SIZE - 5U)) { + tx_cnt = (DAP_PACKET_SIZE - 5U); + } + tx_num = UartTxIndexI - UartTxIndexO; + num = pUSART->GetTxCount(); + if (UartTransmitActive != 0U) { + tx_num -= num; + } + if (tx_cnt > (DAP_UART_TX_BUFFER_SIZE - tx_num)) { + tx_cnt = (DAP_UART_TX_BUFFER_SIZE - tx_num); + } + + index = UartTxIndexI & (DAP_UART_TX_BUFFER_SIZE - 1U); + if ((index + tx_cnt) <= DAP_UART_TX_BUFFER_SIZE) { + memcpy(&UartTxBuf[index], tx_data, tx_cnt); + } else { + num = DAP_UART_TX_BUFFER_SIZE - index; + memcpy(&UartTxBuf[index], tx_data, num); + memcpy(&UartTxBuf[0], &tx_data[num], tx_cnt - num); + } + UartTxIndexI += tx_cnt; + + if (UartTransmitActive == 0U) { + UART_Transmit(); + } + + status = UART_Get_Status(); + } + + *response++ = status; + *response++ = (uint8_t)(tx_cnt >> 0); + *response++ = (uint8_t)(tx_cnt >> 8); + *response++ = (uint8_t)(rx_cnt >> 0); + *response = (uint8_t)(rx_cnt >> 8); + + return (((4U + tx_cnt) << 16) | (5U + rx_cnt)); +} + +#endif /* DAP_UART */ diff --git a/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7rsxx.h b/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7rsxx.h new file mode 100644 index 0000000..46c5f6e --- /dev/null +++ b/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7rsxx.h @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx.h + * @author MCD Application Team + * @brief CMSIS STM32H7RSxx 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 STM32H7RSxx 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) 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32h7rsxx + * @{ + */ + +#ifndef STM32H7RSxx_H +#define STM32H7RSxx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * @brief STM32 Family + */ +#if !defined (STM32H7RS) +#define STM32H7RS +#endif /* STM32H7RS */ + +/* Uncomment the line below according to the target STM32H7RS device used in your + application + */ + +#if !defined (STM32H7R7xx) && !defined (STM32H7R3xx) && !defined (STM32H7S3xx) && !defined (STM32H7S7xx) + /* #define STM32H7R3xx */ /*!< STM32H7R3xx Devices */ + /* #define STM32H7R7xx */ /*!< STM32H7R7xx Devices */ + /* #define STM32H7S3xx */ /*!< STM32H7S3xx Devices */ + /* #define STM32H7S7xx */ /*!< STM32H7S7xx 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 + */ +#define __STM32H7RS_CMSIS_VERSION_MAIN (0x01U) /*!< [31:24] main version */ +#define __STM32H7RS_CMSIS_VERSION_SUB1 (0x02U) /*!< [23:16] sub1 version */ +#define __STM32H7RS_CMSIS_VERSION_SUB2 (0x01U) /*!< [15:8] sub2 version */ +#define __STM32H7RS_CMSIS_VERSION_RC (0x00U) /*!< [7:0] release candidate */ +#define __STM32H7RS_CMSIS_VERSION ((__STM32H7RS_CMSIS_VERSION_MAIN << 24U)\ + |(__STM32H7RS_CMSIS_VERSION_SUB1 << 16U)\ + |(__STM32H7RS_CMSIS_VERSION_SUB2 << 8U )\ + |(__STM32H7RS_CMSIS_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Device_Included + * @{ + */ + +#if defined(STM32H7R3xx) + #include "stm32h7r3xx.h" +#elif defined(STM32H7R7xx) + #include "stm32h7r7xx.h" +#elif defined(STM32H7S3xx) + #include "stm32h7s3xx.h" +#elif defined(STM32H7S7xx) + #include "stm32h7s7xx.h" +#else + #error "Please select first the target STM32H7RSxx device used in your application (in stm32h7rsxx.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))) + +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) + +/* 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) + +/** + * @} + */ + +#if defined (USE_HAL_DRIVER) + #include "stm32h7rsxx_hal.h" +#endif /* USE_HAL_DRIVER */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H7RSxx_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7s7xx.h b/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7s7xx.h new file mode 100644 index 0000000..f3ce477 --- /dev/null +++ b/Drivers/CMSIS/Device/ST/STM32H7RSxx/Include/stm32h7s7xx.h @@ -0,0 +1,24680 @@ +/** + ****************************************************************************** + * @file stm32h7s7xx.h + * @author MCD Application Team + * @brief CMSIS STM32H7S7xx 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) 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. + * + ****************************************************************************** + */ + +#ifndef STM32H7S7xx_H +#define STM32H7S7xx_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup ST + * @{ + */ + + +/** @addtogroup STM32H7S7xx + * @{ + */ + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum +{ +/* ======================================= ARM Cortex-M7 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 */ + +/* =========================================== STM32H7S7xx Specific Interrupt Numbers ====================================== */ + PVD_PVM_IRQn = 0, /*!< PVD/PVM through EXTI Line detection */ + DTS_IRQn = 2, /*!< Digital Temperature Sensor interrupt */ + IWDG_IRQn = 3, /*!< Internal Watchdog interrupt */ + WWDG_IRQn = 4, /*!< Window Watchdog interrupt */ + RCC_IRQn = 5, /*!< RCC global interrupts through EXTI Line detection */ + FLASH_IRQn = 8, /*!< FLASH interrupts */ + RAMECC_IRQn = 9, /*!< RAMECC interrupts */ + FPU_IRQn = 10, /*!< FPU interrupt */ + TAMP_IRQn = 13, /*!< Tamper and TimeStamp interrupts through EXTI Line detection */ + EXTI0_IRQn = 16, /*!< EXTI Line0 interrupt */ + EXTI1_IRQn = 17, /*!< EXTI Line1 interrupt */ + EXTI2_IRQn = 18, /*!< EXTI Line2 interrupt */ + EXTI3_IRQn = 19, /*!< EXTI Line3 interrupt */ + EXTI4_IRQn = 20, /*!< EXTI Line4 interrupt */ + EXTI5_IRQn = 21, /*!< EXTI Line5 interrupt */ + EXTI6_IRQn = 22, /*!< EXTI Line6 interrupt */ + EXTI7_IRQn = 23, /*!< EXTI Line7 interrupt */ + EXTI8_IRQn = 24, /*!< EXTI Line8 interrupt */ + EXTI9_IRQn = 25, /*!< EXTI Line9 interrupt */ + EXTI10_IRQn = 26, /*!< EXTI Line10 interrupt */ + EXTI11_IRQn = 27, /*!< EXTI Line11 interrupt */ + EXTI12_IRQn = 28, /*!< EXTI Line12 interrupt */ + EXTI13_IRQn = 29, /*!< EXTI Line13 interrupt */ + EXTI14_IRQn = 30, /*!< EXTI Line14 interrupt */ + EXTI15_IRQn = 31, /*!< EXTI Line15 interrupt */ + RTC_IRQn = 32, /*!< RTC Wakeup and Alarm interrupts through EXTI Line detection */ + SAES_IRQn = 33, /*!< SAES interrupt */ + CRYP_IRQn = 34, /*!< CRYP interrupt */ + PKA_IRQn = 35, /*!< PKA interrupt */ + HASH_IRQn = 36, /*!< HASH interrupt */ + RNG_IRQn = 37, /*!< RNG global interrupt */ + ADC1_2_IRQn = 38, /*!< ADC1 & ADC2 interrupt */ + GPDMA1_Channel0_IRQn = 39, /*!< GPDMA1 Channel 0 interrupt */ + GPDMA1_Channel1_IRQn = 40, /*!< GPDMA1 Channel 1 interrupt */ + GPDMA1_Channel2_IRQn = 41, /*!< GPDMA1 Channel 2 interrupt */ + GPDMA1_Channel3_IRQn = 42, /*!< GPDMA1 Channel 3 interrupt */ + GPDMA1_Channel4_IRQn = 43, /*!< GPDMA1 Channel 4 interrupt */ + GPDMA1_Channel5_IRQn = 44, /*!< GPDMA1 Channel 5 interrupt */ + GPDMA1_Channel6_IRQn = 45, /*!< GPDMA1 Channel 6 interrupt */ + GPDMA1_Channel7_IRQn = 46, /*!< GPDMA1 Channel 7 interrupt */ + TIM1_BRK_IRQn = 47, /*!< TIM1 Break interrupt */ + TIM1_UP_IRQn = 48, /*!< TIM1 Update interrupt */ + TIM1_TRG_COM_IRQn = 49, /*!< TIM1 Trigger and Commutation interrupt */ + TIM1_CC_IRQn = 50, /*!< TIM1 Capture Compare interrupt */ + TIM2_IRQn = 51, /*!< TIM2 global interrupt */ + TIM3_IRQn = 52, /*!< TIM3 global interrupt */ + TIM4_IRQn = 53, /*!< TIM4 global interrupt */ + TIM5_IRQn = 54, /*!< TIM5 global interrupt */ + TIM6_IRQn = 55, /*!< TIM6 global interrupt */ + TIM7_IRQn = 56, /*!< TIM7 global interrupt */ + TIM9_IRQn = 57, /*!< TIM9 global interrupt */ + SPI1_IRQn = 58, /*!< SPI1 global interrupt */ + SPI2_IRQn = 59, /*!< SPI2 global interrupt */ + SPI3_IRQn = 60, /*!< SPI3 global interrupt */ + SPI4_IRQn = 61, /*!< SPI4 global interrupt */ + SPI5_IRQn = 62, /*!< SPI5 global interrupt */ + SPI6_IRQn = 63, /*!< SPI6 global interrupt */ + HPDMA1_Channel0_IRQn = 64, /*!< HPDMA1 Channel 0 global interrupt */ + HPDMA1_Channel1_IRQn = 65, /*!< HPDMA1 Channel 1 global interrupt */ + HPDMA1_Channel2_IRQn = 66, /*!< HPDMA1 Channel 2 global interrupt */ + HPDMA1_Channel3_IRQn = 67, /*!< HPDMA1 Channel 3 global interrupt */ + HPDMA1_Channel4_IRQn = 68, /*!< HPDMA1 Channel 4 global interrupt */ + HPDMA1_Channel5_IRQn = 69, /*!< HPDMA1 Channel 5 global interrupt */ + HPDMA1_Channel6_IRQn = 70, /*!< HPDMA1 Channel 6 global interrupt */ + HPDMA1_Channel7_IRQn = 71, /*!< HPDMA1 Channel 7 global interrupt */ + SAI1_A_IRQn = 72, /*!< Serial Audio Interface 1 block A interrupt */ + SAI1_B_IRQn = 73, /*!< Serial Audio Interface 1 block B interrupt */ + SAI2_A_IRQn = 74, /*!< Serial Audio Interface 2 block A interrupt */ + SAI2_B_IRQn = 75, /*!< Serial Audio Interface 2 block B interrupt */ + I2C1_EV_IRQn = 76, /*!< I2C1 event interrupt */ + I2C1_ER_IRQn = 77, /*!< I2C1 error interrupt */ + I2C2_EV_IRQn = 78, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 79, /*!< I2C2 error interrupt */ + I2C3_EV_IRQn = 80, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 81, /*!< I2C3 error interrupt */ + USART1_IRQn = 82, /*!< USART1 global interrupt */ + USART2_IRQn = 83, /*!< USART2 global interrupt */ + USART3_IRQn = 84, /*!< USART3 global interrupt */ + UART4_IRQn = 85, /*!< UART4 global interrupt */ + UART5_IRQn = 86, /*!< UART5 global interrupt */ + UART7_IRQn = 87, /*!< UART7 global interrupt */ + UART8_IRQn = 88, /*!< UART8 global interrupt */ + I3C1_EV_IRQn = 89, /*!< I3C1 event interrupt */ + I3C1_ER_IRQn = 90, /*!< I3C1 error interrupt */ + OTG_HS_IRQn = 91, /*!< USB OTG HS interrupt */ + ETH_IRQn = 92, /*!< Ethernet global interrupt */ + CORDIC_IRQn = 93, /*!< CORDIC global interrupt */ + GFXTIM_IRQn = 94, /*!< GFXTIM global interrupt */ + DCMIPP_IRQn = 95, /*!< DCMIPP global interrupt */ + LTDC_IRQn = 96, /*!< LTDC global interrupt */ + LTDC_ER_IRQn = 97, /*!< LTDC error global interrupt */ + DMA2D_IRQn = 98, /*!< DMA2D global interrupt */ + JPEG_IRQn = 99, /*!< JPEG global interrupt */ + GFXMMU_IRQn = 100, /*!< GFXMMU global interrupt */ + I3C1_WKUP_IRQn = 101, /*!< I3C1 wakeup global interrupt */ + MCE1_IRQn = 102, /*!< MCE1 global interrupt */ + MCE2_IRQn = 103, /*!< MCE2 global interrupt */ + MCE3_IRQn = 104, /*!< MCE3 global interrupt */ + XSPI1_IRQn = 105, /*!< XSPI1 global interrupt */ + XSPI2_IRQn = 106, /*!< XSPI2 global interrupt */ + FMC_IRQn = 107, /*!< FMC global interrupt */ + SDMMC1_IRQn = 108, /*!< SDMMC1 global interrupt */ + SDMMC2_IRQn = 109, /*!< SDMMC2 global interrupt */ + OTG_FS_IRQn = 112, /*!< USB OTG FS interrupt */ + TIM12_IRQn = 113, /*!< TIM12 global interrupt */ + TIM13_IRQn = 114, /*!< TIM13 global interrupt */ + TIM14_IRQn = 115, /*!< TIM14 global interrupt */ + TIM15_IRQn = 116, /*!< TIM15 global interrupt */ + TIM16_IRQn = 117, /*!< TIM16 global interrupt */ + TIM17_IRQn = 118, /*!< TIM17 global interrupt */ + LPTIM1_IRQn = 119, /*!< LPTIM1 global interrupt */ + LPTIM2_IRQn = 120, /*!< LPTIM2 global interrupt */ + LPTIM3_IRQn = 121, /*!< LPTIM3 global interrupt */ + LPTIM4_IRQn = 122, /*!< LPTIM4 global interrupt */ + LPTIM5_IRQn = 123, /*!< LPTIM5 global interrupt */ + SPDIF_RX_IRQn = 124, /*!< SPDIF_RX global interrupt */ + MDIOS_IRQn = 125, /*!< MDIOS global interrupt */ + ADF1_FLT0_IRQn = 126, /*!< ADF1 Filter 0 global Interrupt */ + CRS_IRQn = 127, /*!< CRS global interrupt */ + UCPD1_IRQn = 128, /*!< UCPD1 global interrupt */ + CEC_IRQn = 129, /*!< HDMI_CEC global Interrupt */ + PSSI_IRQn = 130, /*!< PSSI global interrupt */ + LPUART1_IRQn = 131, /*!< LPUART1 global interrupt */ + WAKEUP_PIN_IRQn = 132, /*!< Wake-up pins interrupt */ + GPDMA1_Channel8_IRQn = 133, /*!< GPDMA1 Channel 8 global interrupt */ + GPDMA1_Channel9_IRQn = 134, /*!< GPDMA1 Channel 9 global interrupt */ + GPDMA1_Channel10_IRQn = 135, /*!< GPDMA1 Channel 10 global interrupt */ + GPDMA1_Channel11_IRQn = 136, /*!< GPDMA1 Channel 11 global interrupt */ + GPDMA1_Channel12_IRQn = 137, /*!< GPDMA1 Channel 12 global interrupt */ + GPDMA1_Channel13_IRQn = 138, /*!< GPDMA1 Channel 13 global interrupt */ + GPDMA1_Channel14_IRQn = 139, /*!< GPDMA1 Channel 14 global interrupt */ + GPDMA1_Channel15_IRQn = 140, /*!< GPDMA1 Channel 15 global interrupt */ + HPDMA1_Channel8_IRQn = 141, /*!< HPDMA1 Channel 8 global interrupt */ + HPDMA1_Channel9_IRQn = 142, /*!< HPDMA1 Channel 9 global interrupt */ + HPDMA1_Channel10_IRQn = 143, /*!< HPDMA1 Channel 10 global interrupt */ + HPDMA1_Channel11_IRQn = 144, /*!< HPDMA1 Channel 11 global interrupt */ + HPDMA1_Channel12_IRQn = 145, /*!< HPDMA1 Channel 12 global interrupt */ + HPDMA1_Channel13_IRQn = 146, /*!< HPDMA1 Channel 13 global interrupt */ + HPDMA1_Channel14_IRQn = 147, /*!< HPDMA1 Channel 14 global interrupt */ + HPDMA1_Channel15_IRQn = 148, /*!< HPDMA1 Channel 15 global interrupt */ + GPU2D_IRQn = 149, /*!< GPU2D interrupt */ + GPU2D_ER_IRQn = 150, /*!< GPU2D error interrupt */ + ICACHE_IRQn = 151, /*!< ICACHE interrupt */ + FDCAN1_IT0_IRQn = 152, /*!< FDCAN1 interrupt 0 */ + FDCAN1_IT1_IRQn = 153, /*!< FDCAN1 interrupt 1 */ + FDCAN2_IT0_IRQn = 154, /*!< FDCAN2 interrupt 0 */ + FDCAN2_IT1_IRQn = 155 /*!< FDCAN2 interrupt 1 */ +} IRQn_Type; + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/** + * @brief Configuration of the Cortex-M7 Processor and Core Peripherals + */ +#define __CM7_REV 0x0102U /*!< Cortex-M7 revision r1p2 */ +#define __MPU_PRESENT 1U /*!< CM7 provides an MPU */ +#define __MPU_REGIONCOUNT 16U /*!< CM7 provides MPU region number */ +#define __NVIC_PRIO_BITS 4U /*!< CM7 uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /*!< FPU present */ +#define __ICACHE_PRESENT 1U /*!< CM7 instruction cache present */ +#define __DCACHE_PRESENT 1U /*!< CM7 data cache present */ + +/** @} */ /* End of group Configuration_of_CMSIS */ + + +#include "core_cm7.h" /*!< ARM Cortex-M7 processor and core peripherals */ +#include "system_stm32h7rsxx.h" /*!< STM32H7RSxx System */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H7RSxx_peripherals + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t ISR; /*!< ADC interrupt and status register, Address offset: 0x00 */ + __IO uint32_t IER; /*!< ADC interrupt enable register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< ADC control register, Address offset: 0x08 */ + __IO uint32_t CFGR; /*!< ADC configuration register 1, Address offset: 0x0C */ + __IO uint32_t CFGR2; /*!< ADC configuration register 2, Address offset: 0x10 */ + __IO uint32_t SMPR1; /*!< ADC sampling time register 1, Address offset: 0x14 */ + __IO uint32_t SMPR2; /*!< ADC sampling time register 2, Address offset: 0x18 */ + uint32_t RESERVED1; /*!< Reserved, 0x1C */ + __IO uint32_t TR1; /*!< ADC analog watchdog 1 threshold register, Address offset: 0x20 */ + __IO uint32_t TR2; /*!< ADC analog watchdog 2 threshold register, Address offset: 0x24 */ + __IO uint32_t TR3; /*!< ADC analog watchdog 3 threshold register, Address offset: 0x28 */ + uint32_t RESERVED2; /*!< Reserved, 0x2C */ + __IO uint32_t SQR1; /*!< ADC group regular sequencer register 1, Address offset: 0x30 */ + __IO uint32_t SQR2; /*!< ADC group regular sequencer register 2, Address offset: 0x34 */ + __IO uint32_t SQR3; /*!< ADC group regular sequencer register 3, Address offset: 0x38 */ + __IO uint32_t SQR4; /*!< ADC group regular sequencer register 4, Address offset: 0x3C */ + __IO uint32_t DR; /*!< ADC group regular data register, Address offset: 0x40 */ + uint32_t RESERVED3; /*!< Reserved, 0x44 */ + uint32_t RESERVED4; /*!< Reserved, 0x48 */ + __IO uint32_t JSQR; /*!< ADC group injected sequencer register, Address offset: 0x4C */ + uint32_t RESERVED5[4]; /*!< Reserved, 0x50 - 0x5C */ + __IO uint32_t OFR1; /*!< ADC offset register 1, Address offset: 0x60 */ + __IO uint32_t OFR2; /*!< ADC offset register 2, Address offset: 0x64 */ + __IO uint32_t OFR3; /*!< ADC offset register 3, Address offset: 0x68 */ + __IO uint32_t OFR4; /*!< ADC offset register 4, Address offset: 0x6C */ + uint32_t RESERVED6[4]; /*!< Reserved, 0x70 - 0x7C */ + __IO uint32_t JDR1; /*!< ADC group injected rank 1 data register, Address offset: 0x80 */ + __IO uint32_t JDR2; /*!< ADC group injected rank 2 data register, Address offset: 0x84 */ + __IO uint32_t JDR3; /*!< ADC group injected rank 3 data register, Address offset: 0x88 */ + __IO uint32_t JDR4; /*!< ADC group injected rank 4 data register, Address offset: 0x8C */ + uint32_t RESERVED7[4]; /*!< Reserved, 0x090 - 0x09C */ + __IO uint32_t AWD2CR; /*!< ADC analog watchdog 2 configuration register, Address offset: 0xA0 */ + __IO uint32_t AWD3CR; /*!< ADC analog watchdog 3 Configuration Register, Address offset: 0xA4 */ + uint32_t RESERVED8; /*!< Reserved, 0x0A8 */ + uint32_t RESERVED9; /*!< Reserved, 0x0AC */ + __IO uint32_t DIFSEL; /*!< ADC differential mode selection register, Address offset: 0xB0 */ + __IO uint32_t CALFACT; /*!< ADC calibration factors, Address offset: 0xB4 */ + uint32_t RESERVED10[4];/*!< Reserved, 0x0B8 - 0x0BC */ + __IO uint32_t OR; /*!< ADC option register, Address offset: 0xC8 */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC common status register, Address offset: 0x300 + 0x00 */ + uint32_t RESERVED1; /*!< Reserved, Address offset: 0x300 + 0x04 */ + __IO uint32_t CCR; /*!< ADC common configuration register, Address offset: 0x300 + 0x08 */ + __IO uint32_t CDR; /*!< ADC common group regular data register Address offset: 0x300 + 0x0C */ +} ADC_Common_TypeDef; + +/** + * @brief AXIM ASIB + */ +typedef struct +{ + uint32_t RESERVED1[9]; /*!< Reserved, Address offset: 0x00-0x20 */ + __IO uint32_t FNMOD2; /*!< AXIM ASIB fn_mod2 register Address offset: 0x24 */ + uint32_t RESERVED3[54]; /*!< Reserved, Address offset: 0x28-0xFC */ + __IO uint32_t READQOS; /*!< AXIM ASIB read_qos register Address offset: 0x100 */ + __IO uint32_t WRITEQOS; /*!< AXIM ASIB write_qos register Address offset: 0x104 */ + __IO uint32_t FNMOD; /*!< AXIM ASIB fn_mod register Address offset: 0x108 */ +} AXIM_ASIB_TypeDef; + +typedef struct +{ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x00-0x04 */ + __IO uint32_t FNMODBMISS; /*!< AXIM AMIB fn_mod_bm_iss register Address offset: 0x08 */ + uint32_t RESERVED2[6]; /*!< Reserved, Address offset: 0x0C-0x20 */ + __IO uint32_t FNMOD2; /*!< AXIM AMIB fn_mod2 register Address offset: 0x24 */ + uint32_t RESERVED3[1]; /*!< Reserved, Address offset: 0x28 */ + __IO uint32_t FNMODLB; /*!< AXIM AMIB fn_mod_lb register Address offset: 0x2C */ + uint32_t RESERVED5[54]; /*!< Reserved, Address offset: 0x30-0x104 */ + __IO uint32_t FNMOD; /*!< AXIM AMIB fn_mod register Address offset: 0x108 */ +} AXIM_AMIB_TypeDef; + +/** + * @brief VREFBUF + */ + +typedef struct +{ + __IO uint32_t CSR; /*!< VREFBUF control and status register, Address offset: 0x00 */ + __IO uint32_t CCR; /*!< VREFBUF calibration and control register, Address offset: 0x04 */ +} VREFBUF_TypeDef; + +/** + * @brief Consumer Electronics Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CEC control register, Address offset:0x00 */ + __IO uint32_t CFGR; /*!< CEC configuration register, Address offset:0x04 */ + __IO uint32_t TXDR; /*!< CEC Tx data register , Address offset:0x08 */ + __IO uint32_t RXDR; /*!< CEC Rx Data Register, Address offset:0x0C */ + __IO uint32_t ISR; /*!< CEC Interrupt and Status Register, Address offset:0x10 */ + __IO uint32_t IER; /*!< CEC interrupt enable register, Address offset:0x14 */ +} CEC_TypeDef; + +/** + * @brief CORDIC + */ +typedef struct +{ + __IO uint32_t CSR; /*!< CORDIC Control and Status register, Address offset: 0x00 */ + __IO uint32_t WDATA; /*!< CORDIC argument register, Address offset: 0x04 */ + __IO uint32_t RDATA; /*!< CORDIC result register, Address offset: 0x08 */ +} CORDIC_TypeDef; + +/** + * @brief GFXTIM + */ +typedef struct +{ + __IO uint32_t CR; /*!< GFXTIM configuration register, Address offset: 0x00 */ + __IO uint32_t CGCR; /*!< GFXTIM clock generator configuration register, Address offset: 0x04 */ + __IO uint32_t TCR; /*!< GFXTIM timers configuration register, Address offset: 0x08 */ + __IO uint32_t TDR; /*!< GFXTIM timers disable register, Address offset: 0x0C */ + __IO uint32_t EVCR; /*!< GFXTIM events control register, Address offset: 0x10 */ + __IO uint32_t EVSR; /*!< GFXTIM events selection register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t WDGTCR; /*!< GFXTIM watchdog timer configuration register, Address offset: 0x20 */ + uint32_t RESERVED2[3]; /*!< Reserved, Address offset: 0x24-0x2C */ + __IO uint32_t ISR; /*!< GFXTIM interrupt status register, Address offset: 0x30 */ + __IO uint32_t ICR; /*!< GFXTIM interrupt clear register, Address offset: 0x34 */ + __IO uint32_t IER; /*!< GFXTIM interrupt enable register, Address offset: 0x38 */ + __IO uint32_t TSR; /*!< GFXTIM timers status register, Address offset: 0x3C */ + __IO uint32_t LCCRR; /*!< GFXTIM line clock counter reload register, Address offset: 0x40 */ + __IO uint32_t FCCRR; /*!< GFXTIM frame clock counter reload register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, Address offset: 0x48-0x4C */ + __IO uint32_t ATR; /*!< GFXTIM absolute time register, Address offset: 0x50 */ + __IO uint32_t AFCR; /*!< GFXTIM absolute frame counter register, Address offset: 0x54 */ + __IO uint32_t ALCR; /*!< GFXTIM absolute line counter register, Address offset: 0x58 */ + uint32_t RESERVED4[1]; /*!< Reserved, Address offset: 0x5C */ + __IO uint32_t AFCC1R; /*!< GFXTIM absolute frame counter compare 1 register, Address offset: 0x60 */ + uint32_t RESERVED5[3]; /*!< Reserved, Address offset: 0x64-0X6C */ + __IO uint32_t ALCC1R; /*!< GFXTIM absolute line counter compare 1 register, Address offset: 0x70 */ + __IO uint32_t ALCC2R; /*!< GFXTIM absolute line counter compare 2 register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, Address offset: 0x78-0X7C */ + __IO uint32_t RFC1R; /*!< GFXTIM relative frame counter 1 register, Address offset: 0x80 */ + __IO uint32_t RFC1RR; /*!< GFXTIM relative frame counter 1 reload register, Address offset: 0x84 */ + __IO uint32_t RFC2R; /*!< GFXTIM relative frame counter 2 register, Address offset: 0x88 */ + __IO uint32_t RFC2RR; /*!< GFXTIM relative frame counter 2 reload register, Address offset: 0x8C */ + uint32_t RESERVED7[4]; /*!< Reserved, Address offset: 0x90-0X9C */ + __IO uint32_t WDGCR; /*!< GFXTIM watchdog counter register, Address offset: 0xA0 */ + __IO uint32_t WDGRR; /*!< GFXTIM watchdog reload register, Address offset: 0xA4 */ + __IO uint32_t WDGPAR; /*!< GFXTIM watchdog pre-alarm register, Address offset: 0xA8 */ + uint32_t RESERVED8[209]; /*!< Reserved, Address offset: 0xAC-0X3EC */ + __IO uint32_t HWCFGR; /*!< GFXTIM HW configuration register, Address offset: 0x3F0 */ + __IO uint32_t VERR; /*!< GFXTIM version register, Address offset: 0x3F4 */ + __IO uint32_t IPIDR; /*!< GFXTIM identification register, Address offset: 0x3F8 */ + __IO uint32_t SIDR; /*!< GFXTIM size identification register, Address offset: 0x3FC */ +} GFXTIM_TypeDef; + + +/** + * @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 RESERVED1; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ + __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ +} CRC_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 Cryp Processor + */ +typedef struct +{ + __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ + __IO uint32_t DIN; /*!< CRYP data input register, Address offset: 0x08 */ + __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ + __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ + __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ + __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ + __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ + __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ + __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ + __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ + __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ + __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ + __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ + __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ + __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ + __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ + __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ + __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ + __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ + __IO uint32_t CSGCMCCM0R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 0, Address offset: 0x50 */ + __IO uint32_t CSGCMCCM1R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 1, Address offset: 0x54 */ + __IO uint32_t CSGCMCCM2R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 2, Address offset: 0x58 */ + __IO uint32_t CSGCMCCM3R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 3, Address offset: 0x5C */ + __IO uint32_t CSGCMCCM4R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 4, Address offset: 0x60 */ + __IO uint32_t CSGCMCCM5R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 5, Address offset: 0x64 */ + __IO uint32_t CSGCMCCM6R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 6, Address offset: 0x68 */ + __IO uint32_t CSGCMCCM7R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 7, Address offset: 0x6C */ + __IO uint32_t CSGCM0R; /*!< CRYP GCM/GMAC context swap register 0, Address offset: 0x70 */ + __IO uint32_t CSGCM1R; /*!< CRYP GCM/GMAC context swap register 1, Address offset: 0x74 */ + __IO uint32_t CSGCM2R; /*!< CRYP GCM/GMAC context swap register 2, Address offset: 0x78 */ + __IO uint32_t CSGCM3R; /*!< CRYP GCM/GMAC context swap register 3, Address offset: 0x7C */ + __IO uint32_t CSGCM4R; /*!< CRYP GCM/GMAC context swap register 4, Address offset: 0x80 */ + __IO uint32_t CSGCM5R; /*!< CRYP GCM/GMAC context swap register 5, Address offset: 0x84 */ + __IO uint32_t CSGCM6R; /*!< CRYP GCM/GMAC context swap register 6, Address offset: 0x88 */ + __IO uint32_t CSGCM7R; /*!< CRYP GCM/GMAC context swap register 7, Address offset: 0x8C */ +} CRYP_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 */ + uint32_t RESERVED1[5]; /*!< Reserved, Address offset: 0x08-0x18 */ + __IO uint32_t AHB5FZR; /*!< Debug MCU AHB5FZR freeze register, Address offset: 0x1C */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t AHB1FZR; /*!< Debug MCU AHB1FZR freeze register, Address offset: 0x24 */ + uint32_t RESERVED3[5]; /*!< Reserved, Address offset: 0x28-0x38 */ + __IO uint32_t APB1FZR; /*!< Debug MCU APB1FZR freeze register, Address offset: 0x3C */ + uint32_t RESERVED4[3]; /*!< Reserved, Address offset: 0x40-0x48 */ + __IO uint32_t APB2FZR; /*!< Debug MCU APB2FZR freeze register, Address offset: 0x4C */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x50 */ + __IO uint32_t APB4FZR; /*!< Debug MCU APB4FZR freeze register, Address offset: 0x54 */ + uint32_t RESERVED6[41]; /*!< Reserved, Address offset: 0x58-0xF8 */ + __IO uint32_t SR; /*!< Debug MCU status register, Address offset: 0xFC */ + __IO uint32_t DBG_AUTH_HOST; /*!< Debug MCU Authentication Host register, Address offset: 0x100 */ + __IO uint32_t DBG_AUTH_DEV; /*!< Debug MCU Authentication Device register, Address offset: 0x104 */ + __IO uint32_t DBG_AUTH_ACK; /*!< Debug MCU Authentication Ack register, Address offset: 0x108 */ + uint32_t RESERVED7[945]; /*!< Reserved, Address offset: 0x10C-0xFCC */ + __IO uint32_t PIDR4; /*!< Debug MCU peripheral identity register 4, Address offset: 0xFD0 */ + uint32_t RESERVED8[3]; /*!< Reserved, Address offset: 0xFD4-0xFDC */ + __IO uint32_t PIDR0; /*!< Debug MCU peripheral identity register 0, Address offset: 0xFE0 */ + __IO uint32_t PIDR1; /*!< Debug MCU peripheral identity register 1, Address offset: 0xFE4 */ + __IO uint32_t PIDR2; /*!< Debug MCU peripheral identity register 2, Address offset: 0xFE8 */ + __IO uint32_t PIDR3; /*!< Debug MCU peripheral identity register 3, Address offset: 0xFEC */ + __IO uint32_t CIDR0; /*!< Debug MCU component identity register 0, Address offset: 0xFF0 */ + __IO uint32_t CIDR1; /*!< Debug MCU component identity register 1, Address offset: 0xFF4 */ + __IO uint32_t CIDR2; /*!< Debug MCU component identity register 2, Address offset: 0xFF8 */ + __IO uint32_t CIDR3; /*!< Debug MCU component identity register 3, Address offset: 0xFFC */ +} DBGMCU_TypeDef; + +/** + * @brief DCMIPP + */ +typedef struct +{ + __IO uint32_t IPGR1; /*!< IP-Plug global register 1 Address offset: 0x00 */ + __IO uint32_t IPGR2; /*!< IP-Plug global register 2 Address offset: 0x04 */ + __IO uint32_t IPGR3; /*!< IP-Plug global register 3 Address offset: 0x08 */ + uint32_t RESERVED1[4]; /*!< Reserved, Address offset: 0x0C-0x18 */ + __IO uint32_t IPGR8; /*!< IP-Plug global register 8 Address offset: 0x1C */ + __IO uint32_t IPC1R1; /*!< IP-Plug client 1 register 1 Address offset: 0x20 */ + __IO uint32_t IPC1R2; /*!< IP-Plug client 1 register 2 Address offset: 0x24 */ + __IO uint32_t IPC1R3; /*!< IP-Plug client 1 register 3 Address offset: 0x28 */ + __IO uint32_t RESERVED2[54]; /*!< Reserved, Address offset: 0x2C-0x100 */ + __IO uint32_t PRCR; /*!< Parallel interface control register Address offset: 0x104 */ + __IO uint32_t PRESCR; /*!< Parallel interface embedded sync code register Address offset: 0x108 */ + __IO uint32_t PRESUR; /*!< Parallel interface embedded sync unmask register Address offset: 0x10C */ + __IO uint32_t RESERVED3[57]; /*!< Reserved, Address offset: 0x110-0x1F0 */ + __IO uint32_t PRIER; /*!< Parallel interface interrupt enable register Address offset: 0x1F4 */ + __IO uint32_t PRSR; /*!< Parallel interface status register Address offset: 0x1F8 */ + __IO uint32_t PRFCR; /*!< Parallel interface interrupt clear register Address offset: 0x1FC */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x200 */ + __IO uint32_t CMCR; /*!< Common configuration register Address offset: 0x204 */ + __IO uint32_t CMFRCR; /*!< Common frame counter register Address offset: 0x208 */ + __IO uint32_t RESERVED5[121]; /*!< Reserved, Address offset: 0x20C-0x3EC */ + __IO uint32_t CMIER; /*!< Common interrupt enable register Address offset: 0x3F0 */ + __IO uint32_t CMSR1; /*!< Common status register 1 Address offset: 0x3F4 */ + __IO uint32_t CMSR2; /*!< Common status register 2 Address offset: 0x3F8 */ + __IO uint32_t CMFCR; /*!< Common interrupt clear register Address offset: 0x3FC */ + uint32_t RESERVED6; /*!< Reserved, Address offset: 0x400 */ + __IO uint32_t P0FSCR; /*!< Pipe0 flow selection configuration register Address offset: 0x404 */ + __IO uint32_t RESERVED7[62]; /*!< Reserved, Address offset: 0x408-0x4FC */ + __IO uint32_t P0FCTCR; /*!< Pipe0 flow control configuration register Address offset: 0x500 */ + __IO uint32_t P0SCSTR; /*!< Pipe0 stat/crop start register Address offset: 0x504 */ + __IO uint32_t P0SCSZR; /*!< Pipe0 stat/crop size register Address offset: 0x508 */ + __IO uint32_t RESERVED8[41]; /*!< Reserved, Address offset: 0x50C-0x5AC */ + __IO uint32_t P0DCCNTR; /*!< Pipe0 dump counter register Address offset: 0x5B0 */ + __IO uint32_t P0DCLMTR; /*!< Pipe0 dump limit register Address offset: 0x5B4 */ + __IO uint32_t RESERVED9[2]; /*!< Reserved, Address offset: 0x5B8-0x5BC */ + __IO uint32_t P0PPCR; /*!< Pipe0 pixel packer configuration register Address offset: 0x5C0 */ + __IO uint32_t P0PPM0AR1; /*!< Pipe0 pixel packer memory0 address register 1 Address offset: 0x5C4 */ + __IO uint32_t P0PPM0AR2; /*!< Pipe0 pixel packer memory0 address register 2 Address offset: 0x5C8 */ + __IO uint32_t RESERVED10[10]; /*!< Reserved, Address offset: 0x5CC-0x5F0 */ + __IO uint32_t P0IER; /*!< Pipe0 interrupt enable register Address offset: 0x5F4 */ + __IO uint32_t P0SR; /*!< Pipe0 status register Address offset: 0x5F8 */ + __IO uint32_t P0FCR; /*!< Pipe0 interrupt clear register Address offset: 0x5FC */ + __IO uint32_t RESERVED11[64]; /*!< Reserved, Address offset: 0x600-0x6FC */ + __IO uint32_t P0CFCTCR; /*!< Pipe0 current flow control configuration register Address offset: 0x700 */ + __IO uint32_t P0CSCSTR; /*!< Pipe0 current stat/crop start register Address offset: 0x704 */ + __IO uint32_t P0CSCSZR; /*!< Pipe0 current stat/crop size register Address offset: 0x708 */ + __IO uint32_t RESERVED12[45]; /*!< Reserved, Address offset: 0x70C-0x7BC */ + __IO uint32_t P0CPPCR; /*!< Pipe0 current pixel packer configuration register Address offset: 0x700 */ + __IO uint32_t P0CPPM0AR1; /*!< Pipe0 current pixel packer memory0 address register 1 Address offset: 0x7C4 */ + __IO uint32_t P0CPPM0AR2; /*!< Pipe0 current pixel packer memory0 address register 2 Address offset: 0x7C8 */ +} DCMIPP_TypeDef; + +/** + * @ brief Delay Block + */ +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 DMA Controller + */ +typedef struct +{ + uint32_t RESERVED1; /*!< Reserved 1, Address offset: 0x00 */ + __IO uint32_t PRIVCFGR; /*!< DMA privileged configuration register, Address offset: 0x04 */ + __IO uint32_t RCFGLOCKR; /*!< DMA configuration lock register, Address offset: 0x08 */ + __IO uint32_t MISR; /*!< DMA masked interrupt status register, Address offset: 0x0C */ +} 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 DMA2D Controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< DMA2D Control Register, Address offset: 0x00 */ + __IO uint32_t ISR; /*!< DMA2D Interrupt Status Register, Address offset: 0x04 */ + __IO uint32_t IFCR; /*!< DMA2D Interrupt Flag Clear Register, Address offset: 0x08 */ + __IO uint32_t FGMAR; /*!< DMA2D Foreground Memory Address Register, Address offset: 0x0C */ + __IO uint32_t FGOR; /*!< DMA2D Foreground Offset Register, Address offset: 0x10 */ + __IO uint32_t BGMAR; /*!< DMA2D Background Memory Address Register, Address offset: 0x14 */ + __IO uint32_t BGOR; /*!< DMA2D Background Offset Register, Address offset: 0x18 */ + __IO uint32_t FGPFCCR; /*!< DMA2D Foreground PFC Control Register, Address offset: 0x1C */ + __IO uint32_t FGCOLR; /*!< DMA2D Foreground Color Register, Address offset: 0x20 */ + __IO uint32_t BGPFCCR; /*!< DMA2D Background PFC Control Register, Address offset: 0x24 */ + __IO uint32_t BGCOLR; /*!< DMA2D Background Color Register, Address offset: 0x28 */ + __IO uint32_t FGCMAR; /*!< DMA2D Foreground CLUT Memory Address Register, Address offset: 0x2C */ + __IO uint32_t BGCMAR; /*!< DMA2D Background CLUT Memory Address Register, Address offset: 0x30 */ + __IO uint32_t OPFCCR; /*!< DMA2D Output PFC Control Register, Address offset: 0x34 */ + __IO uint32_t OCOLR; /*!< DMA2D Output Color Register, Address offset: 0x38 */ + __IO uint32_t OMAR; /*!< DMA2D Output Memory Address Register, Address offset: 0x3C */ + __IO uint32_t OOR; /*!< DMA2D Output Offset Register, Address offset: 0x40 */ + __IO uint32_t NLR; /*!< DMA2D Number of Line Register, Address offset: 0x44 */ + __IO uint32_t LWR; /*!< DMA2D Line Watermark Register, Address offset: 0x48 */ + __IO uint32_t AMTCR; /*!< DMA2D AHB Master Timer Configuration Register, Address offset: 0x4C */ + uint32_t RESERVED[236]; /*!< Reserved, Address offset: 0x50-0x3FF */ + __IO uint32_t FGCLUT[256]; /*!< DMA2D Foreground CLUT, Address offset:0x400-0x7FF */ + __IO uint32_t BGCLUT[256]; /*!< DMA2D Background CLUT, Address offset:0x800-0xBFF */ +} DMA2D_TypeDef; + +/** + * @brief DTS + */ +typedef struct +{ + __IO uint32_t CFGR1; /*!< DTS configuration register, Address offset: 0x00 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x04 */ + __IO uint32_t T0VALR1; /*!< DTS T0 Value register, Address offset: 0x08 */ + uint32_t RESERVED1; /*!< Reserved, Address offset: 0x0C */ + __IO uint32_t RAMPVALR; /*!< DTS Ramp value register, Address offset: 0x10 */ + __IO uint32_t ITR1; /*!< DTS Interrupt threshold register, Address offset: 0x14 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x18 */ + __IO uint32_t DR; /*!< DTS data register, Address offset: 0x1C */ + __IO uint32_t SR; /*!< DTS status register Address offset: 0x20 */ + __IO uint32_t ITENR; /*!< DTS Interrupt enable register, Address offset: 0x24 */ + __IO uint32_t ICIFR; /*!< DTS Clear Interrupt flag register, Address offset: 0x28 */ + __IO uint32_t OR; /*!< DTS option register 1, Address offset: 0x2C */ +} DTS_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 External Interrupt/Event Controller + */ +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 */ + uint32_t RESERVED1[5]; /*!< Reserved 1, Address offset: 0x0C-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 */ + uint32_t RESERVED2[21]; /*!< Reserved 2, Address offset: 0x2C-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 */ + __IO uint32_t PR1; /*!< EXTI Pending register 1, Address offset: 0x88 */ + uint32_t RESERVED3; /*!< Reserved 3, Address offset: 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 */ + __IO uint32_t PR2; /*!< EXTI Pending register 2, Address offset: 0x98 */ + uint32_t RESERVED4; /*!< Reserved 4, Address offset: 0x9C */ + __IO uint32_t IMR3; /*!< EXTI Interrupt mask register 3, Address offset: 0xA0 */ + __IO uint32_t EMR3; /*!< EXTI Event mask register 3, Address offset: 0xA4 */ +} EXTI_TypeDef; + +/** + * @brief FD Controller Area Network + */ +typedef struct +{ + __IO uint32_t CREL; /*!< FDCAN Core Release register, Address offset: 0x000 */ + __IO uint32_t ENDN; /*!< FDCAN Endian register, Address offset: 0x004 */ + uint32_t RESERVED1; /*!< Reserved, 0x008 */ + __IO uint32_t DBTP; /*!< FDCAN Data Bit Timing & Prescaler register, Address offset: 0x00C */ + __IO uint32_t TEST; /*!< FDCAN Test register, Address offset: 0x010 */ + __IO uint32_t RWD; /*!< FDCAN RAM Watchdog register, Address offset: 0x014 */ + __IO uint32_t CCCR; /*!< FDCAN CC Control register, Address offset: 0x018 */ + __IO uint32_t NBTP; /*!< FDCAN Nominal Bit Timing & Prescaler register, Address offset: 0x01C */ + __IO uint32_t TSCC; /*!< FDCAN Timestamp Counter Configuration register, Address offset: 0x020 */ + __IO uint32_t TSCV; /*!< FDCAN Timestamp Counter Value register, Address offset: 0x024 */ + __IO uint32_t TOCC; /*!< FDCAN Timeout Counter Configuration register, Address offset: 0x028 */ + __IO uint32_t TOCV; /*!< FDCAN Timeout Counter Value register, Address offset: 0x02C */ + uint32_t RESERVED2[4]; /*!< Reserved, 0x030 - 0x03C */ + __IO uint32_t ECR; /*!< FDCAN Error Counter register, Address offset: 0x040 */ + __IO uint32_t PSR; /*!< FDCAN Protocol Status register, Address offset: 0x044 */ + __IO uint32_t TDCR; /*!< FDCAN Transmitter Delay Compensation register, Address offset: 0x048 */ + uint32_t RESERVED3; /*!< Reserved, 0x04C */ + __IO uint32_t IR; /*!< FDCAN Interrupt register, Address offset: 0x050 */ + __IO uint32_t IE; /*!< FDCAN Interrupt Enable register, Address offset: 0x054 */ + __IO uint32_t ILS; /*!< FDCAN Interrupt Line Select register, Address offset: 0x058 */ + __IO uint32_t ILE; /*!< FDCAN Interrupt Line Enable register, Address offset: 0x05C */ + uint32_t RESERVED4[8]; /*!< Reserved, 0x060 - 0x07C */ + __IO uint32_t RXGFC; /*!< FDCAN Global Filter Configuration register, Address offset: 0x080 */ + __IO uint32_t XIDAM; /*!< FDCAN Extended ID AND Mask register, Address offset: 0x084 */ + __IO uint32_t HPMS; /*!< FDCAN High Priority Message Status register, Address offset: 0x088 */ + uint32_t RESERVED5; /*!< Reserved, 0x08C */ + __IO uint32_t RXF0S; /*!< FDCAN Rx FIFO 0 Status register, Address offset: 0x090 */ + __IO uint32_t RXF0A; /*!< FDCAN Rx FIFO 0 Acknowledge register, Address offset: 0x094 */ + __IO uint32_t RXF1S; /*!< FDCAN Rx FIFO 1 Status register, Address offset: 0x098 */ + __IO uint32_t RXF1A; /*!< FDCAN Rx FIFO 1 Acknowledge register, Address offset: 0x09C */ + uint32_t RESERVED6[8]; /*!< Reserved, 0x0A0 - 0x0BC */ + __IO uint32_t TXBC; /*!< FDCAN Tx Buffer Configuration register, Address offset: 0x0C0 */ + __IO uint32_t TXFQS; /*!< FDCAN Tx FIFO/Queue Status register, Address offset: 0x0C4 */ + __IO uint32_t TXBRP; /*!< FDCAN Tx Buffer Request Pending register, Address offset: 0x0C8 */ + __IO uint32_t TXBAR; /*!< FDCAN Tx Buffer Add Request register, Address offset: 0x0CC */ + __IO uint32_t TXBCR; /*!< FDCAN Tx Buffer Cancellation Request register, Address offset: 0x0D0 */ + __IO uint32_t TXBTO; /*!< FDCAN Tx Buffer Transmission Occurred register, Address offset: 0x0D4 */ + __IO uint32_t TXBCF; /*!< FDCAN Tx Buffer Cancellation Finished register, Address offset: 0x0D8 */ + __IO uint32_t TXBTIE; /*!< FDCAN Tx Buffer Transmission Interrupt Enable register, Address offset: 0x0DC */ + __IO uint32_t TXBCIE; /*!< FDCAN Tx Buffer Cancellation Finished Interrupt Enable register, Address offset: 0x0E0 */ + __IO uint32_t TXEFS; /*!< FDCAN Tx Event FIFO Status register, Address offset: 0x0E4 */ + __IO uint32_t TXEFA; /*!< FDCAN Tx Event FIFO Acknowledge register, Address offset: 0x0E8 */ +} FDCAN_GlobalTypeDef; + +/** + * @brief FD Controller Area Network Configuration + */ +typedef struct +{ + __IO uint32_t CKDIV; /*!< FDCAN clock divider register, Address offset: 0x100 + 0x000 */ + uint32_t RESERVED1[128];/*!< Reserved, 0x100 + 0x004 - 0x100 + 0x200 */ + __IO uint32_t OPTR; /*!< FDCAN option register, Address offset: 0x100 + 0x204 */ + uint32_t RESERVED2[58]; /*!< Reserved, 0x100 + 0x208 - 0x100 + 0x2EC */ + __IO uint32_t HWCFG; /*!< FDCAN hardware configuration register, Address offset: 0x100 + 0x2F0 */ + __IO uint32_t VERR; /*!< FDCAN IP version register, Address offset: 0x100 + 0x2F4 */ + __IO uint32_t IPIDR; /*!< FDCAN IP ID register, Address offset: 0x100 + 0x2F8 */ + __IO uint32_t SIDR; /*!< FDCAN size ID register, Address offset: 0x100 + 0x2FC */ +} FDCAN_Config_TypeDef; + +/** + * @brief FLASH Registers + */ +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x000 */ + __IO uint32_t KEYR; /*!< FLASH control key register, Address offset: 0x004 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x008 - 0x00C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x010 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x014 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x018 - 0x01C */ + __IO uint32_t IER; /*!< FLASH interrupt enable register, Address offset: 0x020 */ + __IO uint32_t ISR; /*!< FLASH interrupt status register, Address offset: 0x024 */ + __IO uint32_t ICR; /*!< FLASH interrupt clear register, Address offset: 0x028 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x02C */ + __IO uint32_t CRCCR; /*!< FLASH CRC control register, Address offset: 0x030 */ + __IO uint32_t CRCSADDR; /*!< FLASH CRC start address register, Address offset: 0x034 */ + __IO uint32_t CRCEADDR; /*!< FLASH CRC end address register, Address offset: 0x038 */ + __IO uint32_t CRCDATAR; /*!< FLASH CRC data register, Address offset: 0x03C */ + __IO uint32_t ECCSFADDR; /*!< FLASH ECC single fail address register, Address offset: 0x040 */ + __IO uint32_t ECCDFADDR; /*!< FLASH ECC double fail address register, Address offset: 0x044 */ + uint32_t RESERVED4[46]; /*!< Reserved, Address offset: 0x048 - 0x0FC */ + __IO uint32_t OPTKEYR; /*!< FLASH options key register, Address offset: 0x100 */ + __IO uint32_t OPTCR; /*!< FLASH options control register, Address offset: 0x104 */ + __IO uint32_t OPTISR; /*!< FLASH options interrupt status register, Address offset: 0x108 */ + __IO uint32_t OPTICR; /*!< FLASH options interrupt clear register, Address offset: 0x10C */ + __IO uint32_t OBKCR; /*!< FLASH option byte key control register, Address offset: 0x110 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x114 */ + __IO uint32_t OBKDR[8]; /*!< FLASH option bytes key data register, Address offset: 0x118 - 0x134 */ + uint32_t RESERVED6[50]; /*!< Reserved, Address offset: 0x138 - 0x1FC */ + __IO uint32_t NVSR; /*!< FLASH non-volatile status register, Address offset: 0x200 */ + __IO uint32_t NVSRP; /*!< FLASH security status register programming, Address offset: 0x204 */ + __IO uint32_t ROTSR; /*!< FLASH RoT status register, Address offset: 0x208 */ + __IO uint32_t ROTSRP; /*!< FLASH RoT status register programming, Address offset: 0x20C */ + __IO uint32_t OTPLSR; /*!< FLASH OTP lock status register, Address offset: 0x210 */ + __IO uint32_t OTPLSRP; /*!< FLASH OTP lock status programming register, Address offset: 0x214 */ + __IO uint32_t WRPSR; /*!< FLASH write protection status register, Address offset: 0x218 */ + __IO uint32_t WRPSRP; /*!< FLASH write protection status register programming, Address offset: 0x21C */ + uint32_t RESERVED7[4]; /*!< Reserved, Address offset: 0x220 - 0x22C */ + __IO uint32_t HDPSR; /*!< FLASH hide protection status register, Address offset: 0x230 */ + __IO uint32_t HDPSRP; /*!< FLASH hide protection status register programming, Address offset: 0x234 */ + uint32_t RESERVED8[6]; /*!< Reserved, Address offset: 0x238 - 0x24C */ + __IO uint32_t EPOCHSR; /*!< FLASH epoch status register, Address offset: 0x250 */ + __IO uint32_t EPOCHSRP; /*!< FLASH epoch status register programming, Address offset: 0x254 */ + uint32_t RESERVED9[2]; /*!< Reserved, Address offset: 0x258 - 0x25C */ + __IO uint32_t OBW1SR; /*!< FLASH option byte word 1 status register, Address offset: 0x260 */ + __IO uint32_t OBW1SRP; /*!< FLASH option byte word 1 status register programming, Address offset: 0x264 */ + __IO uint32_t OBW2SR; /*!< FLASH option byte word 2 status register, Address offset: 0x268 */ + __IO uint32_t OBW2SRP; /*!< FLASH option byte word 2 status register programming, Address offset: 0x26C */ +} FLASH_TypeDef; + +/** + * @brief Flexible Memory Controller Bank1 + */ +typedef struct { + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FMC_Bank1_TypeDef; + +/** + * @brief Flexible Memory Controller Bank1 Extended + */ +typedef struct { + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FMC_Bank1E_TypeDef; + +/** + * @brief Flexible Memory Controller Bank3 + */ +typedef struct { + __IO uint32_t PCR; /*!< NAND Flash control register, Address offset: 0x80 */ + __IO uint32_t SR; /*!< NAND Flash FIFO status and interrupt register, Address offset: 0x84 */ + __IO uint32_t PMEM; /*!< NAND Flash Common memory space timing register, Address offset: 0x88 */ + __IO uint32_t PATT; /*!< NAND Flash Attribute memory space timing register, Address offset: 0x8C */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x90 */ + __IO uint32_t ECCR; /*!< NAND Flash ECC result registers, Address offset: 0x94 */ +} FMC_Bank3_TypeDef; + +/** + * @brief Flexible Memory Controller Bank5 & 6 + */ +typedef struct +{ + __IO uint32_t SDCR[2]; /*!< SDRAM Control registers , Address offset: 0x140 - 0x144 */ + __IO uint32_t SDTR[2]; /*!< SDRAM Timing registers , Address offset: 0x148 - 0x14C */ + __IO uint32_t SDCMR; /*!< SDRAM Command Mode register, Address offset: 0x150 */ + __IO uint32_t SDRTR; /*!< SDRAM Refresh Timer register, Address offset: 0x154 */ + __IO uint32_t SDSR; /*!< SDRAM Status register, Address offset: 0x158 */ +} FMC_Bank5_6_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 */ +} GPIO_TypeDef; + +/** + * @brief GFXMMU + */ +typedef struct +{ + __IO uint32_t CR; /*!< GFXMMU configuration register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< GFXMMU status register, Address offset: 0x04 */ + __IO uint32_t FCR; /*!< GFXMMU flag clear register, Address offset: 0x08 */ + uint32_t RESERVED0; /*!< Reserved0, Address offset: 0x0C */ + __IO uint32_t DVR; /*!< GFXMMU default value register, Address offset: 0x10 */ + __IO uint32_t DAR; /*!< GFXMMU default alpha register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved1, Address offset: 0x18 to 0x1C */ + __IO uint32_t B0CR; /*!< GFXMMU buffer 0 configuration register, Address offset: 0x20 */ + __IO uint32_t B1CR; /*!< GFXMMU buffer 1 configuration register, Address offset: 0x24 */ + __IO uint32_t B2CR; /*!< GFXMMU buffer 2 configuration register, Address offset: 0x28 */ + __IO uint32_t B3CR; /*!< GFXMMU buffer 3 configuration register, Address offset: 0x2C */ + uint32_t RESERVED2[1012]; /*!< Reserved2, Address offset: 0x30 to 0xFFC */ + __IO uint32_t LUT[2048]; /*!< GFXMMU LUT registers, Address offset: 0x1000 to 0x2FFC + For LUT line i, LUTiL = LUT[2*i] and LUTiH = LUT[(2*i)+1] */ +} GFXMMU_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 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 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 IWDG + */ +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ + __IO uint32_t WINR; /*!< IWDG Window register, Address offset: 0x10 */ + __IO uint32_t EWCR; /*!< IWDG Early Wakeup register, Address offset: 0x14 */ +} IWDG_TypeDef; + +/** + * @brief JPEG Codec + */ +typedef struct +{ + __IO uint32_t CONFR0; /*!< JPEG Codec Control Register (JPEG_CONFR0), Address offset: 0x00 */ + __IO uint32_t CONFR1; /*!< JPEG Codec Control Register (JPEG_CONFR1), Address offset: 0x04 */ + __IO uint32_t CONFR2; /*!< JPEG Codec Control Register (JPEG_CONFR2), Address offset: 0x08 */ + __IO uint32_t CONFR3; /*!< JPEG Codec Control Register (JPEG_CONFR3), Address offset: 0x0C */ + __IO uint32_t CONFR4; /*!< JPEG Codec Control Register (JPEG_CONFR4), Address offset: 0x10 */ + __IO uint32_t CONFR5; /*!< JPEG Codec Control Register (JPEG_CONFR5), Address offset: 0x14 */ + __IO uint32_t CONFR6; /*!< JPEG Codec Control Register (JPEG_CONFR6), Address offset: 0x18 */ + __IO uint32_t CONFR7; /*!< JPEG Codec Control Register (JPEG_CONFR7), Address offset: 0x1C */ + uint32_t RESERVED0[4]; /* Reserved Address offset: 0x20-0x2C */ + __IO uint32_t CR; /*!< JPEG Control Register (JPEG_CR), Address offset: 0x30 */ + __IO uint32_t SR; /*!< JPEG Status Register (JPEG_SR), Address offset: 0x34 */ + __IO uint32_t CFR; /*!< JPEG Clear Flag Register (JPEG_CFR), Address offset: 0x38 */ + uint32_t RESERVED1; /* Reserved Address offset: 0x3C */ + __IO uint32_t DIR; /*!< JPEG Data Input Register (JPEG_DIR), Address offset: 0x40 */ + __IO uint32_t DOR; /*!< JPEG Data Output Register (JPEG_DOR), Address offset: 0x44 */ + uint32_t RESERVED2[2]; /* Reserved Address offset: 0x48-0x4C */ + __IO uint32_t QMEM0[16]; /*!< JPEG quantization tables 0, Address offset: 0x50-0x8C */ + __IO uint32_t QMEM1[16]; /*!< JPEG quantization tables 1, Address offset: 0x90-0xCC */ + __IO uint32_t QMEM2[16]; /*!< JPEG quantization tables 2, Address offset: 0xD0-0x10C */ + __IO uint32_t QMEM3[16]; /*!< JPEG quantization tables 3, Address offset: 0x110-0x14C */ + __IO uint32_t HUFFMIN[16]; /*!< JPEG HuffMin tables, Address offset: 0x150-0x18C */ + __IO uint32_t HUFFBASE[32]; /*!< JPEG HuffSymb tables, Address offset: 0x190-0x20C */ + __IO uint32_t HUFFSYMB[84]; /*!< JPEG HUFFSYMB tables, Address offset: 0x210-0x35C */ + __IO uint32_t DHTMEM[103]; /*!< JPEG DHTMem tables, Address offset: 0x360-0x4F8 */ + uint32_t RESERVED3; /* Reserved Address offset: 0x4FC */ + __IO uint32_t HUFFENC_AC0[88]; /*!< JPEG encodor, AC Huffman table 0, Address offset: 0x500-0x65C */ + __IO uint32_t HUFFENC_AC1[88]; /*!< JPEG encodor, AC Huffman table 1, Address offset: 0x660-0x7BC */ + __IO uint32_t HUFFENC_DC0[8]; /*!< JPEG encodor, DC Huffman table 0, Address offset: 0x7C0-0x7DC */ + __IO uint32_t HUFFENC_DC1[8]; /*!< JPEG encodor, DC Huffman table 1, Address offset: 0x7E0-0x7FC */ +} JPEG_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 Memory Cipher Engine (MCE) + */ +typedef struct +{ + __IO uint32_t REGCR; /*!< MCE region configuration register, Address offset: 0x040 + 0x10 * (x-1) (x = 1 to 4) */ + __IO uint32_t SADDR; /*!< MCE region start address register, Address offset: 0x044 + 0x10 * (x-1) (x = 1 to 4) */ + __IO uint32_t EADDR; /*!< MCE region end address register, Address offset: 0x048 + 0x10 * (x-1) (x = 1 to 4) */ + __IO uint32_t ATTR; /*!< MCE region attribute register, Address offset: 0x04C + 0x10 * (x-1) (x = 1 to 4) */ +} MCE_Region_TypeDef; + +typedef struct +{ + __IO uint32_t CCCFGR; /*!< MCE cipher context configuration register, Address offset: 0x240 + 0x30 * (x-1) (x = 1 to 2) */ + __IO uint32_t CCNR0; /*!< MCE cipher context nonce register 0, Address offset: 0x244 + 0x30 * (x-1) (x = 1 to 2) */ + __IO uint32_t CCNR1; /*!< MCE cipher context nonce register 1, Address offset: 0x248 + 0x30 * (x-1) (x = 1 to 2) */ + __IO uint32_t CCKEYR0; /*!< MCE cipher context key register 0, Address offset: 0x24C + 0x30 * (x-1) (x = 1 to 2) */ + __IO uint32_t CCKEYR1; /*!< MCE cipher context key register 1, Address offset: 0x250 + 0x30 * (x-1) (x = 1 to 2) */ + __IO uint32_t CCKEYR2; /*!< MCE cipher context key register 2, Address offset: 0x254 + 0x30 * (x-1) (x = 1 to 2) */ + __IO uint32_t CCKEYR3; /*!< MCE cipher context key register 3, Address offset: 0x258 + 0x30 * (x-1) (x = 1 to 2) */ +} MCE_Context_TypeDef; + +typedef struct +{ + __IO uint32_t CR; /*!< MCE configuration register, Address offset: 0x000 */ + __IO uint32_t SR; /*!< MCE status register, Address offset: 0x004 */ + __IO uint32_t IASR; /*!< MCE illegal access status register, Address offset: 0x008 */ + __IO uint32_t IACR; /*!< MCE illegal access clear register, Address offset: 0x00C */ + __IO uint32_t IAIER; /*!< MCE illegal access interrupt enable register, Address offset: 0x010 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x014-0x018 */ + __IO uint32_t PRIVCFGR; /*!< MCE privileged configuration register, Address offset: 0x01C */ + __IO uint32_t IAESR; /*!< MCE illegal access error status register, Address offset: 0x020 */ + __IO uint32_t IADDR; /*!< MCE illegal address register, Address offset: 0x024 */ + uint32_t RESERVED2[118]; /*!< Reserved, Address offset: 0x028-0x1FC */ + __IO uint32_t MKEYR0; /*!< MCE master key register 0, Address offset: 0x200 */ + __IO uint32_t MKEYR1; /*!< MCE master key register 1, Address offset: 0x204 */ + __IO uint32_t MKEYR2; /*!< MCE master key register 2, Address offset: 0x208 */ + __IO uint32_t MKEYR3; /*!< MCE master key register 3, Address offset: 0x20C */ + uint32_t RESERVED3[4]; /*!< Reserved, Address offset: 0x210-0x21C */ + __IO uint32_t FMKEYR0; /*!< MCE fast master key register 0, Address offset: 0x220 */ + __IO uint32_t FMKEYR1; /*!< MCE fast master key register 1, Address offset: 0x224 */ + __IO uint32_t FMKEYR2; /*!< MCE fast master key register 2, Address offset: 0x228 */ + __IO uint32_t FMKEYR3; /*!< MCE fast master key register 3, Address offset: 0x22C */ +} MCE_TypeDef; + +/** + * @brief MDIOS + */ + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t WRFR; + __IO uint32_t CWRFR; + __IO uint32_t RDFR; + __IO uint32_t CRDFR; + __IO uint32_t SR; + __IO uint32_t CLRFR; + uint32_t RESERVED[57]; + __IO uint32_t DINR0; + __IO uint32_t DINR1; + __IO uint32_t DINR2; + __IO uint32_t DINR3; + __IO uint32_t DINR4; + __IO uint32_t DINR5; + __IO uint32_t DINR6; + __IO uint32_t DINR7; + __IO uint32_t DINR8; + __IO uint32_t DINR9; + __IO uint32_t DINR10; + __IO uint32_t DINR11; + __IO uint32_t DINR12; + __IO uint32_t DINR13; + __IO uint32_t DINR14; + __IO uint32_t DINR15; + __IO uint32_t DINR16; + __IO uint32_t DINR17; + __IO uint32_t DINR18; + __IO uint32_t DINR19; + __IO uint32_t DINR20; + __IO uint32_t DINR21; + __IO uint32_t DINR22; + __IO uint32_t DINR23; + __IO uint32_t DINR24; + __IO uint32_t DINR25; + __IO uint32_t DINR26; + __IO uint32_t DINR27; + __IO uint32_t DINR28; + __IO uint32_t DINR29; + __IO uint32_t DINR30; + __IO uint32_t DINR31; + __IO uint32_t DOUTR0; + __IO uint32_t DOUTR1; + __IO uint32_t DOUTR2; + __IO uint32_t DOUTR3; + __IO uint32_t DOUTR4; + __IO uint32_t DOUTR5; + __IO uint32_t DOUTR6; + __IO uint32_t DOUTR7; + __IO uint32_t DOUTR8; + __IO uint32_t DOUTR9; + __IO uint32_t DOUTR10; + __IO uint32_t DOUTR11; + __IO uint32_t DOUTR12; + __IO uint32_t DOUTR13; + __IO uint32_t DOUTR14; + __IO uint32_t DOUTR15; + __IO uint32_t DOUTR16; + __IO uint32_t DOUTR17; + __IO uint32_t DOUTR18; + __IO uint32_t DOUTR19; + __IO uint32_t DOUTR20; + __IO uint32_t DOUTR21; + __IO uint32_t DOUTR22; + __IO uint32_t DOUTR23; + __IO uint32_t DOUTR24; + __IO uint32_t DOUTR25; + __IO uint32_t DOUTR26; + __IO uint32_t DOUTR27; + __IO uint32_t DOUTR28; + __IO uint32_t DOUTR29; + __IO uint32_t DOUTR30; + __IO uint32_t DOUTR31; +} MDIOS_TypeDef; + +/** + * @brief ADF + */ +typedef struct +{ + __IO uint32_t GCR; /*!< MDF Global Control register, Address offset: 0x00 */ + __IO uint32_t CKGCR; /*!< MDF Clock Generator Control Register, Address offset: 0x04 */ +} MDF_TypeDef; + +/** + * @brief ADF filter + */ +typedef struct +{ + __IO uint32_t SITFCR; /*!< MDF Serial Interface Control Register, Address offset: 0x80 */ + __IO uint32_t BSMXCR; /*!< MDF Bitstream Matrix Control Register, Address offset: 0x84 */ + __IO uint32_t DFLTCR; /*!< MDF Digital Filter Control Register, Address offset: 0x88 */ + __IO uint32_t DFLTCICR; /*!< MDF MCIC Configuration Register, Address offset: 0x8C */ + __IO uint32_t DFLTRSFR; /*!< MDF Reshape Filter Configuration Register, Address offset: 0x90 */ + uint32_t RESERVED0[4]; /*!< Reserved, 0x94-0xA0 */ + __IO uint32_t DLYCR; /*!< MDF Delay control Register, Address offset: 0xA4 */ + uint32_t RESERVED1[1]; /*!< Reserved, 0xA8 */ + __IO uint32_t DFLTIER; /*!< MDF DFLT Interrupt enable Register, Address offset: 0xAC */ + __IO uint32_t DFLTISR; /*!< MDF DFLT Interrupt status Register, Address offset: 0xB0 */ + uint32_t RESERVED2[1]; /*!< Reserved, 0xB4 */ + __IO uint32_t SADCR; /*!< MDF SAD Control Register, Address offset: 0xB8 */ + __IO uint32_t SADCFGR; /*!< MDF SAD configuration register, Address offset: 0xBC */ + __IO uint32_t SADSDLVR; /*!< MDF SAD Sound level Register, Address offset: 0xC0 */ + __IO uint32_t SADANLVR; /*!< MDF SAD Ambient Noise level Register, Address offset: 0xC4 */ + uint32_t RESERVED3[10]; /*!< Reserved, 0xC8-0xEC */ + __IO uint32_t DFLTDR; /*!< MDF Digital Filter Data Register, Address offset: 0xF0 */ +} MDF_Filter_TypeDef; + +/** + * @brief LCD-TFT Display Controller + */ + +typedef struct +{ + uint32_t RESERVED0[2]; /*!< Reserved, 0x00-0x04 */ + __IO uint32_t SSCR; /*!< LTDC Synchronization Size Configuration Register, Address offset: 0x08 */ + __IO uint32_t BPCR; /*!< LTDC Back Porch Configuration Register, Address offset: 0x0C */ + __IO uint32_t AWCR; /*!< LTDC Active Width Configuration Register, Address offset: 0x10 */ + __IO uint32_t TWCR; /*!< LTDC Total Width Configuration Register, Address offset: 0x14 */ + __IO uint32_t GCR; /*!< LTDC Global Control Register, Address offset: 0x18 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x1C-0x20 */ + __IO uint32_t SRCR; /*!< LTDC Shadow Reload Configuration Register, Address offset: 0x24 */ + uint32_t RESERVED2[1]; /*!< Reserved, 0x28 */ + __IO uint32_t BCCR; /*!< LTDC Background Color Configuration Register, Address offset: 0x2C */ + uint32_t RESERVED3[1]; /*!< Reserved, 0x30 */ + __IO uint32_t IER; /*!< LTDC Interrupt Enable Register, Address offset: 0x34 */ + __IO uint32_t ISR; /*!< LTDC Interrupt Status Register, Address offset: 0x38 */ + __IO uint32_t ICR; /*!< LTDC Interrupt Clear Register, Address offset: 0x3C */ + __IO uint32_t LIPCR; /*!< LTDC Line Interrupt Position Configuration Register, Address offset: 0x40 */ + __IO uint32_t CPSR; /*!< LTDC Current Position Status Register, Address offset: 0x44 */ + __IO uint32_t CDSR; /*!< LTDC Current Display Status Register, Address offset: 0x48 */ +} LTDC_TypeDef; + +/** + * @brief LCD-TFT Display layer x Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< LTDC Layerx Control Register Address offset: 0x84 */ + __IO uint32_t WHPCR; /*!< LTDC Layerx Window Horizontal Position Configuration Register Address offset: 0x88 */ + __IO uint32_t WVPCR; /*!< LTDC Layerx Window Vertical Position Configuration Register Address offset: 0x8C */ + __IO uint32_t CKCR; /*!< LTDC Layerx Color Keying Configuration Register Address offset: 0x90 */ + __IO uint32_t PFCR; /*!< LTDC Layerx Pixel Format Configuration Register Address offset: 0x94 */ + __IO uint32_t CACR; /*!< LTDC Layerx Constant Alpha Configuration Register Address offset: 0x98 */ + __IO uint32_t DCCR; /*!< LTDC Layerx Default Color Configuration Register Address offset: 0x9C */ + __IO uint32_t BFCR; /*!< LTDC Layerx Blending Factors Configuration Register Address offset: 0xA0 */ + uint32_t RESERVED0[2]; /*!< Reserved, 0xA4-0xA8 */ + __IO uint32_t CFBAR; /*!< LTDC Layerx Color Frame Buffer Address Register Address offset: 0xAC */ + __IO uint32_t CFBLR; /*!< LTDC Layerx Color Frame Buffer Length Register Address offset: 0xB0 */ + __IO uint32_t CFBLNR; /*!< LTDC Layerx ColorFrame Buffer Line Number Register Address offset: 0xB4 */ + uint32_t RESERVED1[3]; /*!< Reserved, 0xB8-0xC0 */ + __IO uint32_t CLUTWR; /*!< LTDC Layerx CLUT Write Register Address offset: 0xC4 */ + +} LTDC_Layer_TypeDef; + +/** + * @brief XSPI + */ +typedef struct +{ + __IO uint32_t CR; /*!< XSPI Control Register, Address offset: 0x000 */ + uint32_t RESERVED1; /*!< Reserved, Address offset: 0x004 */ + __IO uint32_t DCR1; /*!< XSPI Device Configuration Register 1, Address offset: 0x008 */ + __IO uint32_t DCR2; /*!< XSPI Device Configuration Register 2, Address offset: 0x00C */ + __IO uint32_t DCR3; /*!< XSPI Device Configuration Register 3, Address offset: 0x010 */ + __IO uint32_t DCR4; /*!< XSPI Device Configuration Register 4, Address offset: 0x014 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x018 - 0x01C */ + __IO uint32_t SR; /*!< XSPI Status Register, Address offset: 0x020 */ + __IO uint32_t FCR; /*!< XSPI Flag Clear Register, Address offset: 0x024 */ + uint32_t RESERVED3[6]; /*!< Reserved, Address offset: 0x028 - 0x03C */ + __IO uint32_t DLR; /*!< XSPI Data Length Register, Address offset: 0x040 */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x044 */ + __IO uint32_t AR; /*!< XSPI Address Register, Address offset: 0x048 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x04C */ + __IO uint32_t DR; /*!< XSPI Data Register, Address offset: 0x050 */ + uint32_t RESERVED6[11]; /*!< Reserved, Address offset: 0x054 - 0x07C */ + __IO uint32_t PSMKR; /*!< XSPI Polling Status Mask Register, Address offset: 0x080 */ + uint32_t RESERVED7; /*!< Reserved, Address offset: 0x084 */ + __IO uint32_t PSMAR; /*!< XSPI Polling Status Match Register, Address offset: 0x088 */ + uint32_t RESERVED8; /*!< Reserved, Address offset: 0x08C */ + __IO uint32_t PIR; /*!< XSPI Polling Interval Register, Address offset: 0x090 */ + uint32_t RESERVED9[27]; /*!< Reserved, Address offset: 0x094 - 0x0FC */ + __IO uint32_t CCR; /*!< XSPI Communication Configuration Register, Address offset: 0x100 */ + uint32_t RESERVED10; /*!< Reserved, Address offset: 0x104 */ + __IO uint32_t TCR; /*!< XSPI Timing Configuration Register, Address offset: 0x108 */ + uint32_t RESERVED11; /*!< Reserved, Address offset: 0x10C */ + __IO uint32_t IR; /*!< XSPI Instruction Register, Address offset: 0x110 */ + uint32_t RESERVED12[3]; /*!< Reserved, Address offset: 0x114 - 0x11C */ + __IO uint32_t ABR; /*!< XSPI Alternate Bytes Register, Address offset: 0x120 */ + uint32_t RESERVED13[3]; /*!< Reserved, Address offset: 0x124 - 0x12C */ + __IO uint32_t LPTR; /*!< XSPI Low-Power Timeout Register, Address offset: 0x130 */ + uint32_t RESERVED14[3]; /*!< Reserved, Address offset: 0x134 - 0x13C */ + __IO uint32_t WPCCR; /*!< XSPI Wrap Communication Configuration Register, Address offset: 0x140 */ + uint32_t RESERVED15; /*!< Reserved, Address offset: 0x144 */ + __IO uint32_t WPTCR; /*!< XSPI Wrap Timing Configuration Register, Address offset: 0x148 */ + uint32_t RESERVED16; /*!< Reserved, Address offset: 0x14C */ + __IO uint32_t WPIR; /*!< XSPI Wrap Instruction Register, Address offset: 0x150 */ + uint32_t RESERVED17[3]; /*!< Reserved, Address offset: 0x154 - 0x15C */ + __IO uint32_t WPABR; /*!< XSPI Wrap Alternate Bytes Register, Address offset: 0x160 */ + uint32_t RESERVED18[7]; /*!< Reserved, Address offset: 0x164 - 0x17C */ + __IO uint32_t WCCR; /*!< XSPI Write Communication Configuration Register, Address offset: 0x180 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0x184 */ + __IO uint32_t WTCR; /*!< XSPI Write Timing Configuration Register, Address offset: 0x188 */ + uint32_t RESERVED20; /*!< Reserved, Address offset: 0x18C */ + __IO uint32_t WIR; /*!< XSPI Write Instruction Register, Address offset: 0x190 */ + uint32_t RESERVED21[3]; /*!< Reserved, Address offset: 0x194 - 0x19C */ + __IO uint32_t WABR; /*!< XSPI Write Alternate Bytes Register, Address offset: 0x1A0 */ + uint32_t RESERVED22[23]; /*!< Reserved, Address offset: 0x1A4 - 0x1FC */ + __IO uint32_t HLCR; /*!< XSPI HyperBus Latency Configuration Register, Address offset: 0x200 */ + uint32_t RESERVED23[3]; /*!< Reserved, Address offset: 0x204 - 0x20C */ + __IO uint32_t CALFCR; /*!< XSPI Full-Cycle Calibration Configuration Register, Address offset: 0x210 */ + uint32_t RESERVED24; /*!< Reserved, Address offset: 0x214 */ + __IO uint32_t CALMR; /*!< XSPI DLL Master Calibration Configuration Register, Address offset: 0x218 */ + uint32_t RESERVED25; /*!< Reserved, Address offset: 0x21C */ + __IO uint32_t CALSOR; /*!< XSPI Slave Output Calibration Configuration Register, Address offset: 0x220 */ + uint32_t RESERVED26; /*!< Reserved, Address offset: 0x224 */ + __IO uint32_t CALSIR; /*!< XSPI Slave Input Calibration Configuration Register, Address offset: 0x228 */ +} XSPI_TypeDef; + +/** + * @brief XSPI IO Manager + */ +typedef struct +{ + __IO uint32_t CR; /*!< XSPIM IO Manager Control Register, Address offset: 0x00 */ +} XSPIM_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< PWR power control register 1, Address offset: 0x00 */ + __IO uint32_t SR1; /*!< PWR power status register 1, Address offset: 0x04 */ + __IO uint32_t CSR1; /*!< PWR power control status register 1, Address offset: 0x08 */ + __IO uint32_t CSR2; /*!< PWR power control status register 2, Address offset: 0x0C */ + __IO uint32_t CSR3; /*!< PWR power control status register 3, Address offset: 0x10 */ + __IO uint32_t CSR4; /*!< PWR power control status register 4, Address offset: 0x14 */ + uint32_t RESERVED0[2]; /*!< Reserved */ + __IO uint32_t WKUPCR; /*!< PWR wakeup clear register, Address offset: 0x20 */ + __IO uint32_t WKUPFR; /*!< PWR wakeup flag register, Address offset: 0x24 */ + __IO uint32_t WKUPEPR; /*!< PWR wakeup enable and polarity register, Address offset: 0x28 */ + __IO uint32_t UCPDR; /*!< PWR USB Type-C and power delivery register, Address offset: 0x2C */ + __IO uint32_t APCR; /*!< PWR apply pull configuration register, Address offset: 0x30 */ + __IO uint32_t PUCRN; /*!< PWR port N pull-up control register, Address offset: 0x34 */ + __IO uint32_t PDCRN; /*!< PWR port N pull-down control register, Address offset: 0x38 */ + __IO uint32_t PUCRO; /*!< PWR port O pull-up control register, Address offset: 0x3C */ + __IO uint32_t PDCRO; /*!< PWR port O pull-down control register, Address offset: 0x40 */ + __IO uint32_t PDCRP; /*!< PWR port P pull-down control register, Address offset: 0x44 */ + uint32_t RESERVED2[2]; /*!< Reserved */ + __IO uint32_t PDR1; /*!< PWR debug register 1, Address offset: 0x50 */ +} PWR_TypeDef; + +/** + * @brief Public Key Accelerator (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 Reserved1[253]; /*!< Reserved, Address offset: 0x000C-0x03FC */ + __IO uint32_t RAM[1334]; /*!< PKA RAM Address offset: 0x0400-0x18D8 */ +} PKA_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, Address offset: 0x018 - 0x024 */ + __IO uint32_t DR; /*!< PSSI data register, Address offset: 0x028 */ +} PSSI_TypeDef; + +/** + * @brief RAM_ECC_Specific_Registers + */ +typedef struct +{ + __IO uint32_t CR; /*!< RAMECC monitor configuration register */ + __IO uint32_t SR; /*!< RAMECC monitor status register */ + __IO uint32_t FAR; /*!< RAMECC monitor failing address register */ + __IO uint32_t FDRL; /*!< RAMECC monitor failing data low register */ + __IO uint32_t FDRH; /*!< RAMECC monitor failing data high register */ + __IO uint32_t FECR; /*!< RAMECC monitor failing ECC error code register */ +} RAMECC_MonitorTypeDef; + +typedef struct +{ + __IO uint32_t IER; /*!< RAMECC interrupt enable register */ +} RAMECC_TypeDef; + + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t HSICFGR; /*!< HSI clock calibration register, Address offset: 0x04 */ + __IO uint32_t CRRCR; /*!< Clock recovery RC register, Address offset: 0x08 */ + __IO uint32_t CSICFGR; /*!< CSI clock calibration register, Address offset: 0x0C */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x10 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x14 */ + __IO uint32_t CDCFGR; /*!< RCC CPU domain configuration register, Address offset: 0x18 */ + __IO uint32_t BMCFGR; /*!< RCC Bus matrix configuration register, Address offset: 0x1C */ + __IO uint32_t APBCFGR; /*!< RCC APB clock configuration register, Address offset: 0x20 */ + uint32_t RESERVED1; /*!< Reserved, Address offset: 0x24 */ + __IO uint32_t PLLCKSELR; /*!< RCC PLLs clock source selection register, Address offset: 0x28 */ + __IO uint32_t PLLCFGR; /*!< RCC PLLs configuration register, Address offset: 0x2C */ + __IO uint32_t PLL1DIVR1; /*!< RCC PLL1 dividers configuration register 1, Address offset: 0x30 */ + __IO uint32_t PLL1FRACR; /*!< RCC PLL1 fractional divider configuration register, Address offset: 0x34 */ + __IO uint32_t PLL2DIVR1; /*!< RCC PLL2 dividers configuration register 1, Address offset: 0x38 */ + __IO uint32_t PLL2FRACR; /*!< RCC PLL2 fractional divider configuration register, Address offset: 0x3C */ + __IO uint32_t PLL3DIVR1; /*!< RCC PLL3 dividers configuration register 1, Address offset: 0x40 */ + __IO uint32_t PLL3FRACR; /*!< RCC PLL3 fractional divider configuration register, Address offset: 0x44 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x48 */ + __IO uint32_t CCIPR1; /*!< RCC AHB peripherals kernel clock configuration register Address offset: 0x4C */ + __IO uint32_t CCIPR2; /*!< RCC APB1 peripherals kernel clock configuration register Address offset: 0x50 */ + __IO uint32_t CCIPR3; /*!< RCC APB2 peripherals kernel clock configuration register Address offset: 0x54 */ + __IO uint32_t CCIPR4; /*!< RCC APB4/APB5 peripherals kernel clock configuration register Address offset: 0x58 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x5C */ + __IO uint32_t CIER; /*!< RCC clock interrupt enable register, Address offset: 0x60 */ + __IO uint32_t CIFR; /*!< RCC clock interrupt flag register, Address offset: 0x64 */ + __IO uint32_t CICR; /*!< RCC clock interrupt clear register, Address offset: 0x68 */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x6C */ + __IO uint32_t BDCR; /*!< RCC backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x78 */ + __IO uint32_t AHB5RSTR; /*!< RCC AHB5 peripheral reset register, Address offset: 0x7C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x80 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x84 */ + __IO uint32_t AHB4RSTR; /*!< RCC AHB4 peripheral reset register, Address offset: 0x88 */ + __IO uint32_t APB5RSTR; /*!< RCC APB5 peripheral reset register, Address offset: 0x8C */ + __IO uint32_t APB1RSTR1; /*!< RCC APB1 peripheral reset register 1, Address offset: 0x90 */ + __IO uint32_t APB1RSTR2; /*!< RCC APB1 peripheral reset register 2, Address offset: 0x94 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x98 */ + __IO uint32_t APB4RSTR; /*!< RCC APB4 peripheral reset register, Address offset: 0x9C */ + uint32_t RESERVED6; /*!< Reserved, Address offset: 0xA0 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0xA4 */ + uint32_t RESERVED7[2]; /*!< Reserved, Address offset: 0xA8-0xAC */ + __IO uint32_t CKGDISR ; /*!< RCC AXI clocks gating disable register, Address offset: 0xB0 */ + uint32_t RESERVED8[3]; /*!< Reserved, Address offset: 0xB4-0xBC */ + __IO uint32_t PLL1DIVR2; /*!< RCC PLL1 dividers configuration register 2, Address offset: 0xC0 */ + __IO uint32_t PLL2DIVR2; /*!< RCC PLL2 dividers configuration register 2, Address offset: 0xC4 */ + __IO uint32_t PLL3DIVR2; /*!< RCC PLL3 dividers configuration register 2, Address offset: 0xC8 */ + __IO uint32_t PLL1SSCGR; /*!< RCC PLL1 spread spectrum clock generator register, Address offset: 0xCC */ + __IO uint32_t PLL2SSCGR; /*!< RCC PLL2 spread spectrum clock generator register, Address offset: 0xD0 */ + __IO uint32_t PLL3SSCGR; /*!< RCC PLL3 spread spectrum clock generator register, Address offset: 0xD4 */ + uint32_t RESERVED9[10]; /*!< Reserved, Address offset: 0xD8-0xFC */ + __IO uint32_t CKPROTR; /*!< RCC clock protection register, Address offset: 0x100 */ + uint32_t RESERVED10[11]; /*!< Reserved, Address offset: 0x104-0x12C */ + __IO uint32_t RSR; /*!< RCC reset status register, Address offset: 0x130 */ + __IO uint32_t AHB5ENR; /*!< RCC AHB5 peripheral clocks enable register, Address offset: 0x134 */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clocks enable register, Address offset: 0x138 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clocks enable register, Address offset: 0x13C */ + __IO uint32_t AHB4ENR; /*!< RCC AHB4 peripheral clocks enable register, Address offset: 0x140 */ + __IO uint32_t APB5ENR; /*!< RCC APB5 peripheral clocks enable register, Address offset: 0x144 */ + __IO uint32_t APB1ENR1; /*!< RCC APB1 peripheral clocks enable register 1, Address offset: 0x148 */ + __IO uint32_t APB1ENR2; /*!< RCC APB1 peripheral clocks enable register 2, Address offset: 0x14C */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clocks enable register, Address offset: 0x150 */ + __IO uint32_t APB4ENR; /*!< RCC APB4 peripheral clocks enable register, Address offset: 0x154 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clocks enable register, Address offset: 0x158 */ + __IO uint32_t AHB5LPENR; /*!< RCC AHB5 peripheral sleep clocks enable register, Address offset: 0x15C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral sleep clocks enable register, Address offset: 0x160 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral sleep clocks enable register, Address offset: 0x164 */ + __IO uint32_t AHB4LPENR; /*!< RCC AHB4 peripheral sleep clocks enable register, Address offset: 0x168 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral sleep clocks enable register, Address offset: 0x16C */ + __IO uint32_t APB1LPENR1; /*!< RCC APB1 peripheral sleep clocks enable register 1, Address offset: 0x170 */ + __IO uint32_t APB1LPENR2; /*!< RCC APB1 peripheral sleep clocks enable register 2, Address offset: 0x174 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral sleep clocks enable register, Address offset: 0x178 */ + __IO uint32_t APB4LPENR; /*!< RCC APB4 peripheral sleep clocks enable register, Address offset: 0x17C */ + __IO uint32_t APB5LPENR; /*!< RCC APB5 peripheral sleep clocks enable register, Address offset: 0x180 */ +} RCC_TypeDef; + +/** + * @brief Random Number Generator + */ +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 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 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 */ + __IO uint32_t RESERVED2; /*!< Reserved, Address offset: 0x58 */ + __IO uint32_t SCR; /*!< RTC status Clear register, Address offset: 0x5C */ + uint32_t RESERVED3[4];/*!< Reserved, Address offset: 0x58 */ + __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 SAES Processor + */ +typedef struct +{ + __IO uint32_t CR; /*!< SAES control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< SAES status register, Address offset: 0x04 */ + __IO uint32_t DINR; /*!< SAES data input register, Address offset: 0x08 */ + __IO uint32_t DOUTR; /*!< SAES data output register, Address offset: 0x0C */ + __IO uint32_t KEYR0; /*!< SAES key register 0, Address offset: 0x10 */ + __IO uint32_t KEYR1; /*!< SAES key register 1, Address offset: 0x14 */ + __IO uint32_t KEYR2; /*!< SAES key register 2, Address offset: 0x18 */ + __IO uint32_t KEYR3; /*!< SAES key register 3, Address offset: 0x1C */ + __IO uint32_t IVR0; /*!< SAES initialization vector register 0, Address offset: 0x20 */ + __IO uint32_t IVR1; /*!< SAES initialization vector register 1, Address offset: 0x24 */ + __IO uint32_t IVR2; /*!< SAES initialization vector register 2, Address offset: 0x28 */ + __IO uint32_t IVR3; /*!< SAES initialization vector register 3, Address offset: 0x2C */ + __IO uint32_t KEYR4; /*!< SAES key register 4, Address offset: 0x30 */ + __IO uint32_t KEYR5; /*!< SAES key register 5, Address offset: 0x34 */ + __IO uint32_t KEYR6; /*!< SAES key register 6, Address offset: 0x38 */ + __IO uint32_t KEYR7; /*!< SAES key register 7, Address offset: 0x3C */ + __IO uint32_t SUSP0R; /*!< SAES Suspend register 0, Address offset: 0x40 */ + __IO uint32_t SUSP1R; /*!< SAES Suspend register 1, Address offset: 0x44 */ + __IO uint32_t SUSP2R; /*!< SAES Suspend register 2, Address offset: 0x48 */ + __IO uint32_t SUSP3R; /*!< SAES Suspend register 3, Address offset: 0x4C */ + __IO uint32_t SUSP4R; /*!< SAES Suspend register 4, Address offset: 0x50 */ + __IO uint32_t SUSP5R; /*!< SAES Suspend register 5, Address offset: 0x54 */ + __IO uint32_t SUSP6R; /*!< SAES Suspend register 6, Address offset: 0x58 */ + __IO uint32_t SUSP7R; /*!< SAES Suspend register 7, Address offset: 0x5C */ + uint32_t RESERVED1[168]; /*!< Reserved, Address offset: 0x60 -- 0x2FC */ + __IO uint32_t IER; /*!< SAES Interrupt Enable Register, Address offset: 0x300 */ + __IO uint32_t ISR; /*!< SAES Interrupt Status Register, Address offset: 0x304 */ + __IO uint32_t ICR; /*!< SAES Interrupt Clear Register, Address offset: 0x308 */ +} SAES_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 controller + */ +typedef struct +{ + __IO uint32_t BOOTSR; /*!< SBS Boot Status register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x04-0x0C */ + __IO uint32_t HDPLCR; /*!< SBS Hide Protection Control register, Address offset: 0x10 */ + __IO uint32_t HDPLSR; /*!< SBS Hide Protection Status register, Address offset: 0x14 */ + uint32_t RESERVED2[2]; /*!< Reserved, 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]; /*!< Reserved, Address offset: 0x28-0x30 */ + __IO uint32_t RSSCMDR; /*!< SBS RSS Command register, Address offset: 0x34 */ + uint32_t RESERVED4[50]; /*!< Reserved, Address offset: 0x38-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 RESERVED5; /*!< Reserved, Address offset: 0x10C */ + __IO uint32_t CCCSR; /*!< SBS IO Compensation Cell Control and Status register, Address offset: 0x110 */ + __IO uint32_t CCVALR; /*!< SBS IO Compensation Cell Value register, Address offset: 0x114 */ + __IO uint32_t CCSWVALR; /*!< SBS IO Compensation Cell Software Value register, Address offset: 0x118 */ + uint32_t RESERVED6; /*!< Reserved, Address offset: 0x11C */ + __IO uint32_t BKLOCKR; /*!< SBS Break Lockup register, Address offset: 0x120 */ + uint32_t RESERVED7[3]; /*!< Reserved, Address offset: 0x124-0x12C */ + __IO uint32_t EXTICR[4]; /*!< SBS External Interrupt Configuration registers, Address offset: 0x130-0x13C */ +} SBS_TypeDef; + +/** + * @brief Secure Digital Card/IO Embedded MultiMediaCard Interface + */ +typedef struct +{ + __IO uint32_t POWER; /*!< SDMMC Power control register, Address offset : 0x000 */ + __IO uint32_t CLKCR; /*!< SDMMC Clock control register, Address offset : 0x004 */ + __IO uint32_t ARG; /*!< SDMMC Argument register, Address offset : 0x008 */ + __IO uint32_t CMD; /*!< SDMMC Command register, Address offset : 0x00C */ + __IO uint32_t RESPCMD; /*!< SDMMC Command response register, Address offset : 0x010 */ + __IO uint32_t RESP1; /*!< SDMMC Response 1 register, Address offset : 0x014 */ + __IO uint32_t RESP2; /*!< SDMMC Response 2 register, Address offset : 0x018 */ + __IO uint32_t RESP3; /*!< SDMMC Response 3 register, Address offset : 0x01C */ + __IO uint32_t RESP4; /*!< SDMMC Response 4 register, Address offset : 0x020 */ + __IO uint32_t DTIMER; /*!< SDMMC Data timer register, Address offset : 0x024 */ + __IO uint32_t DLEN; /*!< SDMMC Data length register, Address offset : 0x028 */ + __IO uint32_t DCTRL; /*!< SDMMC Data control register, Address offset : 0x02C */ + __IO uint32_t DCOUNT; /*!< SDMMC Data counter register, Address offset : 0x030 */ + __IO uint32_t STA; /*!< SDMMC Status register, Address offset : 0x034 */ + __IO uint32_t ICR; /*!< SDMMC Interrupt clear register, Address offset : 0x038 */ + __IO uint32_t MASK; /*!< SDMMC Mask register, Address offset : 0x03C */ + __IO uint32_t ACKTIME; /*!< SDMMC Acknowledgement timer register, Address offset : 0x040 */ + uint32_t RESERVED0[3]; /*!< Reserved, Address offset : 0x044 - 0x04C */ + __IO uint32_t IDMACTRL; /*!< SDMMC IDMA control register, Address offset : 0x050 */ + __IO uint32_t IDMABSIZE; /*!< SDMMC IDMA buffer size register, Address offset : 0x054 */ + __IO uint32_t IDMABASER; /*!< SDMMC IDMA buffer base address register, Address offset : 0x058 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset : 0x05C - 0x060 */ + __IO uint32_t IDMALAR; /*!< SDMMC IDMA linked list address register, Address offset : 0x064 */ + __IO uint32_t IDMABAR; /*!< SDMMC IDMA linked list memory base register, Address offset : 0x068 */ + uint32_t RESERVED2[5]; /*!< Reserved, Address offset : 0x06C - 0x07C */ + __IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset : 0x080 */ +} SDMMC_TypeDef; + +/** + * @brief SPDIF-RX Interface + */ +typedef struct +{ + __IO uint32_t CR; /*!< Control register, Address offset: 0x00 */ + __IO uint32_t IMR; /*!< Interrupt mask register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< Status register, Address offset: 0x08 */ + __IO uint32_t IFCR; /*!< Interrupt Flag Clear register, Address offset: 0x0C */ + __IO uint32_t DR; /*!< Data input register, Address offset: 0x10 */ + __IO uint32_t CSR; /*!< Channel Status register, Address offset: 0x14 */ + __IO uint32_t DIR; /*!< Debug Information register, Address offset: 0x18 */ +} SPDIFRX_TypeDef; + +/** + * @brief SPI + */ +typedef struct +{ + __IO uint32_t CR1; /*!< SPI/I2S Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< SPI Control register 2, Address offset: 0x04 */ + __IO uint32_t CFG1; /*!< SPI Configuration register 1, Address offset: 0x08 */ + __IO uint32_t CFG2; /*!< SPI Configuration register 2, Address offset: 0x0C */ + __IO uint32_t IER; /*!< SPI/I2S Interrupt Enable register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< SPI/I2S Status register, Address offset: 0x14 */ + __IO uint32_t IFCR; /*!< SPI/I2S Interrupt/Status flags clear register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x1C */ + __IO uint32_t TXDR; /*!< SPI Transmit data register, Address offset: 0x20 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x24-0x2C */ + __IO uint32_t RXDR; /*!< SPI/I2S data register, Address offset: 0x30 */ + uint32_t RESERVED2[3]; /*!< Reserved, Address offset: 0x34-0x3C */ + __IO uint32_t CRCPOLY; /*!< SPI CRC Polynomial register, Address offset: 0x40 */ + __IO uint32_t TXCRC; /*!< SPI Transmitter CRC register, Address offset: 0x44 */ + __IO uint32_t RXCRC; /*!< SPI Receiver CRC register, Address offset: 0x48 */ + __IO uint32_t UDRDR; /*!< SPI Underrun data register, Address offset: 0x4C */ + __IO uint32_t I2SCFGR; /*!< I2S Configuration register, Address offset: 0x50 */ +} SPI_TypeDef; + +/** + * @brief Tamper and backup registers + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TAMP configuration register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TAMP configuration register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< TAMP configuration 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 CFGR; /*!< TAMP configuration control register, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR; /*!< TAMP privilege mode control register, Address offset: 0x24 */ + uint32_t RESERVED2; /*!< 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 RESERVED3; /*!< Reserved, Address offset: 0x38 */ + __IO uint32_t SCR; /*!< TAMP status clear register, Address offset: 0x3C */ + __IO uint32_t COUNT1R; /*!< TAMP monotonic counter 1 register, Address offset: 0x40 */ + uint32_t RESERVED4[4]; /*!< Reserved, Address offset: 0x43 -- 0x50 */ + __IO uint32_t RPCFGR; /*!< TAMP resources protection configuration register, Address offset: 0x54 */ + uint32_t RESERVED5[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 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 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 */ +} UCPD_TypeDef; + +/** + * @brief USB_OTG_Core_register + */ +typedef struct +{ + __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register, Address offset: 000h */ + __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register, Address offset: 004h */ + __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register, Address offset: 008h */ + __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register, Address offset: 00Ch */ + __IO uint32_t GRSTCTL; /*!< Core Reset Register, Address offset: 010h */ + __IO uint32_t GINTSTS; /*!< Core Interrupt Register, Address offset: 014h */ + __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register, Address offset: 018h */ + __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register, Address offset: 01Ch */ + __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register, Address offset: 020h */ + __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register, Address offset: 024h */ + __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register, Address offset: 028h */ + __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg, Address offset: 02Ch */ + __IO uint32_t Reserved30[2]; /*!< Reserved, Address offset: 030h */ + __IO uint32_t GCCFG; /*!< General Purpose IO Register, Address offset: 038h */ + __IO uint32_t CID; /*!< User ID Register, Address offset: 03Ch */ + __IO uint32_t GSNPSID; /*!< USB_OTG core ID, Address offset: 040h */ + __IO uint32_t GHWCFG1; /*!< User HW config1, Address offset: 044h */ + __IO uint32_t GHWCFG2; /*!< User HW config2, Address offset: 048h */ + __IO uint32_t GHWCFG3; /*!< User HW config3, Address offset: 04Ch */ + __IO uint32_t Reserved6; /*!< Reserved, Address offset: 050h */ + __IO uint32_t GLPMCFG; /*!< LPM Register, Address offset: 054h */ + __IO uint32_t GPWRDN; /*!< Power Down Register, Address offset: 058h */ + __IO uint32_t GDFIFOCFG; /*!< DFIFO Software Config Register, Address offset: 05Ch */ + __IO uint32_t GADPCTL; /*!< ADP Timer, Control and Status Register, Address offset: 60Ch */ + __IO uint32_t Reserved43[39]; /*!< Reserved, Address offset: 058h */ + __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg, Address offset: 100h */ + __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO Address offset: 104h */ +} USB_OTG_GlobalTypeDef; + +/** + * @brief USB_OTG_device_Registers + */ +typedef struct +{ + __IO uint32_t DCFG; /*!< dev Configuration Register, Address offset: 800h */ + __IO uint32_t DCTL; /*!< dev Control Register, Address offset: 804h */ + __IO uint32_t DSTS; /*!< dev Status Register (RO), Address offset: 808h */ + uint32_t Reserved0C; /*!< Reserved, Address offset: 80Ch */ + __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask, Address offset: 810h */ + __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask, Address offset: 814h */ + __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg, Address offset: 818h */ + __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask, Address offset: 81Ch */ + uint32_t Reserved20; /*!< Reserved, Address offset: 820h */ + uint32_t Reserved9; /*!< Reserved, Address offset: 824h */ + __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register, Address offset: 828h */ + __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register, Address offset: 82Ch */ + __IO uint32_t DTHRCTL; /*!< dev threshold, Address offset: 830h */ + __IO uint32_t DIEPEMPMSK; /*!< dev empty msk, Address offset: 834h */ + __IO uint32_t DEACHINT; /*!< dedicated EP interrupt, Address offset: 838h */ + __IO uint32_t DEACHMSK; /*!< dedicated EP msk, Address offset: 83Ch */ + uint32_t Reserved40; /*!< dedicated EP mask, Address offset: 840h */ + __IO uint32_t DINEP1MSK; /*!< dedicated EP mask, Address offset: 844h */ + uint32_t Reserved44[15]; /*!< Reserved, Address offset: 844-87Ch */ + __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk, Address offset: 884h */ +} USB_OTG_DeviceTypeDef; + + +/** + * @brief USB_OTG_IN_Endpoint-Specific_Register + */ +typedef struct +{ + __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Register, Address offset: 900h + (ep_num * 20h) + 00h */ + __IO uint32_t Reserved04; /*!< Reserved, Address offset: 900h + (ep_num * 20h) + 04h */ + __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Register, Address offset: 900h + (ep_num * 20h) + 08h */ + __IO uint32_t Reserved0C; /*!< Reserved, Address offset: 900h + (ep_num * 20h) + 0Ch */ + __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size Register, Address offset: 900h + (ep_num * 20h) + 10h */ + __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Register, Address offset: 900h + (ep_num * 20h) + 14h */ + __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Register, Address offset: 900h + (ep_num * 20h) + 18h */ + __IO uint32_t Reserved18; /*!< Reserved, Address offset: 900h + (ep_num * 20h) + 1Ch */ +} USB_OTG_INEndpointTypeDef; + +/** + * @brief USB_OTG_OUT_Endpoint-Specific_Registers + */ +typedef struct +{ + __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Register, Address offset: B00h + (ep_num * 20h) + 00h */ + __IO uint32_t Reserved04; /*!< Reserved, Address offset: B00h + (ep_num * 20h) + 04h */ + __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Register, Address offset: B00h + (ep_num * 20h) + 08h */ + __IO uint32_t Reserved0C; /*!< Reserved, Address offset: B00h + (ep_num * 20h) + 0Ch */ + __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size Register, Address offset: B00h + (ep_num * 20h) + 10h */ + __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address Register, Address offset: B00h + (ep_num * 20h) + 14h */ + __IO uint32_t Reserved18[2]; /*!< Reserved, Address offset: B00h + (ep_num * 20h) + 18h */ +} USB_OTG_OUTEndpointTypeDef; + +/** + * @brief USB_OTG_Host_Mode_Register_Structures + */ +typedef struct +{ + __IO uint32_t HCFG; /*!< Host Configuration Register, Address offset: 400h */ + __IO uint32_t HFIR; /*!< Host Frame Interval Register, Address offset: 404h */ + __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining, Address offset: 408h */ + uint32_t Reserved40C; /*!< Reserved, Address offset: 40Ch */ + __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status, Address offset: 410h */ + __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register, Address offset: 414h */ + __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask, Address offset: 418h */ +} USB_OTG_HostTypeDef; + +/** + * @brief USB_OTG_Host_Channel_Specific_Registers + */ +typedef struct +{ + __IO uint32_t HCCHAR; /*!< Host Channel Characteristics Register, Address offset: 500h */ + __IO uint32_t HCSPLT; /*!< Host Channel Split Control Register, Address offset: 504h */ + __IO uint32_t HCINT; /*!< Host Channel Interrupt Register, Address offset: 508h */ + __IO uint32_t HCINTMSK; /*!< Host Channel Interrupt Mask Register, Address offset: 50Ch */ + __IO uint32_t HCTSIZ; /*!< Host Channel Transfer Size Register, Address offset: 510h */ + __IO uint32_t HCDMA; /*!< Host Channel DMA Address Register, Address offset: 514h */ + uint32_t Reserved[2]; /*!< Reserved, Address offset: 518h */ +} USB_OTG_HostChannelTypeDef; + +/** + * @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 Window Watchdog + */ +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/*@}*/ /* end of group STM32H7RSxx_peripherals */ + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + +/** @addtogroup STM32H7RSxx_Peripheral_peripheralAddr + * @{ + */ +#define ITCM_BASE 0x00000000UL /*!< ITCM base address */ +#define FLASH_BASE 0x08000000UL /*!< User Flash address */ +#define OTP_AREA_BASE 0x08FFF000UL /*!< OTP Area base address */ +#define ENGI_BYTES_BASE 0x52002800UL /*!< Engi Bytes */ +#define SYSTEM_FLASH_BASE 0x1FF00000UL /*!< System Flash base address */ +#define DTCM_BASE 0x20000000UL /*!< DTCM base address */ +#define SRAM1_AXI_BASE 0x24000000UL /*!< SRAM1 base address - accessible over AXI */ +#define SRAM2_AXI_BASE 0x24020000UL /*!< SRAM2 base address - accessible over AXI */ +#define SRAM3_AXI_BASE 0x24040000UL /*!< SRAM3 base address - accessible over AXI */ +#define SRAM4_AXI_BASE 0x24060000UL /*!< SRAM4 base address - accessible over AXI */ + +#define GFXMMU_VIRTUAL_BUFFER0_BASE 0x25000000UL /*!< GFXMMU virtual buffer 0 base address */ +#define GFXMMU_VIRTUAL_BUFFER1_BASE 0x25400000UL /*!< GFXMMU virtual buffer 1 base address */ +#define GFXMMU_VIRTUAL_BUFFER2_BASE 0x25800000UL /*!< GFXMMU virtual buffer 2 base address */ +#define GFXMMU_VIRTUAL_BUFFER3_BASE 0x25C00000UL /*!< GFXMMU virtual buffer 3 base address */ + +#define SRAM1_AHB_BASE 0x30000000UL /*!< SRAM1 base address */ +#define SRAM2_AHB_BASE 0x30004000UL /*!< SRAM2 base address */ +#define BKPSRAM_BASE 0x38800000UL /*!< Backup SRAM */ + +#define PERIPH_BASE 0x40000000UL /*!< AHB and APB Peripherals base address */ +#define XSPI2_BASE 0x70000000UL /*!< XSPI2 base address */ +#define XSPI1_BASE 0x90000000UL /*!< XSPI1 base address */ + +/*!< Internal memory size */ +#define ITCM_SIZE 0x00010000UL /*!< 64 KB default, can be increased up to 192 KB */ +#define DTCM_SIZE 0x00010000UL /*!< 64 KB default, can be increased up to 192 KB */ +#define FLASH_SIZE 0x00010000UL /*!< 64 KB */ +#define SRAM1_AXI_SIZE 0x00020000UL /*!< 128 KB default, can be decreased down to 0 KB to increase ITCM */ +#define SRAM2_AXI_SIZE 0x00020000UL /*!< 128 KB */ +#define SRAM3_AXI_SIZE 0x00020000UL /*!< 128 KB default, can be decreased down to 0 KB to increase DTCM */ +#define SRAM4_AXI_SIZE 0x00012000UL /*!< 72 KB default, can be decreased to 0 KB when RAM ECC is disable */ +#define SRAM_AHB_SIZE 0x00004000UL /*!< Both AHB SRAMs are 16 KB */ +#define BKPSRAM_SIZE 0x00001000UL /*!< 4 KB */ + +/*!< OTP Area size */ +#define OTP_SIZE 0x400U /* 1 KB */ + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000UL) +#define APB2PERIPH_BASE (PERIPH_BASE + 0x02000000UL) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000UL) +#define AHB3PERIPH_BASE (PERIPH_BASE + 0x08020000UL) +#define APB5PERIPH_BASE (PERIPH_BASE + 0x10000000UL) +#define AHB5PERIPH_BASE (PERIPH_BASE + 0x12000000UL) +#define APB4PERIPH_BASE (PERIPH_BASE + 0x18000000UL) +#define AHB4PERIPH_BASE (PERIPH_BASE + 0x18020000UL) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000UL) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400UL) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800UL) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00UL) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000UL) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400UL) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800UL) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00UL) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000UL) +#define LPTIM1_BASE (APB1PERIPH_BASE + 0x2400UL) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00UL) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800UL) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00UL) +#define SPDIFRX_BASE (APB1PERIPH_BASE + 0x4000UL) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400UL) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800UL) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00UL) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000UL) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400UL) +#define I3C1_BASE (APB1PERIPH_BASE + 0x5400UL) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800UL) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00UL) +#define CEC_BASE (APB1PERIPH_BASE + 0x6C00UL) +#define UART7_BASE (APB1PERIPH_BASE + 0x7800UL) +#define UART8_BASE (APB1PERIPH_BASE + 0x7C00UL) +#define CRS_BASE (APB1PERIPH_BASE + 0x8400UL) +#define MDIOS_BASE (APB1PERIPH_BASE + 0x9400UL) +#define FDCAN1_BASE (APB1PERIPH_BASE + 0xA000UL) +#define FDCAN_CONFIG_BASE (APB1PERIPH_BASE + 0xA100UL) /*!< FDCAN configuration registers base address */ +#define FDCAN2_BASE (APB1PERIPH_BASE + 0xA400UL) +#define SRAMCAN_BASE (APB1PERIPH_BASE + 0xAC00UL) +#define UCPD1_BASE (APB1PERIPH_BASE + 0xEC00UL) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000UL) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000UL) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000UL) +#define SPI4_BASE (APB2PERIPH_BASE + 0x3400UL) +#define TIM15_BASE (APB2PERIPH_BASE + 0x4000UL) +#define TIM16_BASE (APB2PERIPH_BASE + 0x4400UL) +#define TIM17_BASE (APB2PERIPH_BASE + 0x4800UL) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4C00UL) +#define SPI5_BASE (APB2PERIPH_BASE + 0x5000UL) +#define SAI1_BASE (APB2PERIPH_BASE + 0x5800UL) +#define SAI1_Block_A_BASE (SAI1_BASE + 0x0004UL) +#define SAI1_Block_B_BASE (SAI1_BASE + 0x0024UL) +#define SAI2_BASE (APB2PERIPH_BASE + 0x5C00UL) +#define SAI2_Block_A_BASE (SAI2_BASE + 0x0004UL) +#define SAI2_Block_B_BASE (SAI2_BASE + 0x0024UL) + +/*!< AHB1 peripherals */ +#define GPDMA1_BASE (AHB1PERIPH_BASE + 0x1000UL) +#define GPDMA1_Channel0_BASE (GPDMA1_BASE + 0x0050UL) +#define GPDMA1_Channel1_BASE (GPDMA1_BASE + 0x00D0UL) +#define GPDMA1_Channel2_BASE (GPDMA1_BASE + 0x0150UL) +#define GPDMA1_Channel3_BASE (GPDMA1_BASE + 0x01D0UL) +#define GPDMA1_Channel4_BASE (GPDMA1_BASE + 0x0250UL) +#define GPDMA1_Channel5_BASE (GPDMA1_BASE + 0x02D0UL) +#define GPDMA1_Channel6_BASE (GPDMA1_BASE + 0x0350UL) +#define GPDMA1_Channel7_BASE (GPDMA1_BASE + 0x03D0UL) +#define GPDMA1_Channel8_BASE (GPDMA1_BASE + 0x0450UL) +#define GPDMA1_Channel9_BASE (GPDMA1_BASE + 0x04D0UL) +#define GPDMA1_Channel10_BASE (GPDMA1_BASE + 0x0550UL) +#define GPDMA1_Channel11_BASE (GPDMA1_BASE + 0x05D0UL) +#define GPDMA1_Channel12_BASE (GPDMA1_BASE + 0x0650UL) +#define GPDMA1_Channel13_BASE (GPDMA1_BASE + 0x06D0UL) +#define GPDMA1_Channel14_BASE (GPDMA1_BASE + 0x0750UL) +#define GPDMA1_Channel15_BASE (GPDMA1_BASE + 0x07D0UL) +#define ADC1_BASE (AHB1PERIPH_BASE + 0x2000UL) +#define ADC2_BASE (AHB1PERIPH_BASE + 0x2100UL) +#define ADC12_COMMON_BASE (AHB1PERIPH_BASE + 0x2300UL) +#define ETH_BASE (AHB1PERIPH_BASE + 0x8000UL) +#define ETH_MAC_BASE (ETH_BASE) +#define ADF1_BASE (AHB1PERIPH_BASE + 0xF000UL) +#define ADF1_Filter0_BASE (ADF1_BASE + 0x0080UL) +#define USB_OTG_HS_PERIPH_BASE (AHB1PERIPH_BASE + 0x20000UL) +#define USB_OTG_FS_PERIPH_BASE (AHB1PERIPH_BASE + 0x60000UL) + +/*!< AHB2 peripherals */ +#define PSSI_BASE (AHB2PERIPH_BASE + 0x0400UL) +#define SDMMC2_BASE (AHB2PERIPH_BASE + 0x2400UL) +#define DLYB_SDMMC2_BASE (AHB2PERIPH_BASE + 0x2800UL) +#define CORDIC_BASE (AHB2PERIPH_BASE + 0x4400UL) + +/*!< AHB3 peripherals */ +#define RNG_BASE AHB3PERIPH_BASE +#define HASH_BASE (AHB3PERIPH_BASE + 0x0400UL) +#define HASH_DIGEST_BASE (AHB3PERIPH_BASE + 0x0710UL) +#define CRYP_BASE (AHB3PERIPH_BASE + 0x0800UL) +#define SAES_BASE (AHB3PERIPH_BASE + 0x1000UL) +#define PKA_BASE (AHB3PERIPH_BASE + 0x2000UL) + +/*!< APB5 peripherals */ +#define LTDC_BASE (APB5PERIPH_BASE + 0x1000UL) +#define LTDC_Layer1_BASE (LTDC_BASE + 0x0084UL) +#define LTDC_Layer2_BASE (LTDC_BASE + 0x0104UL) +#define DCMIPP_BASE (APB5PERIPH_BASE + 0x2000UL) +#define GFXTIM_BASE (APB5PERIPH_BASE + 0x4000UL) + +/*!< AHB5 peripherals */ +#define HPDMA1_BASE AHB5PERIPH_BASE +#define HPDMA1_Channel0_BASE (HPDMA1_BASE + 0x0050UL) +#define HPDMA1_Channel1_BASE (HPDMA1_BASE + 0x00D0UL) +#define HPDMA1_Channel2_BASE (HPDMA1_BASE + 0x0150UL) +#define HPDMA1_Channel3_BASE (HPDMA1_BASE + 0x01D0UL) +#define HPDMA1_Channel4_BASE (HPDMA1_BASE + 0x0250UL) +#define HPDMA1_Channel5_BASE (HPDMA1_BASE + 0x02D0UL) +#define HPDMA1_Channel6_BASE (HPDMA1_BASE + 0x0350UL) +#define HPDMA1_Channel7_BASE (HPDMA1_BASE + 0x03D0UL) +#define HPDMA1_Channel8_BASE (HPDMA1_BASE + 0x0450UL) +#define HPDMA1_Channel9_BASE (HPDMA1_BASE + 0x04D0UL) +#define HPDMA1_Channel10_BASE (HPDMA1_BASE + 0x0550UL) +#define HPDMA1_Channel11_BASE (HPDMA1_BASE + 0x05D0UL) +#define HPDMA1_Channel12_BASE (HPDMA1_BASE + 0x0650UL) +#define HPDMA1_Channel13_BASE (HPDMA1_BASE + 0x06D0UL) +#define HPDMA1_Channel14_BASE (HPDMA1_BASE + 0x0750UL) +#define HPDMA1_Channel15_BASE (HPDMA1_BASE + 0x07D0UL) +#define DMA2D_BASE (AHB5PERIPH_BASE + 0x1000UL) +#define FLASH_R_BASE (AHB5PERIPH_BASE + 0x2000UL) +#define JPEG_BASE (AHB5PERIPH_BASE + 0x3000UL) +#define FMC_R_BASE (AHB5PERIPH_BASE + 0x4000UL) +#define FMC_Bank1_R_BASE (FMC_R_BASE + 0x0000UL) +#define FMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104UL) +#define FMC_Bank3_R_BASE (FMC_R_BASE + 0x0080UL) +#define FMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140UL) +#define XSPI1_R_BASE (AHB5PERIPH_BASE + 0x5000UL) +#define SDMMC1_BASE (AHB5PERIPH_BASE + 0x7000UL) +#define DLYB_SDMMC1_BASE (AHB5PERIPH_BASE + 0x8000UL) +#define RAMECC1_BASE (AHB5PERIPH_BASE + 0x9000UL) +#define RAMECC1_Monitor0_BASE (RAMECC1_BASE + 0x20UL) +#define RAMECC1_Monitor1_BASE (RAMECC1_BASE + 0x40UL) +#define RAMECC1_Monitor2_BASE (RAMECC1_BASE + 0x60UL) +#define RAMECC1_Monitor3_BASE (RAMECC1_BASE + 0x80UL) +#define RAMECC1_Monitor4_BASE (RAMECC1_BASE + 0xA0UL) +#define XSPI2_R_BASE (AHB5PERIPH_BASE + 0xA000UL) +#define XSPIM_BASE (AHB5PERIPH_BASE + 0xB400UL) +#define MCE1_BASE (AHB5PERIPH_BASE + 0xB800UL) +#define MCE1_REGION1_BASE (MCE1_BASE + 0x040UL) +#define MCE1_REGION2_BASE (MCE1_BASE + 0x050UL) +#define MCE1_REGION3_BASE (MCE1_BASE + 0x060UL) +#define MCE1_REGION4_BASE (MCE1_BASE + 0x070UL) +#define MCE1_CONTEXT1_BASE (MCE1_BASE + 0x240UL) +#define MCE1_CONTEXT2_BASE (MCE1_BASE + 0x270UL) +#define MCE2_BASE (AHB5PERIPH_BASE + 0xBC00UL) +#define MCE2_REGION1_BASE (MCE2_BASE + 0x040UL) +#define MCE2_REGION2_BASE (MCE2_BASE + 0x050UL) +#define MCE2_REGION3_BASE (MCE2_BASE + 0x060UL) +#define MCE2_REGION4_BASE (MCE2_BASE + 0x070UL) +#define MCE3_BASE (AHB5PERIPH_BASE + 0xC000UL) +#define MCE3_REGION1_BASE (MCE3_BASE + 0x040UL) +#define MCE3_REGION2_BASE (MCE3_BASE + 0x050UL) +#define MCE3_REGION3_BASE (MCE3_BASE + 0x060UL) +#define MCE3_REGION4_BASE (MCE3_BASE + 0x070UL) +#define GFXMMU_BASE (AHB5PERIPH_BASE + 0x010000UL) +#define GPU2D_BASE (AHB5PERIPH_BASE + 0x014000UL) +#define ICACHE_BASE (AHB5PERIPH_BASE + 0x015000UL) + +/*!< APB4 peripherals */ +#define EXTI_BASE APB4PERIPH_BASE +#define SBS_BASE (APB4PERIPH_BASE + 0x0400UL) +#define LPUART1_BASE (APB4PERIPH_BASE + 0x0C00UL) +#define SPI6_BASE (APB4PERIPH_BASE + 0x1400UL) +#define LPTIM2_BASE (APB4PERIPH_BASE + 0x2400UL) +#define LPTIM3_BASE (APB4PERIPH_BASE + 0x2800UL) +#define LPTIM4_BASE (APB4PERIPH_BASE + 0x2C00UL) +#define LPTIM5_BASE (APB4PERIPH_BASE + 0x3000UL) +#define VREFBUF_BASE (APB4PERIPH_BASE + 0x3C00UL) +#define RTC_BASE (APB4PERIPH_BASE + 0x4000UL) +#define TAMP_BASE (APB4PERIPH_BASE + 0x4400UL) +#define IWDG_BASE (APB4PERIPH_BASE + 0x4800UL) +#define DTS_BASE (APB4PERIPH_BASE + 0x6800UL) + +/*!< AHB4 peripherals */ +#define GPIOA_BASE AHB4PERIPH_BASE +#define GPIOB_BASE (AHB4PERIPH_BASE + 0x0400UL) +#define GPIOC_BASE (AHB4PERIPH_BASE + 0x0800UL) +#define GPIOD_BASE (AHB4PERIPH_BASE + 0x0C00UL) +#define GPIOE_BASE (AHB4PERIPH_BASE + 0x1000UL) +#define GPIOF_BASE (AHB4PERIPH_BASE + 0x1400UL) +#define GPIOG_BASE (AHB4PERIPH_BASE + 0x1800UL) +#define GPIOH_BASE (AHB4PERIPH_BASE + 0x1C00UL) +#define GPIOM_BASE (AHB4PERIPH_BASE + 0x3000UL) +#define GPION_BASE (AHB4PERIPH_BASE + 0x3400UL) +#define GPIOO_BASE (AHB4PERIPH_BASE + 0x3800UL) +#define GPIOP_BASE (AHB4PERIPH_BASE + 0x3C00UL) +#define RCC_BASE (AHB4PERIPH_BASE + 0x4400UL) +#define PWR_BASE (AHB4PERIPH_BASE + 0x4800UL) +#define CRC_BASE (AHB4PERIPH_BASE + 0x4C00UL) +#define RAMECC2_BASE (AHB4PERIPH_BASE + 0x7000UL) +#define RAMECC2_Monitor1_BASE (RAMECC2_BASE + 0x40UL) + +/*!< Debug MCU registers base address */ +#define DBGMCU_BASE (0x5C001000UL) + +/*!< AXIM registers base address */ +#define AXIM_BASE (0xBFF00000UL) +#define AXIM_ASIB1_BASE (AXIM_BASE + 0x42000UL) +#define AXIM_ASIB2_BASE (AXIM_BASE + 0x43000UL) +#define AXIM_ASIB3_BASE (AXIM_BASE + 0x44000UL) +#define AXIM_ASIB4_BASE (AXIM_BASE + 0x45000UL) +#define AXIM_ASIB5_BASE (AXIM_BASE + 0x46000UL) +#define AXIM_ASIB6_BASE (AXIM_BASE + 0x47000UL) +#define AXIM_ASIB7_BASE (AXIM_BASE + 0x48000UL) +#define AXIM_ASIB8_BASE (AXIM_BASE + 0x49000UL) +#define AXIM_ASIB9_BASE (AXIM_BASE + 0x4A000UL) +#define AXIM_ASIB10_BASE (AXIM_BASE + 0x4B000UL) +#define AXIM_ASIB11_BASE (AXIM_BASE + 0x4C000UL) +#define AXIM_AMIB1_BASE (AXIM_BASE + 0x02000UL) +#define AXIM_AMIB2_BASE (AXIM_BASE + 0x03000UL) +#define AXIM_AMIB3_BASE (AXIM_BASE + 0x04000UL) +#define AXIM_AMIB4_BASE (AXIM_BASE + 0x05000UL) +#define AXIM_AMIB5_BASE (AXIM_BASE + 0x06000UL) +#define AXIM_AMIB6_BASE (AXIM_BASE + 0x07000UL) +#define AXIM_AMIB7_BASE (AXIM_BASE + 0x08000UL) +#define AXIM_AMIB8_BASE (AXIM_BASE + 0x09000UL) +#define AXIM_AMIB9_BASE (AXIM_BASE + 0x0A000UL) +#define AXIM_AMIB10_BASE (AXIM_BASE + 0x0B000UL) + +/*!< Unique device ID register base address */ +#define UID_BASE (0x08FFF800UL) + +/*!< Package data register base address */ +#define PACKAGE_BASE (0x08FFF80CUL) + +/* USB OTG registers base addresses */ +#define USB_OTG_GLOBAL_BASE (0x0000UL) +#define USB_OTG_DEVICE_BASE (0x0800UL) +#define USB_OTG_IN_ENDPOINT_BASE (0x0900UL) +#define USB_OTG_OUT_ENDPOINT_BASE (0x0B00UL) +#define USB_OTG_EP_REG_SIZE (0x0020UL) +#define USB_OTG_HOST_BASE (0x0400UL) +#define USB_OTG_HOST_PORT_BASE (0x0440UL) +#define USB_OTG_HOST_CHANNEL_BASE (0x0500UL) +#define USB_OTG_HOST_CHANNEL_SIZE (0x0020UL) +#define USB_OTG_PCGCCTL_BASE (0x0E00UL) +#define USB_OTG_FIFO_BASE (0x1000UL) +#define USB_OTG_FIFO_SIZE (0x1000UL) + +/*!< Root Secure Service Library */ +/************ RSSLIB system Flash region definition constants *************/ +#define RSSLIB_SYS_FLASH_PFUNC_START (0x1FF1FD4CUL) +#define RSSLIB_SYS_FLASH_PFUNC_END (0x1FF1FD78UL) + +/************ RSSLIB function return constants ********************************/ +#define RSSLIB_ERROR (0xF5F5F5F5UL) +#define RSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define RSSLIB_PFUNC_BASE (0x1FF1FD4CUL) +#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_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_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @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 Destination; /*!< OBKeys destination information 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_DataProvisioning_TypeDef)(RSSLIB_DataProvisioningConf_t *pConfig); + +/** + * @brief Prototype of RSSLIB Set Secure OB Function + * @detail This function configure a secure OB. + * @param OB address among following values: + * &(FLASH->WRPSRP), &(FLASH->HDPSRP) or &(FLASH->ROTSRP) + * @param OB mask (example 0x000000FF for updating WRP OB). + * @param OB value + * @param OB Pos: bit position of OB value. + * ObValue << ObPos must be aligned on ObMask. + * @retval RSSLIB_RSS_ERROR on error, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_SetSecOB_TypeDef)(uint32_t ObAddr, uint32_t ObMask, uint32_t ObValue, uint32_t ObPos); + +/** + * @brief Prototype of RSSLIB Get RSS Status Function + * @detail This function return RSS Status. + * Calling GetRssStatus is only relevant after calling + * SetSecOB or DataProvisioning. + * @param none. + * @retval RSSLIB_SUCCESS on success, otherwise return an error 0xF5F5xxxx. + */ +typedef uint32_t (*RSSLIB_GetRssStatus_TypeDef)(void); + +/** + * @brief Prototype of RSSLIB Set Product State Function + * @detail This function change Product State. + * @param Requested Product State among following values: + * 0x17 : Provisioning + * 0x72 : Closed + * 0x5C : Locked + * @retval RSSLIB_RSS_ERROR on error, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_SetProductState_TypeDef)(uint32_t ProductState); + +/** + * @brief Prototype of RSSLIB Get Product State Function + * @detail This function return current Product State. + * @param none. + * @retval RSSLIB_RSS_ERROR on error, + * otherwise return product state among following values: + * 0x39 : Open + * 0x17 : Provisioning + * 0x72 : Closed + * 0x5C : Locked + */ +typedef uint32_t (*RSSLIB_GetProductState_TypeDef)(void); + + +/** + * @brief RSSLib callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_SetSecOB_TypeDef SetSecOB; + uint32_t RESERVED1[4]; + __IM RSSLIB_GetRssStatus_TypeDef GetRssStatus; + __IM RSSLIB_SetProductState_TypeDef SetProductState; + __IM RSSLIB_DataProvisioning_TypeDef DataProvisioning; + __IM RSSLIB_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM RSSLIB_JumpHDPlvl3_TypeDef JumpHDPLvl3; + __IM RSSLIB_GetProductState_TypeDef GetProductState; +} RSSLIB_pFunc_TypeDef; + + +/** @} */ /* End of group STM32H7RSxx_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H7RSxx_Peripheral_declaration + * @{ + */ + +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC12_COMMON ((ADC_Common_TypeDef *) ADC12_COMMON_BASE) +#define ADF1 ((MDF_TypeDef *) ADF1_BASE) +#define ADF1_Filter0 ((MDF_Filter_TypeDef *) ADF1_Filter0_BASE) +#define AXIM_AMIB_1 ((AXIM_AMIB_TypeDef *) AXIM_AMIB1_BASE ) +#define AXIM_AMIB_2 ((AXIM_AMIB_TypeDef *) AXIM_AMIB2_BASE ) +#define AXIM_AMIB_3 ((AXIM_AMIB_TypeDef *) AXIM_AMIB3_BASE ) +#define AXIM_AMIB_4 ((AXIM_AMIB_TypeDef *) AXIM_AMIB4_BASE ) +#define AXIM_AMIB_5 ((AXIM_AMIB_TypeDef *) AXIM_AMIB5_BASE ) +#define AXIM_AMIB_6 ((AXIM_AMIB_TypeDef *) AXIM_AMIB6_BASE ) +#define AXIM_AMIB_7 ((AXIM_AMIB_TypeDef *) AXIM_AMIB7_BASE ) +#define AXIM_AMIB_8 ((AXIM_AMIB_TypeDef *) AXIM_AMIB8_BASE ) +#define AXIM_AMIB_9 ((AXIM_AMIB_TypeDef *) AXIM_AMIB9_BASE ) +#define AXIM_AMIB_10 ((AXIM_AMIB_TypeDef *) AXIM_AMIB10_BASE) +#define AXIM_ASIB_1 ((AXIM_ASIB_TypeDef *) AXIM_ASIB1_BASE ) +#define AXIM_ASIB_2 ((AXIM_ASIB_TypeDef *) AXIM_ASIB2_BASE ) +#define AXIM_ASIB_3 ((AXIM_ASIB_TypeDef *) AXIM_ASIB3_BASE ) +#define AXIM_ASIB_4 ((AXIM_ASIB_TypeDef *) AXIM_ASIB4_BASE ) +#define AXIM_ASIB_5 ((AXIM_ASIB_TypeDef *) AXIM_ASIB5_BASE ) +#define AXIM_ASIB_6 ((AXIM_ASIB_TypeDef *) AXIM_ASIB6_BASE ) +#define AXIM_ASIB_7 ((AXIM_ASIB_TypeDef *) AXIM_ASIB7_BASE ) +#define AXIM_ASIB_8 ((AXIM_ASIB_TypeDef *) AXIM_ASIB8_BASE ) +#define AXIM_ASIB_9 ((AXIM_ASIB_TypeDef *) AXIM_ASIB9_BASE ) +#define AXIM_ASIB_10 ((AXIM_ASIB_TypeDef *) AXIM_ASIB10_BASE) +#define AXIM_ASIB_11 ((AXIM_ASIB_TypeDef *) AXIM_ASIB11_BASE) +#define CEC ((CEC_TypeDef *) CEC_BASE) +#define CORDIC ((CORDIC_TypeDef *) CORDIC_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define CRS ((CRS_TypeDef *) CRS_BASE) +#define CRYP ((CRYP_TypeDef *) CRYP_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) +#define DCMIPP ((DCMIPP_TypeDef *) DCMIPP_BASE) +#define DLYB_SDMMC1 ((DLYB_TypeDef *) DLYB_SDMMC1_BASE) +#define DLYB_SDMMC2 ((DLYB_TypeDef *) DLYB_SDMMC2_BASE) +#define DMA2D ((DMA2D_TypeDef *) DMA2D_BASE) +#define DTS ((DTS_TypeDef *) DTS_BASE) +#define ETH ((ETH_TypeDef *)ETH_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define FDCAN1 ((FDCAN_GlobalTypeDef *) FDCAN1_BASE) +#define FDCAN2 ((FDCAN_GlobalTypeDef *) FDCAN2_BASE) +#define FDCAN_CONFIG ((FDCAN_Config_TypeDef *) FDCAN_CONFIG_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define FMC_Bank1_R ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE) +#define FMC_Bank1E_R ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE) +#define FMC_Bank3_R ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE) +#define FMC_Bank5_6_R ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE) +#define GFXTIM ((GFXTIM_TypeDef *) GFXTIM_BASE) +#define GFXMMU ((GFXMMU_TypeDef *) GFXMMU_BASE) +#define GPU2D GPU2D_BASE +#define GPDMA1 ((DMA_TypeDef *) GPDMA1_BASE) +#define GPDMA1_Channel0 ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE) +#define GPDMA1_Channel1 ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE) +#define GPDMA1_Channel2 ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE) +#define GPDMA1_Channel3 ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE) +#define GPDMA1_Channel4 ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE) +#define GPDMA1_Channel5 ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE) +#define GPDMA1_Channel6 ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE) +#define GPDMA1_Channel7 ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE) +#define GPDMA1_Channel8 ((DMA_Channel_TypeDef *) GPDMA1_Channel8_BASE) +#define GPDMA1_Channel9 ((DMA_Channel_TypeDef *) GPDMA1_Channel9_BASE) +#define GPDMA1_Channel10 ((DMA_Channel_TypeDef *) GPDMA1_Channel10_BASE) +#define GPDMA1_Channel11 ((DMA_Channel_TypeDef *) GPDMA1_Channel11_BASE) +#define GPDMA1_Channel12 ((DMA_Channel_TypeDef *) GPDMA1_Channel12_BASE) +#define GPDMA1_Channel13 ((DMA_Channel_TypeDef *) GPDMA1_Channel13_BASE) +#define GPDMA1_Channel14 ((DMA_Channel_TypeDef *) GPDMA1_Channel14_BASE) +#define GPDMA1_Channel15 ((DMA_Channel_TypeDef *) GPDMA1_Channel15_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOM ((GPIO_TypeDef *) GPIOM_BASE) +#define GPION ((GPIO_TypeDef *) GPION_BASE) +#define GPIOO ((GPIO_TypeDef *) GPIOO_BASE) +#define GPIOP ((GPIO_TypeDef *) GPIOP_BASE) +#define HASH ((HASH_TypeDef *) HASH_BASE) +#define HASH_DIGEST ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE) +#define HPDMA1 ((DMA_TypeDef *) HPDMA1_BASE) +#define HPDMA1_Channel0 ((DMA_Channel_TypeDef *) HPDMA1_Channel0_BASE) +#define HPDMA1_Channel1 ((DMA_Channel_TypeDef *) HPDMA1_Channel1_BASE) +#define HPDMA1_Channel2 ((DMA_Channel_TypeDef *) HPDMA1_Channel2_BASE) +#define HPDMA1_Channel3 ((DMA_Channel_TypeDef *) HPDMA1_Channel3_BASE) +#define HPDMA1_Channel4 ((DMA_Channel_TypeDef *) HPDMA1_Channel4_BASE) +#define HPDMA1_Channel5 ((DMA_Channel_TypeDef *) HPDMA1_Channel5_BASE) +#define HPDMA1_Channel6 ((DMA_Channel_TypeDef *) HPDMA1_Channel6_BASE) +#define HPDMA1_Channel7 ((DMA_Channel_TypeDef *) HPDMA1_Channel7_BASE) +#define HPDMA1_Channel8 ((DMA_Channel_TypeDef *) HPDMA1_Channel8_BASE) +#define HPDMA1_Channel9 ((DMA_Channel_TypeDef *) HPDMA1_Channel9_BASE) +#define HPDMA1_Channel10 ((DMA_Channel_TypeDef *) HPDMA1_Channel10_BASE) +#define HPDMA1_Channel11 ((DMA_Channel_TypeDef *) HPDMA1_Channel11_BASE) +#define HPDMA1_Channel12 ((DMA_Channel_TypeDef *) HPDMA1_Channel12_BASE) +#define HPDMA1_Channel13 ((DMA_Channel_TypeDef *) HPDMA1_Channel13_BASE) +#define HPDMA1_Channel14 ((DMA_Channel_TypeDef *) HPDMA1_Channel14_BASE) +#define HPDMA1_Channel15 ((DMA_Channel_TypeDef *) HPDMA1_Channel15_BASE) +#define ICACHE ((ICACHE_TypeDef *) ICACHE_BASE) +#define JPEG ((JPEG_TypeDef *) JPEG_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define I3C1 ((I3C_TypeDef *) I3C1_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define LPTIM1 ((LPTIM_TypeDef *) LPTIM1_BASE) +#define LPTIM2 ((LPTIM_TypeDef *) LPTIM2_BASE) +#define LPTIM3 ((LPTIM_TypeDef *) LPTIM3_BASE) +#define LPTIM4 ((LPTIM_TypeDef *) LPTIM4_BASE) +#define LPTIM5 ((LPTIM_TypeDef *) LPTIM5_BASE) +#define LPUART1 ((USART_TypeDef *) LPUART1_BASE) +#define LTDC ((LTDC_TypeDef *)LTDC_BASE) +#define LTDC_Layer1 ((LTDC_Layer_TypeDef *)LTDC_Layer1_BASE) +#define LTDC_Layer2 ((LTDC_Layer_TypeDef *)LTDC_Layer2_BASE) +#define MCE1 ((MCE_TypeDef *) MCE1_BASE) +#define MCE1_REGION1 ((MCE_Region_TypeDef *) MCE1_REGION1_BASE) +#define MCE1_REGION2 ((MCE_Region_TypeDef *) MCE1_REGION2_BASE) +#define MCE1_REGION3 ((MCE_Region_TypeDef *) MCE1_REGION3_BASE) +#define MCE1_REGION4 ((MCE_Region_TypeDef *) MCE1_REGION4_BASE) +#define MCE1_CONTEXT1 ((MCE_Context_TypeDef *) MCE1_CONTEXT1_BASE) +#define MCE1_CONTEXT2 ((MCE_Context_TypeDef *) MCE1_CONTEXT2_BASE) +#define MCE2 ((MCE_TypeDef *) MCE2_BASE) +#define MCE2_REGION1 ((MCE_Region_TypeDef *) MCE2_REGION1_BASE) +#define MCE2_REGION2 ((MCE_Region_TypeDef *) MCE2_REGION2_BASE) +#define MCE2_REGION3 ((MCE_Region_TypeDef *) MCE2_REGION3_BASE) +#define MCE2_REGION4 ((MCE_Region_TypeDef *) MCE2_REGION4_BASE) +#define MCE3 ((MCE_TypeDef *) MCE3_BASE) +#define MCE3_REGION1 ((MCE_Region_TypeDef *) MCE3_REGION1_BASE) +#define MCE3_REGION2 ((MCE_Region_TypeDef *) MCE3_REGION2_BASE) +#define MCE3_REGION3 ((MCE_Region_TypeDef *) MCE3_REGION3_BASE) +#define MCE3_REGION4 ((MCE_Region_TypeDef *) MCE3_REGION4_BASE) +#define MDIOS ((MDIOS_TypeDef *) MDIOS_BASE) +#define PKA ((PKA_TypeDef *) PKA_BASE) +#define PSSI ((PSSI_TypeDef *) PSSI_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define RAMECC1 ((RAMECC_TypeDef *)RAMECC1_BASE) +#define RAMECC2 ((RAMECC_TypeDef *)RAMECC2_BASE) +#define RAMECC1_Monitor0 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor0_BASE) +#define RAMECC1_Monitor1 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor1_BASE) +#define RAMECC1_Monitor2 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor2_BASE) +#define RAMECC1_Monitor3 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor3_BASE) +#define RAMECC1_Monitor4 ((RAMECC_MonitorTypeDef *)RAMECC1_Monitor4_BASE) +#define RAMECC2_Monitor1 ((RAMECC_MonitorTypeDef *)RAMECC2_Monitor1_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define SAES ((SAES_TypeDef *) SAES_BASE) +#define SAI1 ((SAI_TypeDef *) SAI1_BASE) +#define SAI1_Block_A ((SAI_Block_TypeDef *) SAI1_Block_A_BASE) +#define SAI1_Block_B ((SAI_Block_TypeDef *) SAI1_Block_B_BASE) +#define SAI2 ((SAI_TypeDef *) SAI2_BASE) +#define SAI2_Block_A ((SAI_Block_TypeDef *) SAI2_Block_A_BASE) +#define SAI2_Block_B ((SAI_Block_TypeDef *) SAI2_Block_B_BASE) +#define SBS ((SBS_TypeDef *) SBS_BASE) +#define SDMMC1 ((SDMMC_TypeDef *) SDMMC1_BASE) +#define SDMMC2 ((SDMMC_TypeDef *) SDMMC2_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define SPI4 ((SPI_TypeDef *) SPI4_BASE) +#define SPI5 ((SPI_TypeDef *) SPI5_BASE) +#define SPI6 ((SPI_TypeDef *) SPI6_BASE) +#define SPDIFRX ((SPDIFRX_TypeDef *) SPDIFRX_BASE) +#define TAMP ((TAMP_TypeDef *) TAMP_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define TIM15 ((TIM_TypeDef *) TIM15_BASE) +#define TIM16 ((TIM_TypeDef *) TIM16_BASE) +#define TIM17 ((TIM_TypeDef *) TIM17_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define UART7 ((USART_TypeDef *) UART7_BASE) +#define UART8 ((USART_TypeDef *) UART8_BASE) +#define UCPD1 ((UCPD_TypeDef *) UCPD1_BASE) +#define USB_OTG_HS ((USB_OTG_GlobalTypeDef *) USB_OTG_HS_PERIPH_BASE) +#define USB_OTG_FS ((USB_OTG_GlobalTypeDef *) USB_OTG_FS_PERIPH_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define XSPI1 ((XSPI_TypeDef *) XSPI1_R_BASE) +#define XSPI2 ((XSPI_TypeDef *) XSPI2_R_BASE) +#define XSPIM ((XSPIM_TypeDef *) XSPIM_BASE) +#define VREFBUF ((VREFBUF_TypeDef *) VREFBUF_BASE) + +/** @} */ /* End of group STM32H7RSxx_Peripheral_declaration */ + +/** @addtogroup STM32H7RSxx_Peripheral_Exported_constants + * @{ + */ + +/** @addtogroup STM32H7RSxx_Peripheral_Hardware_Constant_Definition + * @{ + */ +#define LSI_STARTUP_TIME 130U /*!< LSI Maximum startup time in us */ +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_Peripheral_Registers_Bits_Definition + * @{ + */ +/******************************************************************************/ +/* Peripheral Registers Bits Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ + +/* + * @brief Specific device feature definitions (not present on all devices in the STM32G4 series) + */ +#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_ADFCFG_Pos (2U) +#define ADC_CFGR_ADFCFG_Msk (0x1UL << ADC_CFGR_ADFCFG_Pos) /*!< 0x00000004 */ +#define ADC_CFGR_ADFCFG ADC_CFGR_ADFCFG_Msk /*!< ADC ADF 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_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 */ + +/******************** 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 (0x7FFFFUL << 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 */ + +/******************** Bit definition for ADC_AWD3CR register ****************/ +#define ADC_AWD3CR_AWD3CH_Pos (0U) +#define ADC_AWD3CR_AWD3CH_Msk (0x7FFFFUL << 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 */ + +/******************** Bit definition for ADC_DIFSEL register ****************/ +#define ADC_DIFSEL_DIFSEL_Pos (0U) +#define ADC_DIFSEL_DIFSEL_Msk (0x7FFFFUL << 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 */ + +/******************** 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 (0x1UL << ADC_OR_OP0_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP0 ADC_OR_OP0_Msk /*!< ADC internal path to VDDCORE */ + +/************************* 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 */ + +/******************************************************************************/ +/* */ +/* AXIM */ +/* */ +/******************************************************************************/ +/******************* Bit definition for AXIM_ASIB_FNMOD2 register **********/ +#define AXIM_ASIB_FNMOD2_BYPASS_MERGE_Pos (0U) +#define AXIM_ASIB_FNMOD2_BYPASS_MERGE_Msk (0x1UL << AXIM_ASIB_FNMOD2_BYPASS_MERGE_Pos) /*!< 0x00000001 */ +#define AXIM_ASIB_FNMOD2_BYPASS_MERGE AXIM_ASIB_FNMOD2_BYPASS_MERGE_Msk /*!< Bypass Merge enable */ + +/******************* Bit definition for AXIM_ASIB_READQOS register ********/ +#define AXIM_ASIB_READQOS_AR_QOS_Pos (0U) +#define AXIM_ASIB_READQOS_AR_QOS_Msk (0xFUL << AXIM_ASIB_READQOS_AR_QOS_Pos) /*!< 0x0000000F */ +#define AXIM_ASIB_READQOS_AR_QOS AXIM_ASIB_READQOS_AR_QOS_Msk /*!< Read channel QoS setting */ + +/******************* Bit definition for AXIM_ASIB_WRITEQOS register *******/ +#define AXIM_ASIB_WRITEQOS_AW_QOS_Pos (0U) +#define AXIM_ASIB_WRITEQOS_AW_QOS_Msk (0xFUL << AXIM_ASIB_WRITEQOS_AW_QOS_Pos) /*!< 0x0000000F */ +#define AXIM_ASIB_WRITEQOS_AW_QOS AXIM_ASIB_WRITEQOS_AW_QOS_Msk /*!< Write channel QoS setting */ + +/******************* Bit definition for AXIM_ASIB_FNMOD register **********/ +#define AXIM_ASIB_FNMOD_READ_ISS_Pos (0U) +#define AXIM_ASIB_FNMOD_READ_ISS_Msk (0x1UL << AXIM_ASIB_FNMOD_READ_ISS_Pos) /*!< 0x00000001 */ +#define AXIM_ASIB_FNMOD_READ_ISS AXIM_ASIB_FNMOD_READ_ISS_Msk /*!< Force read issuing capability to 1 */ +#define AXIM_ASIB_FNMOD_WRITE_ISS_Pos (1U) +#define AXIM_ASIB_FNMOD_WRITE_ISS_Msk (0x1UL << AXIM_ASIB_FNMOD_WRITE_ISS_Pos) /*!< 0x00000002 */ +#define AXIM_ASIB_FNMOD_WRITE_ISS AXIM_ASIB_FNMOD_WRITE_ISS_Msk /*!< Force write issuing capability to 1 */ + +/******************* Bit definition for AXIM_AMIB_FNMODBMISS register **********/ +#define AXIM_AMIB_FNMODBMISS_READ_ISS_Pos (0U) +#define AXIM_AMIB_FNMODBMISS_READ_ISS_Msk (0x1UL << AXIM_AMIB_FNMODBMISS_READ_ISS_Pos) /*!< 0x00000001 */ +#define AXIM_AMIB_FNMODBMISS_READ_ISS AXIM_AMIB_FNMODBMISS_READ_ISS_Msk /*!< Force read issuing capability to 1 */ +#define AXIM_AMIB_FNMODBMISS_WRITE_ISS_Pos (1U) +#define AXIM_AMIB_FNMODBMISS_WRITE_ISS_Msk (0x1UL << AXIM_AMIB_FNMODBMISS_WRITE_ISS_Pos) /*!< 0x00000002 */ +#define AXIM_AMIB_FNMODBMISS_WRITE_ISS AXIM_AMIB_FNMODBMISS_WRITE_ISS_Msk /*!< Force write issuing capability to 1 */ + +/******************* Bit definition for AXIM_AMIB_FNMOD2 register **********/ +#define AXIM_AMIB_FNMOD2_BYPASS_MERGE_Pos (0U) +#define AXIM_AMIB_FNMOD2_BYPASS_MERGE_Msk (0x1UL << AXIM_AMIB_FNMOD2_BYPASS_MERGE_Pos) /*!< 0x00000001 */ +#define AXIM_AMIB_FNMOD2_BYPASS_MERGE AXIM_AMIB_FNMOD2_BYPASS_MERGE_Msk /*!< Bypass Merge enable */ + +/******************* Bit definition for AXIM_AMIB_FNMODLB register **********/ +#define AXIM_AMIB_FNMODLB_LONG_BURST_Pos (0U) +#define AXIM_AMIB_FNMODLB_LONG_BURST_Msk (0x1UL << AXIM_AMIB_FNMODLB_LONG_BURST_Pos) /*!< 0x00000001 */ +#define AXIM_AMIB_FNMODLB_LONG_BURST AXIM_AMIB_FNMODLB_LONG_BURST_Msk /*!< Long bursts can be generated */ + +/******************* Bit definition for AXIM_AMIB_FNMOD register **********/ +#define AXIM_AMIB_FNMOD_READ_ISS_Pos (0U) +#define AXIM_AMIB_FNMOD_READ_ISS_Msk (0x1UL << AXIM_AMIB_FNMOD_READ_ISS_Pos) /*!< 0x00000001 */ +#define AXIM_AMIB_FNMOD_READ_ISS AXIM_AMIB_FNMOD_READ_ISS_Msk /*!< Force read issuing capability to 1 */ +#define AXIM_AMIB_FNMOD_WRITE_ISS_Pos (1U) +#define AXIM_AMIB_FNMOD_WRITE_ISS_Msk (0x1UL << AXIM_AMIB_FNMOD_WRITE_ISS_Pos) /*!< 0x00000002 */ +#define AXIM_AMIB_FNMOD_WRITE_ISS AXIM_AMIB_FNMOD_WRITE_ISS_Msk /*!< Force write issuing capability to 1 */ + +/******************************************************************************/ +/* */ +/* VREFBUF */ +/* */ +/******************************************************************************/ +/******************* Bit definition for VREFBUF_CSR register ****************/ +#define VREFBUF_CSR_ENVR_Pos (0U) +#define VREFBUF_CSR_ENVR_Msk (0x1UL << VREFBUF_CSR_ENVR_Pos) /*!< 0x00000001 */ +#define VREFBUF_CSR_ENVR VREFBUF_CSR_ENVR_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 */ + + +/******************************************************************************/ +/* */ +/* Parallel Synchronous Slave Interface (PSSI ) */ +/* */ +/******************************************************************************/ +/******************** Bit definition for PSSI_CR register *******************/ +#define PSSI_CR_CKPOL_Pos (5U) +#define PSSI_CR_CKPOL_Msk (0x1UL << PSSI_CR_CKPOL_Pos) /*!< 0x00000020 */ +#define PSSI_CR_CKPOL PSSI_CR_CKPOL_Msk /*!< Parallel data clock polarity */ +#define PSSI_CR_DEPOL_Pos (6U) +#define PSSI_CR_DEPOL_Msk (0x1UL << PSSI_CR_DEPOL_Pos) /*!< 0x00000040 */ +#define PSSI_CR_DEPOL PSSI_CR_DEPOL_Msk /*!< Data enable polarity */ +#define PSSI_CR_RDYPOL_Pos (8U) +#define PSSI_CR_RDYPOL_Msk (0x1UL << PSSI_CR_RDYPOL_Pos) /*!< 0x00000100 */ +#define PSSI_CR_RDYPOL PSSI_CR_RDYPOL_Msk /*!< Ready polarity */ +#define PSSI_CR_EDM_Pos (10U) +#define PSSI_CR_EDM_Msk (0x3UL << PSSI_CR_EDM_Pos) /*!< 0x00000C00 */ +#define PSSI_CR_EDM PSSI_CR_EDM_Msk /*!< Extended data mode */ +#define PSSI_CR_ENABLE_Pos (14U) +#define PSSI_CR_ENABLE_Msk (0x1UL << PSSI_CR_ENABLE_Pos) /*!< 0x00004000 */ +#define PSSI_CR_ENABLE PSSI_CR_ENABLE_Msk /*!< PSSI enable */ +#define PSSI_CR_DERDYCFG_Pos (18U) +#define PSSI_CR_DERDYCFG_Msk (0x7UL << PSSI_CR_DERDYCFG_Pos) /*!< 0x001C0000 */ +#define PSSI_CR_DERDYCFG PSSI_CR_DERDYCFG_Msk /*!< Data enable and ready configuration */ +#define PSSI_CR_CKSRC_Pos (29U) +#define PSSI_CR_CKSRC_Msk (0x1UL << PSSI_CR_CKSRC_Pos) /*!< 0x20000000 */ +#define PSSI_CR_CKSRC PSSI_CR_CKSRC_Msk /*!< Clock source */ +#define PSSI_CR_DMAEN_Pos (30U) +#define PSSI_CR_DMAEN_Msk (0x1UL << PSSI_CR_DMAEN_Pos) /*!< 0x40000000 */ +#define PSSI_CR_DMAEN PSSI_CR_DMAEN_Msk /*!< DMA enable */ +#define PSSI_CR_OUTEN_Pos (31U) +#define PSSI_CR_OUTEN_Msk (0x1UL << PSSI_CR_OUTEN_Pos) /*!< 0x80000000 */ +#define PSSI_CR_OUTEN PSSI_CR_OUTEN_Msk /*!< Data direction selection */ + +/******************** Bit definition for PSSI_SR register *******************/ +#define PSSI_SR_RTT4B_Pos (2U) +#define PSSI_SR_RTT4B_Msk (0x1UL << PSSI_SR_RTT4B_Pos) /*!< 0x00000004 */ +#define PSSI_SR_RTT4B PSSI_SR_RTT4B_Msk /*!< Ready to transfer four bytes */ +#define PSSI_SR_RTT1B_Pos (3U) +#define PSSI_SR_RTT1B_Msk (0x1UL << PSSI_SR_RTT1B_Pos) /*!< 0x00000008 */ +#define PSSI_SR_RTT1B PSSI_SR_RTT1B_Msk /*!< Ready to transfer one byte */ + +/******************** Bit definition for PSSI_RIS register ******************/ +#define PSSI_RIS_OVR_RIS_Pos (1U) +#define PSSI_RIS_OVR_RIS_Msk (0x1UL << PSSI_RIS_OVR_RIS_Pos) /*!< 0x00000002 */ +#define PSSI_RIS_OVR_RIS PSSI_RIS_OVR_RIS_Msk /*!< Data buffer overrun/underrun raw interrupt status */ + +/******************** Bit definition for PSSI_IER register ******************/ +#define PSSI_IER_OVR_IE_Pos (1U) +#define PSSI_IER_OVR_IE_Msk (0x1UL << PSSI_IER_OVR_IE_Pos) /*!< 0x00000002 */ +#define PSSI_IER_OVR_IE PSSI_IER_OVR_IE_Msk /*!< Data buffer overrun/underrun interrupt enable */ + +/******************** Bit definition for PSSI_MIS register ******************/ +#define PSSI_MIS_OVR_MIS_Pos (1U) +#define PSSI_MIS_OVR_MIS_Msk (0x1UL << PSSI_MIS_OVR_MIS_Pos) /*!< 0x00000002 */ +#define PSSI_MIS_OVR_MIS PSSI_MIS_OVR_MIS_Msk /*!< Data buffer overrun/underrun masked interrupt status */ + +/******************** Bit definition for PSSI_ICR register ******************/ +#define PSSI_ICR_OVR_ISC_Pos (1U) +#define PSSI_ICR_OVR_ISC_Msk (0x1UL << PSSI_ICR_OVR_ISC_Pos) /*!< 0x00000002 */ +#define PSSI_ICR_OVR_ISC PSSI_ICR_OVR_ISC_Msk /*!< Data buffer overrun/underrun interrupt status clear */ + +/******************** Bit definition for PSSI_DR register *******************/ +#define PSSI_DR_DR_Pos (0U) +#define PSSI_DR_DR_Msk (0xFFFFFFFFUL << PSSI_DR_DR_Pos) /*!< 0xFFFFFFF */ +#define PSSI_DR_DR PSSI_DR_DR_Msk /*!< Data register */ + + +/******************************************************************************/ +/* */ +/* Power Control */ +/* */ +/******************************************************************************/ +/******************** Bit definition for PWR_CR1 register *******************/ +#define PWR_CR1_SVOS_Pos (0U) +#define PWR_CR1_SVOS_Msk (0x1UL << PWR_CR1_SVOS_Pos) /*!< 0x00000001 */ +#define PWR_CR1_SVOS PWR_CR1_SVOS_Msk /*!< System STOP mode Voltage Scaling selection. */ + +#define PWR_CR1_PVDE_Pos (4U) +#define PWR_CR1_PVDE_Msk (0x1UL << PWR_CR1_PVDE_Pos) /*!< 0x00000010 */ +#define PWR_CR1_PVDE PWR_CR1_PVDE_Msk /*!< Programmable Voltage detector enable. */ + +#define PWR_CR1_PLS_Pos (5U) +#define PWR_CR1_PLS_Msk (0x7UL << PWR_CR1_PLS_Pos) /*!< 0x000000E0 */ +#define PWR_CR1_PLS PWR_CR1_PLS_Msk /*!< Programmable Voltage Detector level selection */ +#define PWR_CR1_PLS_0 (0x1UL << PWR_CR1_PLS_Pos) /*!< 0x00000020 */ +#define PWR_CR1_PLS_1 (0x2UL << PWR_CR1_PLS_Pos) /*!< 0x00000040 */ +#define PWR_CR1_PLS_2 (0x4UL << PWR_CR1_PLS_Pos) /*!< 0x00000080 */ + +#define PWR_CR1_DBP_Pos (8U) +#define PWR_CR1_DBP_Msk (0x1UL << PWR_CR1_DBP_Pos) /*!< 0x00000100 */ +#define PWR_CR1_DBP PWR_CR1_DBP_Msk /*!< Disable Back-up domain Protection */ + +#define PWR_CR1_FLPS_Pos (9U) +#define PWR_CR1_FLPS_Msk (0x1UL << PWR_CR1_FLPS_Pos) /*!< 0x00000200 */ +#define PWR_CR1_FLPS PWR_CR1_FLPS_Msk /*!< Flash low power mode in STOP */ + +#define PWR_CR1_BOOSTE_Pos (11U) +#define PWR_CR1_BOOSTE_Msk (0x1UL << PWR_CR1_BOOSTE_Pos) /*!< 0x00000800 */ +#define PWR_CR1_BOOSTE PWR_CR1_BOOSTE_Msk /*!< Analog Switch VBoost control. */ + +#define PWR_CR1_AVDREADY_Pos (12) +#define PWR_CR1_AVDREADY_Msk (0x1UL << PWR_CR1_AVDREADY_Pos) /*!< 0x00001000 */ +#define PWR_CR1_AVDREADY PWR_CR1_AVDREADY_Msk /*!< Analog Voltage Ready. */ + +#define PWR_CR1_AVDEN_Pos (13U) +#define PWR_CR1_AVDEN_Msk (0x1UL << PWR_CR1_AVDEN_Pos) /*!< 0x00002000 */ +#define PWR_CR1_AVDEN PWR_CR1_AVDEN_Msk /*!< Analog Voltage Detector Enable */ + +#define PWR_CR1_ALS_Pos (14U) +#define PWR_CR1_ALS_Msk (0x3UL << PWR_CR1_ALS_Pos) /*!< 0x0000A000 */ +#define PWR_CR1_ALS PWR_CR1_ALS_Msk /*!< Analog Voltage Detector level selection */ +#define PWR_CR1_ALS_0 (0x1UL << PWR_CR1_ALS_Pos) /*!< 0x00004000 */ +#define PWR_CR1_ALS_1 (0x2UL << PWR_CR1_ALS_Pos) /*!< 0x00008000 */ + +/******************** Bit definition for PWR_SR1 register ********************/ +#define PWR_SR1_ACTVOS_Pos (0U) +#define PWR_SR1_ACTVOS_Msk (0x1UL << PWR_SR1_ACTVOS_Pos) /*!< 0x00000001 */ +#define PWR_SR1_ACTVOS PWR_SR1_ACTVOS_Msk /*!< VOS currently applied for VCORE voltage scaling selection */ + +#define PWR_SR1_ACTVOSRDY_Pos (1U) +#define PWR_SR1_ACTVOSRDY_Msk (0x1UL << PWR_SR1_ACTVOSRDY_Pos) /*!< 0x00000002 */ +#define PWR_SR1_ACTVOSRDY PWR_SR1_ACTVOSRDY_Msk /*!< Ready bit for current actual used VOS for VDD11 Voltage Scaling */ + +#define PWR_SR1_PVDO_Pos (4U) +#define PWR_SR1_PVDO_Msk (0x1UL << PWR_SR1_PVDO_Pos) /*!< 0x00000010 */ +#define PWR_SR1_PVDO PWR_SR1_PVDO_Msk /*!< Programmable Voltage Detect Output */ + +#define PWR_SR1_AVDO_Pos (13U) +#define PWR_SR1_AVDO_Msk (0x1UL << PWR_SR1_AVDO_Pos) /*!< 0x00002000 */ +#define PWR_SR1_AVDO PWR_SR1_AVDO_Msk /*!< Analog Voltage Detect Output on VDDA */ + +/******************** Bit definition for PWR_CSR1 register ********************/ +#define PWR_CSR1_BREN_Pos (0U) +#define PWR_CSR1_BREN_Msk (0x1UL << PWR_CSR1_BREN_Pos) /*!< 0x00000001 */ +#define PWR_CSR1_BREN PWR_CSR1_BREN_Msk /*!< Backup regulator enable */ + +#define PWR_CSR1_MONEN_Pos (4U) +#define PWR_CSR1_MONEN_Msk (0x1UL << PWR_CSR1_MONEN_Pos) /*!< 0x00000010 */ +#define PWR_CSR1_MONEN PWR_CSR1_MONEN_Msk /*!< VBAT and temperature monitoring enable */ + +#define PWR_CSR1_BRRDY_Pos (16U) +#define PWR_CSR1_BRRDY_Msk (0x1UL << PWR_CSR1_BRRDY_Pos) /*!< 0x00010000 */ +#define PWR_CSR1_BRRDY PWR_CSR1_BRRDY_Msk /*!< Backup regulator ready */ + +#define PWR_CSR1_VBATL_Pos (20U) +#define PWR_CSR1_VBATL_Msk (0x1UL << PWR_CSR1_VBATL_Pos) /*!< 0x00100000 */ +#define PWR_CSR1_VBATL PWR_CSR1_VBATL_Msk /*!< Monitored VBAT level above low threshold */ + +#define PWR_CSR1_VBATH_Pos (21U) +#define PWR_CSR1_VBATH_Msk (0x1UL << PWR_CSR1_VBATH_Pos) /*!< 0x00200000 */ +#define PWR_CSR1_VBATH PWR_CSR1_VBATH_Msk /*!< Monitored VBAT level above high threshold */ + +#define PWR_CSR1_TEMPL_Pos (22U) +#define PWR_CSR1_TEMPL_Msk (0x1UL << PWR_CSR1_TEMPL_Pos) /*!< 0x00400000 */ +#define PWR_CSR1_TEMPL PWR_CSR1_TEMPL_Msk /*!< Monitored temperature level above low threshold */ + +#define PWR_CSR1_TEMPH_Pos (23U) +#define PWR_CSR1_TEMPH_Msk (0x1UL << PWR_CSR1_TEMPH_Pos) /*!< 0x00800000 */ +#define PWR_CSR1_TEMPH PWR_CSR1_TEMPH_Msk /*!< Monitored temperature level above high threshold */ + +/******************** Bit definition for PWR_CSR2 register ********************/ +#define PWR_CSR2_BYPASS_Pos (0U) +#define PWR_CSR2_BYPASS_Msk (0x1UL << PWR_CSR2_BYPASS_Pos) /*!< 0x00000001 */ +#define PWR_CSR2_BYPASS PWR_CSR2_BYPASS_Msk /*!< Power Management Unit bypass */ + +#define PWR_CSR2_LDOEN_Pos (1U) +#define PWR_CSR2_LDOEN_Msk (0x1UL << PWR_CSR2_LDOEN_Pos) /*!< 0x00000002 */ +#define PWR_CSR2_LDOEN PWR_CSR2_LDOEN_Msk /*!< Low Drop-Out regulator enable */ + +#define PWR_CSR2_SDEN_Pos (2U) +#define PWR_CSR2_SDEN_Msk (0x1UL << PWR_CSR2_SDEN_Pos) /*!< 0x00000004 */ +#define PWR_CSR2_SDEN PWR_CSR2_SDEN_Msk /*!< SMPS Step-down converter enable */ + +#define PWR_CSR2_SMPSEXTHP_Pos (3U) +#define PWR_CSR2_SMPSEXTHP_Msk (0x1UL << PWR_CSR2_SMPSEXTHP_Pos) /*!< 0x00000008 */ +#define PWR_CSR2_SMPSEXTHP PWR_CSR2_SMPSEXTHP_Msk /*!< SMPS external power delivery selection */ + +#define PWR_CSR2_SDHILEVEL_Pos (4U) +#define PWR_CSR2_SDHILEVEL_Msk (0x1UL << PWR_CSR2_SDHILEVEL_Pos) /*!< 0x00000030 */ +#define PWR_CSR2_SDHILEVEL PWR_CSR2_SDHILEVEL_Msk /*!< SMPS step-down converter voltage output for LDO or external supply */ + +#define PWR_CSR2_VBE_Pos (8U) +#define PWR_CSR2_VBE_Msk (0x1UL << PWR_CSR2_VBE_Pos) /*!< 0x00000100 */ +#define PWR_CSR2_VBE PWR_CSR2_VBE_Msk /*!< VBAT charging enable */ + +#define PWR_CSR2_VBRS_Pos (9U) +#define PWR_CSR2_VBRS_Msk (0x1UL << PWR_CSR2_VBRS_Pos) /*!< 0x00000200 */ +#define PWR_CSR2_VBRS PWR_CSR2_VBRS_Msk /*!< VBAT charging resistor selection */ + +#define PWR_CSR2_XSPICAP1_Pos (10U) +#define PWR_CSR2_XSPICAP1_Msk (0x3UL << PWR_CSR2_XSPICAP1_Pos) /*!< 0x00000C00 */ +#define PWR_CSR2_XSPICAP1 PWR_CSR2_XSPICAP1_Msk /*!< XSPI port 1 capacitor control bits */ +#define PWR_CSR2_XSPICAP1_0 (0x1UL << PWR_CSR2_XSPICAP1_Pos) /*!< 0x00000400 */ +#define PWR_CSR2_XSPICAP1_1 (0x2UL << PWR_CSR2_XSPICAP1_Pos) /*!< 0x00000800 */ + +#define PWR_CSR2_XSPICAP2_Pos (12U) +#define PWR_CSR2_XSPICAP2_Msk (0x3UL << PWR_CSR2_XSPICAP2_Pos) /*!< 0x00003000 */ +#define PWR_CSR2_XSPICAP2 PWR_CSR2_XSPICAP2_Msk /*!< XSPI port 2 capacitor control bits */ +#define PWR_CSR2_XSPICAP2_0 (0x1UL << PWR_CSR2_XSPICAP2_Pos) /*!< 0x00001000 */ +#define PWR_CSR2_XSPICAP2_1 (0x2UL << PWR_CSR2_XSPICAP2_Pos) /*!< 0x00002000 */ + +#define PWR_CSR2_EN_XSPIM1_Pos (14U) +#define PWR_CSR2_EN_XSPIM1_Msk (0x1UL << PWR_CSR2_EN_XSPIM1_Pos) /*!< 0x00004000 */ +#define PWR_CSR2_EN_XSPIM1 PWR_CSR2_EN_XSPIM1_Msk /*!< XSPIM1 external supply enable */ + +#define PWR_CSR2_EN_XSPIM2_Pos (15U) +#define PWR_CSR2_EN_XSPIM2_Msk (0x1UL << PWR_CSR2_EN_XSPIM2_Pos) /*!< 0x00008000 */ +#define PWR_CSR2_EN_XSPIM2 PWR_CSR2_EN_XSPIM2_Msk /*!< XSPIM2 external supply enable */ + +#define PWR_CSR2_SDEXTRDY_Pos (16U) +#define PWR_CSR2_SDEXTRDY_Msk (0x1UL << PWR_CSR2_SDEXTRDY_Pos) /*!< 0x00010000 */ +#define PWR_CSR2_SDEXTRDY PWR_CSR2_SDEXTRDY_Msk /*!< SMPS External supply ready */ + +#define PWR_CSR2_USB33DEN_Pos (24U) +#define PWR_CSR2_USB33DEN_Msk (0x1UL << PWR_CSR2_USB33DEN_Pos) /*!< 0x01000000 */ +#define PWR_CSR2_USB33DEN PWR_CSR2_USB33DEN_Msk /*!< VDD33_USB voltage level detector enable */ + +#define PWR_CSR2_USBREGEN_Pos (25U) +#define PWR_CSR2_USBREGEN_Msk (0x1UL << PWR_CSR2_USBREGEN_Pos) /*!< 0x02000000 */ +#define PWR_CSR2_USBREGEN PWR_CSR2_USBREGEN_Msk /*!< USB regulator enable */ + +#define PWR_CSR2_USB33RDY_Pos (26U) +#define PWR_CSR2_USB33RDY_Msk (0x1UL << PWR_CSR2_USB33RDY_Pos) /*!< 0x04000000 */ +#define PWR_CSR2_USB33RDY PWR_CSR2_USB33RDY_Msk /*!< USB supply ready */ + +#define PWR_CSR2_USBHSREGEN_Pos (27U) +#define PWR_CSR2_USBHSREGEN_Msk (0x1UL << PWR_CSR2_USBHSREGEN_Pos) /*!< 0x08000000 */ +#define PWR_CSR2_USBHSREGEN PWR_CSR2_USBHSREGEN_Msk /*!< USB HS regulator enable */ + +/******************** Bit definition for PWR_CSR3 register ********************/ +#define PWR_CSR3_PDDS_Pos (0U) +#define PWR_CSR3_PDDS_Msk (0x1UL << PWR_CSR3_PDDS_Pos) /*!< 0x00000001 */ +#define PWR_CSR3_PDDS PWR_CSR3_PDDS_Msk /*!< D1 domain Power Down Deepsleep */ + +#define PWR_CSR3_CSSF_Pos (1U) +#define PWR_CSR3_CSSF_Msk (0x1UL << PWR_CSR3_CSSF_Pos) /*!< 0x00000002 */ +#define PWR_CSR3_CSSF PWR_CSR3_CSSF_Msk /*!< Clear Standby and Stop flag */ + +#define PWR_CSR3_STOPF_Pos (8U) +#define PWR_CSR3_STOPF_Msk (0x1UL << PWR_CSR3_STOPF_Pos) /*!< 0x00000080 */ +#define PWR_CSR3_STOPF PWR_CSR3_STOPF_Msk /*!< STOP Flag */ + +#define PWR_CSR3_SBF_Pos (9U) +#define PWR_CSR3_SBF_Msk (0x1UL << PWR_CSR3_SBF_Pos) /*!< 0x00000100 */ +#define PWR_CSR3_SBF PWR_CSR3_SBF_Msk /*!< System STANDBY Flag */ + +/******************** Bit definition for PWR_CSR4 register ********************/ +#define PWR_CSR4_VOS_Pos (0U) +#define PWR_CSR4_VOS_Msk (0x1UL << PWR_CSR4_VOS_Pos) /*!< 0x00000001 */ +#define PWR_CSR4_VOS PWR_CSR4_VOS_Msk /*!< Voltage Scaling selection according performance */ + +#define PWR_CSR4_VOSRDY_Pos (1U) +#define PWR_CSR4_VOSRDY_Msk (0x1UL << PWR_CSR4_VOSRDY_Pos) /*!< 0x00000002 */ +#define PWR_CSR4_VOSRDY PWR_CSR4_VOSRDY_Msk /*!< VOSRDY: VOS Ready bit for VCORE voltage scaling output selection. */ + +/******************** Bit definition for PWR_WKUPCR register ********************/ +#define PWR_WKUPCR_WKUPC_Pos (0U) +#define PWR_WKUPCR_WKUPC_Msk (0xFUL << PWR_WKUPCR_WKUPC_Pos) /*!< 0x0000000F */ +#define PWR_WKUPCR_WKUPC PWR_WKUPCR_WKUPC_Msk /*!< Clear Wakeup Pin Flag 1 to 4 */ +#define PWR_WKUPCR_WKUPC1_Pos (0U) +#define PWR_WKUPCR_WKUPC1_Msk (0x1UL << PWR_WKUPCR_WKUPC1_Pos) /*!< 0x00000001 */ +#define PWR_WKUPCR_WKUPC1 PWR_WKUPCR_WKUPC1_Msk /*!< Clear Wakeup Pin Flag 1 */ +#define PWR_WKUPCR_WKUPC2_Pos (1U) +#define PWR_WKUPCR_WKUPC2_Msk (0x1UL << PWR_WKUPCR_WKUPC2_Pos) /*!< 0x00000002 */ +#define PWR_WKUPCR_WKUPC2 PWR_WKUPCR_WKUPC2_Msk /*!< Clear Wakeup Pin Flag 2 */ +#define PWR_WKUPCR_WKUPC3_Pos (2U) +#define PWR_WKUPCR_WKUPC3_Msk (0x1UL << PWR_WKUPCR_WKUPC3_Pos) /*!< 0x00000004 */ +#define PWR_WKUPCR_WKUPC3 PWR_WKUPCR_WKUPC3_Msk /*!< Clear Wakeup Pin Flag 3 */ +#define PWR_WKUPCR_WKUPC4_Pos (3U) +#define PWR_WKUPCR_WKUPC4_Msk (0x1UL << PWR_WKUPCR_WKUPC4_Pos) /*!< 0x00000008 */ +#define PWR_WKUPCR_WKUPC4 PWR_WKUPCR_WKUPC4_Msk /*!< Clear Wakeup Pin Flag 4 */ + +/******************** Bit definition for PWR_WKUPFR register ********************/ +#define PWR_WKUPFR_WKUPF1_Pos (0U) +#define PWR_WKUPFR_WKUPF1_Msk (0x1UL << PWR_WKUPFR_WKUPF1_Pos) /*!< 0x00000001 */ +#define PWR_WKUPFR_WKUPF1 PWR_WKUPFR_WKUPF1_Msk /*!< Wakeup Pin Flag 1 */ +#define PWR_WKUPFR_WKUPF2_Pos (1U) +#define PWR_WKUPFR_WKUPF2_Msk (0x1UL << PWR_WKUPFR_WKUPF2_Pos) /*!< 0x00000002 */ +#define PWR_WKUPFR_WKUPF2 PWR_WKUPFR_WKUPF2_Msk /*!< Wakeup Pin Flag 2 */ +#define PWR_WKUPFR_WKUPF3_Pos (2U) +#define PWR_WKUPFR_WKUPF3_Msk (0x1UL << PWR_WKUPFR_WKUPF3_Pos) /*!< 0x00000004 */ +#define PWR_WKUPFR_WKUPF3 PWR_WKUPFR_WKUPF3_Msk /*!< Wakeup Pin Flag 3 */ +#define PWR_WKUPFR_WKUPF4_Pos (3U) +#define PWR_WKUPFR_WKUPF4_Msk (0x1UL << PWR_WKUPFR_WKUPF4_Pos) /*!< 0x00000008 */ +#define PWR_WKUPFR_WKUPF4 PWR_WKUPFR_WKUPF4_Msk /*!< Wakeup Pin Flag 4 */ + +/******************** Bit definition for PWR_WKUPEPR register ********************/ +#define PWR_WKUPEPR_WKUPEN_Pos (0U) +#define PWR_WKUPEPR_WKUPEN_Msk (0x0FUL << PWR_WKUPEPR_WKUPEN_Pos) /*!< 0x0000000F */ +#define PWR_WKUPEPR_WKUPEN PWR_WKUPEPR_WKUPEN_Msk /*!< Enable all Wakeup Pin */ +#define PWR_WKUPEPR_WKUPEN1_Pos (0U) +#define PWR_WKUPEPR_WKUPEN1_Msk (0x1UL << PWR_WKUPEPR_WKUPEN1_Pos) /*!< 0x00000001 */ +#define PWR_WKUPEPR_WKUPEN1 PWR_WKUPEPR_WKUPEN1_Msk /*!< Enable Wakeup Pin WKUP1 */ +#define PWR_WKUPEPR_WKUPEN2_Pos (1U) +#define PWR_WKUPEPR_WKUPEN2_Msk (0x1UL << PWR_WKUPEPR_WKUPEN2_Pos) /*!< 0x00000002 */ +#define PWR_WKUPEPR_WKUPEN2 PWR_WKUPEPR_WKUPEN2_Msk /*!< Enable Wakeup Pin WKUP2 */ +#define PWR_WKUPEPR_WKUPEN3_Pos (2U) +#define PWR_WKUPEPR_WKUPEN3_Msk (0x1UL << PWR_WKUPEPR_WKUPEN3_Pos) /*!< 0x00000004 */ +#define PWR_WKUPEPR_WKUPEN3 PWR_WKUPEPR_WKUPEN3_Msk /*!< Enable Wakeup Pin WKUP3 */ +#define PWR_WKUPEPR_WKUPEN4_Pos (3U) +#define PWR_WKUPEPR_WKUPEN4_Msk (0x1UL << PWR_WKUPEPR_WKUPEN4_Pos) /*!< 0x00000008 */ +#define PWR_WKUPEPR_WKUPEN4 PWR_WKUPEPR_WKUPEN4_Msk /*!< Enable Wakeup Pin WKUP4 */ + +#define PWR_WKUPEPR_WKUPP_Pos (8U) +#define PWR_WKUPEPR_WKUPP_Msk (0x0FUL << PWR_WKUPEPR_WKUPP_Pos) /*!< 0x0000F00 */ +#define PWR_WKUPEPR_WKUPP PWR_WKUPEPR_WKUPP_Msk /*!< Wakeup Pin Polarity for WKUP1 to WKUP4 */ +#define PWR_WKUPEPR_WKUPP1_Pos (8U) +#define PWR_WKUPEPR_WKUPP1_Msk (0x1UL << PWR_WKUPEPR_WKUPP1_Pos) /*!< 0x00000100 */ +#define PWR_WKUPEPR_WKUPP1 PWR_WKUPEPR_WKUPP1_Msk /*!< Wakeup Pin Polarity for WKUP1 */ +#define PWR_WKUPEPR_WKUPP2_Pos (9U) +#define PWR_WKUPEPR_WKUPP2_Msk (0x1UL << PWR_WKUPEPR_WKUPP2_Pos) /*!< 0x00000200 */ +#define PWR_WKUPEPR_WKUPP2 PWR_WKUPEPR_WKUPP2_Msk /*!< Wakeup Pin Polarity for WKUP2 */ +#define PWR_WKUPEPR_WKUPP3_Pos (10U) +#define PWR_WKUPEPR_WKUPP3_Msk (0x1UL << PWR_WKUPEPR_WKUPP3_Pos) /*!< 0x00000400 */ +#define PWR_WKUPEPR_WKUPP3 PWR_WKUPEPR_WKUPP3_Msk /*!< Wakeup Pin Polarity for WKUP3 */ +#define PWR_WKUPEPR_WKUPP4_Pos (11U) +#define PWR_WKUPEPR_WKUPP4_Msk (0x1UL << PWR_WKUPEPR_WKUPP4_Pos) /*!< 0x00000800 */ +#define PWR_WKUPEPR_WKUPP4 PWR_WKUPEPR_WKUPP4_Msk /*!< Wakeup Pin Polarity for WKUP4 */ + +#define PWR_WKUPEPR_WKUPPUPD1_Pos (16U) +#define PWR_WKUPEPR_WKUPPUPD1_Msk (0x3UL << PWR_WKUPEPR_WKUPPUPD1_Pos) /*!< 0x00030000 */ +#define PWR_WKUPEPR_WKUPPUPD1 PWR_WKUPEPR_WKUPPUPD1_Msk /*!< Wakeup Pin pull configuration for WKUP1 */ +#define PWR_WKUPEPR_WKUPPUPD1_0 (0x1UL << PWR_WKUPEPR_WKUPPUPD1_Pos) /*!< 0x00010000 */ +#define PWR_WKUPEPR_WKUPPUPD1_1 (0x2UL << PWR_WKUPEPR_WKUPPUPD1_Pos) /*!< 0x00020000 */ +#define PWR_WKUPEPR_WKUPPUPD2_Pos (18U) +#define PWR_WKUPEPR_WKUPPUPD2_Msk (0x3UL << PWR_WKUPEPR_WKUPPUPD2_Pos) /*!< 0x000C0000 */ +#define PWR_WKUPEPR_WKUPPUPD2 PWR_WKUPEPR_WKUPPUPD2_Msk /*!< Wakeup Pin pull configuration for WKUP2 */ +#define PWR_WKUPEPR_WKUPPUPD2_0 (0x1UL << PWR_WKUPEPR_WKUPPUPD2_Pos) /*!< 0x00040000 */ +#define PWR_WKUPEPR_WKUPPUPD2_1 (0x2UL << PWR_WKUPEPR_WKUPPUPD2_Pos) /*!< 0x00080000 */ +#define PWR_WKUPEPR_WKUPPUPD3_Pos (20U) +#define PWR_WKUPEPR_WKUPPUPD3_Msk (0x3UL << PWR_WKUPEPR_WKUPPUPD3_Pos) /*!< 0x00300000 */ +#define PWR_WKUPEPR_WKUPPUPD3 PWR_WKUPEPR_WKUPPUPD3_Msk /*!< Wakeup Pin pull configuration for WKUP3 */ +#define PWR_WKUPEPR_WKUPPUPD3_0 (0x1UL << PWR_WKUPEPR_WKUPPUPD3_Pos) /*!< 0x00100000 */ +#define PWR_WKUPEPR_WKUPPUPD3_1 (0x2UL << PWR_WKUPEPR_WKUPPUPD3_Pos) /*!< 0x00200000 */ +#define PWR_WKUPEPR_WKUPPUPD4_Pos (22U) +#define PWR_WKUPEPR_WKUPPUPD4_Msk (0x3UL << PWR_WKUPEPR_WKUPPUPD4_Pos) /*!< 0x00C00000 */ +#define PWR_WKUPEPR_WKUPPUPD4 PWR_WKUPEPR_WKUPPUPD4_Msk /*!< Wakeup Pin pull configuration for WKUP4 */ +#define PWR_WKUPEPR_WKUPPUPD4_0 (0x1UL << PWR_WKUPEPR_WKUPPUPD4_Pos) /*!< 0x00400000 */ +#define PWR_WKUPEPR_WKUPPUPD4_1 (0x2UL << PWR_WKUPEPR_WKUPPUPD4_Pos) /*!< 0x00800000 */ + +/******************** Bit definition for PWR_UCPDRR register ********************/ +#define PWR_UCPDR_UCPD_DBDIS_Pos (0U) +#define PWR_UCPDR_UCPD_DBDIS_Msk (0x1UL << PWR_UCPDR_UCPD_DBDIS_Pos) /*!< 0x00000001 */ +#define PWR_UCPDR_UCPD_DBDIS PWR_UCPDR_UCPD_DBDIS_Msk /*!< UCPD dead battery disable */ + +#define PWR_UCPDR_UCPD_STBY_Pos (1U) +#define PWR_UCPDR_UCPD_STBY_Msk (0x1UL << PWR_UCPDR_UCPD_STBY_Pos) /*!< 0x00000002 */ +#define PWR_UCPDR_UCPD_STBY PWR_UCPDR_UCPD_STBY_Msk /*!< UCPD Standby mode */ + +/******************** Bit definition for PWR_APCR register ********************/ +#define PWR_APCR_APC_Pos (0U) +#define PWR_APCR_APC_Msk (0x1UL << PWR_APCR_APC_Pos) /*!< 0x00000001 */ +#define PWR_APCR_APC PWR_APCR_APC_Msk /*!< Apply pull configuration register */ + +#define PWR_APCR_PN7_PUPD_Pos (16U) +#define PWR_APCR_PN7_PUPD_Msk (0x1UL << PWR_APCR_PN7_PUPD_Pos) /*!< 0x00010000 */ +#define PWR_APCR_PN7_PUPD PWR_APCR_PN7_PUPD_Msk /*!< Port N bit 7 pull-up/down configuration */ + +#define PWR_APCR_PO5_PUPD_Pos (17) +#define PWR_APCR_PO5_PUPD_Msk (0x1UL << PWR_APCR_PO5_PUPD_Pos) /*!< 0x00020000 */ +#define PWR_APCR_PO5_PUPD PWR_APCR_PO5_PUPD_Msk /*!< Port O bit 5 pull-up/down configuration */ + +#define PWR_APCR_I3CPB6_PU_Pos (28U) +#define PWR_APCR_I3CPB6_PU_Msk (0x1UL << PWR_APCR_I3CPB6_PU_Pos) /*!< 0x10000000 */ +#define PWR_APCR_I3CPB6_PU PWR_APCR_I3CPB6_PU_Msk /*!< Port PB6 I3C pull-up bit configuration */ + +#define PWR_APCR_I3CPB7_PU_Pos (29U) +#define PWR_APCR_I3CPB7_PU_Msk (0x1UL << PWR_APCR_I3CPB7_PU_Pos) /*!< 0x20000000 */ +#define PWR_APCR_I3CPB7_PU PWR_APCR_I3CPB7_PU_Msk /*!< Port PB7 I3C pull-up bit configuration */ + +#define PWR_APCR_I3CPB8_PU_Pos (30U) +#define PWR_APCR_I3CPB8_PU_Msk (0x1UL << PWR_APCR_I3CPB8_PU_Pos) /*!< 0x40000000 */ +#define PWR_APCR_I3CPB8_PU PWR_APCR_I3CPB8_PU_Msk /*!< Port PB8 I3C pull-up bit configuration */ + +#define PWR_APCR_I3CPB9_PU_Pos (31U) +#define PWR_APCR_I3CPB9_PU_Msk (0x1UL << PWR_APCR_I3CPB9_PU_Pos) /*!< 0x80000000 */ +#define PWR_APCR_I3CPB9_PU PWR_APCR_I3CPB9_PU_Msk /*!< Port PB9 I3C pull-up bit configuration */ + +/******************** Bit definition for PWR_PUCRN register ********************/ +#define PWR_PUCRN_PUN1_Pos (1U) +#define PWR_PUCRN_PUN1_Msk (0x1UL << PWR_PUCRN_PUN1_Pos) /*!< 0x00000002 */ +#define PWR_PUCRN_PUN1 PWR_PUCRN_PUN1_Msk /*!< PUN1: Port N pull-up */ + +#define PWR_PUCRN_PUN6_Pos (6U) +#define PWR_PUCRN_PUN6_Msk (0x1UL << PWR_PUCRN_PUN6_Pos) /*!< 0x00000040 */ +#define PWR_PUCRN_PUN6 PWR_PUCRN_PUN6_Msk /*!< PUN6: Port N pull-up */ + +#define PWR_PUCRN_PUN12_Pos (12U) +#define PWR_PUCRN_PUN12_Msk (0x1UL << PWR_PUCRN_PUN12_Pos) /*!< 0x00001000 */ +#define PWR_PUCRN_PUN12 PWR_PUCRN_PUN12_Msk /*!< PUN12: Port N pull-up */ + +/******************** Bit definition for PWR_PDCRN register ********************/ +#define PWR_PDCRN_PDN0_Pos (0U) +#define PWR_PDCRN_PDN0_Msk (0x1UL << PWR_PDCRN_PDN0_Pos) /*!< 0x00000001 */ +#define PWR_PDCRN_PDN0 PWR_PDCRN_PDN0_Msk /*!< PDN0: Port N pull-down */ + +#define PWR_PDCRN_PDN1_Pos (1U) +#define PWR_PDCRN_PDN1_Msk (0x1UL << PWR_PDCRN_PDN1_Pos) /*!< 0x00000002 */ +#define PWR_PDCRN_PDN1 PWR_PDCRN_PDN1_Msk /*!< PDN1: Port N pull-down */ + +#define PWR_PDCRN_PDN2N5_Pos (2U) +#define PWR_PDCRN_PDN2N5_Msk (0x1UL << PWR_PDCRN_PDN2N5_Pos) /*!< 0x00000004 */ +#define PWR_PDCRN_PDN2N5 PWR_PDCRN_PDN2N5_Msk /*!< PDN2 to PDN5: Port N pull-down */ + +#define PWR_PDCRN_PDN6_Pos (6U) +#define PWR_PDCRN_PDN6_Msk (0x1UL << PWR_PDCRN_PDN6_Pos) /*!< 0x00000040 */ +#define PWR_PDCRN_PDN6 PWR_PDCRN_PDN6_Msk /*!< PDN6: Port N pull-down */ + +#define PWR_PDCRN_PDN8N11_Pos (8U) +#define PWR_PDCRN_PDN8N11_Msk (0x1UL << PWR_PDCRN_PDN8N11_Pos) /*!< 0x00000100 */ +#define PWR_PDCRN_PDN8N11 PWR_PDCRN_PDN8N11_Msk /*!< PDN8 to PDN11: Port N pull-down */ + +#define PWR_PDCRN_PDN12_Pos (12U) +#define PWR_PDCRN_PDN12_Msk (0x1UL << PWR_PDCRN_PDN12_Pos) /*!< 0x00001000 */ +#define PWR_PDCRN_PDN12 PWR_PDCRN_PDN12_Msk /*!< PDN12: Port N pull-down */ + +/******************** Bit definition for PWR_PUCRO register ********************/ +#define PWR_PUCRO_PUO0_Pos (0U) +#define PWR_PUCRO_PUO0_Msk (0x1UL << PWR_PUCRO_PUO0_Pos) /*!< 0x00000001 */ +#define PWR_PUCRO_PUO0 PWR_PUCRO_PUO0_Msk /*!< PUO0: Port O pull-up */ + +#define PWR_PUCRO_PUO1_Pos (1U) +#define PWR_PUCRO_PUO1_Msk (0x1UL << PWR_PUCRO_PUO1_Pos) /*!< 0x00000002 */ +#define PWR_PUCRO_PUO1 PWR_PUCRO_PUO1_Msk /*!< PUO1: Port O pull-up */ + +#define PWR_PUCRO_PUO4_Pos (4U) +#define PWR_PUCRO_PUO4_Msk (0x1UL << PWR_PUCRO_PUO4_Pos) /*!< 0x00000010 */ +#define PWR_PUCRO_PUO4 PWR_PUCRO_PUO4_Msk /*!< PUO4: Port O pull-up */ + +/******************** Bit definition for PWR_PDCRO register ********************/ +#define PWR_PDCRO_PDO0_Pos (0U) +#define PWR_PDCRO_PDO0_Msk (0x1UL << PWR_PDCRO_PDO0_Pos) /*!< 0x00000001 */ +#define PWR_PDCRO_PDO0 PWR_PDCRO_PDO0_Msk /*!< PDO0: Port O pull-down */ + +#define PWR_PDCRO_PDO1_Pos (1U) +#define PWR_PDCRO_PDO1_Msk (0x1UL << PWR_PDCRO_PDO1_Pos) /*!< 0x00000002 */ +#define PWR_PDCRO_PDO1 PWR_PDCRO_PDO1_Msk /*!< PDO1: Port O pull-down */ + +#define PWR_PDCRO_PDO2_Pos (2U) +#define PWR_PDCRO_PDO2_Msk (0x1UL << PWR_PDCRO_PDO2_Pos) /*!< 0x00000004 */ +#define PWR_PDCRO_PDO2 PWR_PDCRO_PDO2_Msk /*!< PDO2: Port O pull-down */ + +#define PWR_PDCRO_PDO3_Pos (3U) +#define PWR_PDCRO_PDO3_Msk (0x1UL << PWR_PDCRO_PDO3_Pos) /*!< 0x00000008 */ +#define PWR_PDCRO_PDO3 PWR_PDCRO_PDO3_Msk /*!< PDO3: Port O pull-down */ + +#define PWR_PDCRO_PDO4_Pos (4U) +#define PWR_PDCRO_PDO4_Msk (0x1UL << PWR_PDCRO_PDO4_Pos) /*!< 0x00000010 */ +#define PWR_PDCRO_PDO4 PWR_PDCRO_PDO4_Msk /*!< PDO4: Port O pull-down */ + +/******************** Bit definition for PWR_PDCRP register ********************/ +#define PWR_PDCRP_PDP0P3_Pos (0U) +#define PWR_PDCRP_PDP0P3_Msk (0x1UL << PWR_PDCRP_PDP0P3_Pos) /*!< 0x00000001 */ +#define PWR_PDCRP_PDP0P3 PWR_PDCRP_PDP0P3_Msk /*!< PPO0 to PP03 : Port P pull-down */ + +#define PWR_PDCRP_PDP4P7_Pos (4U) +#define PWR_PDCRP_PDP4P7_Msk (0x1UL << PWR_PDCRP_PDP4P7_Pos) /*!< 0x00000010 */ +#define PWR_PDCRP_PDP4P7 PWR_PDCRP_PDP4P7_Msk /*!< PPO4 to PP07 : Port P pull-down */ + +#define PWR_PDCRP_PDP8P11_Pos (8U) +#define PWR_PDCRP_PDP8P11_Msk (0x1UL << PWR_PDCRP_PDP8P11_Pos) /*!< 0x00000100 */ +#define PWR_PDCRP_PDP8P11 PWR_PDCRP_PDP8P11_Msk /*!< PPO8 to PP11 : Port P pull-down */ + +#define PWR_PDCRP_PDP12P15_Pos (12U) +#define PWR_PDCRP_PDP12P15_Msk (0x1UL << PWR_PDCRP_PDP12P15_Pos) /*!< 0x00001000 */ +#define PWR_PDCRP_PDP12P15 PWR_PDCRP_PDP12P15_Msk /*!< PP12 to PP15 : Port P pull-down */ + + +/******************************************************************************/ +/* */ +/* RAM ECC monitoring */ +/* */ +/******************************************************************************/ +/****************** Bit definition for RAMECC_IER register ******************/ +#define RAMECC_IER_GIE_Pos (0U) +#define RAMECC_IER_GIE_Msk (0x1UL << RAMECC_IER_GIE_Pos) /*!< 0x00000001 */ +#define RAMECC_IER_GIE RAMECC_IER_GIE_Msk /*!< Global interrupt enable */ +#define RAMECC_IER_GECCSEIE_Pos (1U) +#define RAMECC_IER_GECCSEIE_Msk (0x1UL << RAMECC_IER_GECCSEIE_Pos) /*!< 0x00000002 */ +#define RAMECC_IER_GECCSEIE RAMECC_IER_GECCSEIE_Msk /*!< Global ECC single error interrupt enable */ +#define RAMECC_IER_GECCDEIE_Pos (2U) +#define RAMECC_IER_GECCDEIE_Msk (0x1UL << RAMECC_IER_GECCDEIE_Pos) /*!< 0x00000004 */ +#define RAMECC_IER_GECCDEIE RAMECC_IER_GECCDEIE_Msk /*!< Global ECC double error interrupt enable */ +#define RAMECC_IER_GECCDEBWIE_Pos (3U) +#define RAMECC_IER_GECCDEBWIE_Msk (0x1UL << RAMECC_IER_GECCDEBWIE_Pos) /*!< 0x00000008 */ +#define RAMECC_IER_GECCDEBWIE RAMECC_IER_GECCDEBWIE_Msk /*!< Global ECC double error on byte write (BW) interrupt enable */ + +/******************* Bit definition for RAMECC_CR register ******************/ +#define RAMECC_CR_ECCSEIE_Pos (2U) +#define RAMECC_CR_ECCSEIE_Msk (0x1UL << RAMECC_CR_ECCSEIE_Pos) /*!< 0x00000004 */ +#define RAMECC_CR_ECCSEIE RAMECC_CR_ECCSEIE_Msk /*!< ECC single error interrupt enable */ +#define RAMECC_CR_ECCDEIE_Pos (3U) +#define RAMECC_CR_ECCDEIE_Msk (0x1UL << RAMECC_CR_ECCDEIE_Pos) /*!< 0x00000008 */ +#define RAMECC_CR_ECCDEIE RAMECC_CR_ECCDEIE_Msk /*!< ECC double error interrupt enable */ +#define RAMECC_CR_ECCDEBWIE_Pos (4U) +#define RAMECC_CR_ECCDEBWIE_Msk (0x1UL << RAMECC_CR_ECCDEBWIE_Pos) /*!< 0x00000010 */ +#define RAMECC_CR_ECCDEBWIE RAMECC_CR_ECCDEBWIE_Msk /*!< ECC double error on byte write (BW) interrupt enable */ +#define RAMECC_CR_ECCELEN_Pos (5U) +#define RAMECC_CR_ECCELEN_Msk (0x1UL << RAMECC_CR_ECCELEN_Pos) /*!< 0x00000020 */ +#define RAMECC_CR_ECCELEN RAMECC_CR_ECCELEN_Msk /*!< ECC error latching enable */ + +/******************* Bit definition for RAMECC_SR register ******************/ +#define RAMECC_SR_SEDCF_Pos (0U) +#define RAMECC_SR_SEDCF_Msk (0x1UL << RAMECC_SR_SEDCF_Pos) /*!< 0x00000001 */ +#define RAMECC_SR_SEDCF RAMECC_SR_SEDCF_Msk /*!< ECC single error detected and corrected flag */ +#define RAMECC_SR_DEDF_Pos (1U) +#define RAMECC_SR_DEDF_Msk (0x1UL << RAMECC_SR_DEDF_Pos) /*!< 0x00000002 */ +#define RAMECC_SR_DEDF RAMECC_SR_DEDF_Msk /*!< ECC double error detected flag */ +#define RAMECC_SR_DEBWDF_Pos (2U) +#define RAMECC_SR_DEBWDF_Msk (0x1UL << RAMECC_SR_DEBWDF_Pos) /*!< 0x00000004 */ +#define RAMECC_SR_DEBWDF RAMECC_SR_DEBWDF_Msk /*!< ECC double error on byte write (BW) detected flag */ + +/****************** Bit definition for RAMECC_FAR register ******************/ +#define RAMECC_FAR_FADD_Pos (0U) +#define RAMECC_FAR_FADD_Msk (0xFFFFFFFFUL << RAMECC_FAR_FADD_Pos) /*!< 0xFFFFFFFF */ +#define RAMECC_FAR_FADD RAMECC_FAR_FADD_Msk /*!< ECC error failing address */ + +/****************** Bit definition for RAMECC_FDRL register *****************/ +#define RAMECC_FDRL_FDATAL_Pos (0U) +#define RAMECC_FDRL_FDATAL_Msk (0xFFFFFFFFUL << RAMECC_FDRL_FDATAL_Pos) /*!< 0xFFFFFFFF */ +#define RAMECC_FDRL_FDATAL RAMECC_FDRL_FDATAL_Msk /*!< Failing data low */ + +/****************** Bit definition for RAMECC_FDRH register *****************/ +#define RAMECC_FDRH_FDATAH_Pos (0U) +#define RAMECC_FDRH_FDATAH_Msk (0xFFFFFFFFUL << RAMECC_FDRH_FDATAH_Pos) /*!< 0xFFFFFFFF */ +#define RAMECC_FDRH_FDATAH RAMECC_FDRH_FDATAH_Msk /* Failing data high (64-bit memory) */ + +/***************** Bit definition for RAMECC_FECR register ******************/ +#define RAMECC_FECR_FEC_Pos (0U) +#define RAMECC_FECR_FEC_Msk (0xFFFFFFFFUL << RAMECC_FECR_FEC_Pos) /*!< 0xFFFFFFFF */ +#define RAMECC_FECR_FEC RAMECC_FECR_FEC_Msk /*!< Failing error code */ + + +/******************************************************************************/ +/* */ +/* Reset and Clock Control */ +/* */ +/******************************************************************************/ +/******************** Bit definition for RCC_CR register ********************/ +#define RCC_CR_HSION_Pos (0U) +#define RCC_CR_HSION_Msk (0x1UL << RCC_CR_HSION_Pos) /*!< 0x00000001 */ +#define RCC_CR_HSION RCC_CR_HSION_Msk /*!< Internal High Speed clock enable */ +#define RCC_CR_HSIKERON_Pos (1U) +#define RCC_CR_HSIKERON_Msk (0x1UL << RCC_CR_HSIKERON_Pos) /*!< 0x00000002 */ +#define RCC_CR_HSIKERON RCC_CR_HSIKERON_Msk /*!< Internal High Speed clock enable in Stop mode */ +#define RCC_CR_HSIRDY_Pos (2U) +#define RCC_CR_HSIRDY_Msk (0x1UL << RCC_CR_HSIRDY_Pos) /*!< 0x00000004 */ +#define RCC_CR_HSIRDY RCC_CR_HSIRDY_Msk /*!< Internal High Speed clock ready flag */ +#define RCC_CR_HSIDIV_Pos (3U) +#define RCC_CR_HSIDIV_Msk (0x3UL << RCC_CR_HSIDIV_Pos) /*!< 0x00000018 */ +#define RCC_CR_HSIDIV RCC_CR_HSIDIV_Msk /*!< Internal High Speed clock divider selection */ +#define RCC_CR_HSIDIV_0 (0x1UL << RCC_CR_HSIDIV_Pos) /*!< 0x00000008 */ +#define RCC_CR_HSIDIV_1 (0x2UL << RCC_CR_HSIDIV_Pos) /*!< 0x00000010 */ + +#define RCC_CR_HSIDIVF_Pos (5U) +#define RCC_CR_HSIDIVF_Msk (0x1UL << RCC_CR_HSIDIVF_Pos) /*!< 0x00000020 */ +#define RCC_CR_HSIDIVF RCC_CR_HSIDIVF_Msk /*!< HSI Divider flag */ +#define RCC_CR_CSION_Pos (7U) +#define RCC_CR_CSION_Msk (0x1UL << RCC_CR_CSION_Pos) /*!< 0x00000080 */ +#define RCC_CR_CSION RCC_CR_CSION_Msk /*!< The Internal RC 4MHz oscillator clock enable */ +#define RCC_CR_CSIRDY_Pos (8U) +#define RCC_CR_CSIRDY_Msk (0x1UL << RCC_CR_CSIRDY_Pos) /*!< 0x00000100 */ +#define RCC_CR_CSIRDY RCC_CR_CSIRDY_Msk /*!< The Internal RC 4MHz oscillator clock ready */ +#define RCC_CR_CSIKERON_Pos (9U) +#define RCC_CR_CSIKERON_Msk (0x1UL << RCC_CR_CSIKERON_Pos) /*!< 0x00000200 */ +#define RCC_CR_CSIKERON RCC_CR_CSIKERON_Msk /*!< Internal RC 4MHz oscillator clock enable in Stop mode */ +#define RCC_CR_HSI48ON_Pos (12U) +#define RCC_CR_HSI48ON_Msk (0x1UL << RCC_CR_HSI48ON_Pos) /*!< 0x00001000 */ +#define RCC_CR_HSI48ON RCC_CR_HSI48ON_Msk /*!< HSI48 clock enable clock enable */ +#define RCC_CR_HSI48RDY_Pos (13U) +#define RCC_CR_HSI48RDY_Msk (0x1UL << RCC_CR_HSI48RDY_Pos) /*!< 0x00002000 */ +#define RCC_CR_HSI48RDY RCC_CR_HSI48RDY_Msk /*!< HSI48 clock ready flag */ +#define RCC_CR_HSEON_Pos (16U) +#define RCC_CR_HSEON_Msk (0x1UL << RCC_CR_HSEON_Pos) /*!< 0x00010000 */ +#define RCC_CR_HSEON RCC_CR_HSEON_Msk /*!< External High Speed clock enable */ +#define RCC_CR_HSERDY_Pos (17U) +#define RCC_CR_HSERDY_Msk (0x1UL << RCC_CR_HSERDY_Pos) /*!< 0x00020000 */ +#define RCC_CR_HSERDY RCC_CR_HSERDY_Msk /*!< External High Speed clock ready flag */ +#define RCC_CR_HSEBYP_Pos (18U) +#define RCC_CR_HSEBYP_Msk (0x1UL << RCC_CR_HSEBYP_Pos) /*!< 0x00040000 */ +#define RCC_CR_HSEBYP RCC_CR_HSEBYP_Msk /*!< External High Speed clock bypass */ +#define RCC_CR_HSEEXT_Pos (19U) +#define RCC_CR_HSEEXT_Msk (0x1UL << RCC_CR_HSEEXT_Pos) /*!< 0x00100000 */ +#define RCC_CR_HSEEXT RCC_CR_HSEEXT_Msk /*!< External High Speed clock type in bypass mode */ +#define RCC_CR_HSECSSON_Pos (20U) +#define RCC_CR_HSECSSON_Msk (0x1UL << RCC_CR_HSECSSON_Pos) /*!< 0x00080000 */ +#define RCC_CR_HSECSSON RCC_CR_HSECSSON_Msk /*!< HSE Clock security System enable */ +#define RCC_CR_PLL1ON_Pos (24U) +#define RCC_CR_PLL1ON_Msk (0x1UL << RCC_CR_PLL1ON_Pos) /*!< 0x01000000 */ +#define RCC_CR_PLL1ON RCC_CR_PLL1ON_Msk /*!< System PLL1 clock enable */ +#define RCC_CR_PLL1RDY_Pos (25U) +#define RCC_CR_PLL1RDY_Msk (0x1UL << RCC_CR_PLL1RDY_Pos) /*!< 0x02000000 */ +#define RCC_CR_PLL1RDY RCC_CR_PLL1RDY_Msk /*!< System PLL1 clock ready flag */ +#define RCC_CR_PLL2ON_Pos (26U) +#define RCC_CR_PLL2ON_Msk (0x1UL << RCC_CR_PLL2ON_Pos) /*!< 0x04000000 */ +#define RCC_CR_PLL2ON RCC_CR_PLL2ON_Msk /*!< System PLL2 clock enable */ +#define RCC_CR_PLL2RDY_Pos (27U) +#define RCC_CR_PLL2RDY_Msk (0x1UL << RCC_CR_PLL2RDY_Pos) /*!< 0x08000000 */ +#define RCC_CR_PLL2RDY RCC_CR_PLL2RDY_Msk /*!< System PLL2 clock ready flag */ +#define RCC_CR_PLL3ON_Pos (28U) +#define RCC_CR_PLL3ON_Msk (0x1UL << RCC_CR_PLL3ON_Pos) /*!< 0x10000000 */ +#define RCC_CR_PLL3ON RCC_CR_PLL3ON_Msk /*!< System PLL3 clock enable */ +#define RCC_CR_PLL3RDY_Pos (29U) +#define RCC_CR_PLL3RDY_Msk (0x1UL << RCC_CR_PLL3RDY_Pos) /*!< 0x20000000 */ +#define RCC_CR_PLL3RDY RCC_CR_PLL3RDY_Msk /*!< System PLL3 clock ready flag */ + +/******************** Bit definition for RCC_HSICFGR register ***************/ +/*!< HSICAL configuration */ +#define RCC_HSICFGR_HSICAL_Pos (0U) +#define RCC_HSICFGR_HSICAL_Msk (0xFFFUL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000FFF */ +#define RCC_HSICFGR_HSICAL RCC_HSICFGR_HSICAL_Msk /*!< HSICAL[11:0] bits */ +#define RCC_HSICFGR_HSICAL_0 (0x001UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000001 */ +#define RCC_HSICFGR_HSICAL_1 (0x002UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000002 */ +#define RCC_HSICFGR_HSICAL_2 (0x004UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000004 */ +#define RCC_HSICFGR_HSICAL_3 (0x008UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000008 */ +#define RCC_HSICFGR_HSICAL_4 (0x010UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000010 */ +#define RCC_HSICFGR_HSICAL_5 (0x020UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000020 */ +#define RCC_HSICFGR_HSICAL_6 (0x040UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000040 */ +#define RCC_HSICFGR_HSICAL_7 (0x080UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000080 */ +#define RCC_HSICFGR_HSICAL_8 (0x100UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000100 */ +#define RCC_HSICFGR_HSICAL_9 (0x200UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000200 */ +#define RCC_HSICFGR_HSICAL_10 (0x400UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000400 */ +#define RCC_HSICFGR_HSICAL_11 (0x800UL << RCC_HSICFGR_HSICAL_Pos) /*!< 0x00000800 */ + +/*!< HSITRIM configuration */ +#define RCC_HSICFGR_HSITRIM_Pos (24U) +#define RCC_HSICFGR_HSITRIM_Msk (0x7FUL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x7F000000 */ +#define RCC_HSICFGR_HSITRIM RCC_HSICFGR_HSITRIM_Msk /*!< HSITRIM[6:0] bits */ +#define RCC_HSICFGR_HSITRIM_0 (0x01UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x01000000 */ +#define RCC_HSICFGR_HSITRIM_1 (0x02UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x02000000 */ +#define RCC_HSICFGR_HSITRIM_2 (0x04UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x04000000 */ +#define RCC_HSICFGR_HSITRIM_3 (0x08UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x08000000 */ +#define RCC_HSICFGR_HSITRIM_4 (0x10UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x10000000 */ +#define RCC_HSICFGR_HSITRIM_5 (0x20UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x20000000 */ +#define RCC_HSICFGR_HSITRIM_6 (0x40UL << RCC_HSICFGR_HSITRIM_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_CRRCR register *****************/ +/*!< HSI48CAL configuration */ +#define RCC_CRRCR_HSI48CAL_Pos (0U) +#define RCC_CRRCR_HSI48CAL_Msk (0x3FFUL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x000003FF */ +#define RCC_CRRCR_HSI48CAL RCC_CRRCR_HSI48CAL_Msk /*!< HSI48CAL[9:0] bits */ +#define RCC_CRRCR_HSI48CAL_0 (0x001UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000001 */ +#define RCC_CRRCR_HSI48CAL_1 (0x002UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000002 */ +#define RCC_CRRCR_HSI48CAL_2 (0x004UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000004 */ +#define RCC_CRRCR_HSI48CAL_3 (0x008UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000008 */ +#define RCC_CRRCR_HSI48CAL_4 (0x010UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000010 */ +#define RCC_CRRCR_HSI48CAL_5 (0x020UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000020 */ +#define RCC_CRRCR_HSI48CAL_6 (0x040UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000040 */ +#define RCC_CRRCR_HSI48CAL_7 (0x080UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000080 */ +#define RCC_CRRCR_HSI48CAL_8 (0x100UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000100 */ +#define RCC_CRRCR_HSI48CAL_9 (0x200UL << RCC_CRRCR_HSI48CAL_Pos) /*!< 0x00000200 */ + +/******************** Bit definition for RCC_CSICFGR register ***************/ +/*!< CSICAL configuration */ +#define RCC_CSICFGR_CSICAL_Pos (0U) +#define RCC_CSICFGR_CSICAL_Msk (0xFFUL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x000000FF */ +#define RCC_CSICFGR_CSICAL RCC_CSICFGR_CSICAL_Msk /*!< CSICAL[7:0] bits */ +#define RCC_CSICFGR_CSICAL_0 (0x01UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000001 */ +#define RCC_CSICFGR_CSICAL_1 (0x02UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000002 */ +#define RCC_CSICFGR_CSICAL_2 (0x04UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000004 */ +#define RCC_CSICFGR_CSICAL_3 (0x08UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000008 */ +#define RCC_CSICFGR_CSICAL_4 (0x10UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000010 */ +#define RCC_CSICFGR_CSICAL_5 (0x20UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000020 */ +#define RCC_CSICFGR_CSICAL_6 (0x40UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000040 */ +#define RCC_CSICFGR_CSICAL_7 (0x80UL << RCC_CSICFGR_CSICAL_Pos) /*!< 0x00000080 */ + +/*!< CSITRIM configuration */ +#define RCC_CSICFGR_CSITRIM_Pos (24U) +#define RCC_CSICFGR_CSITRIM_Msk (0x3FUL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x3F000000 */ +#define RCC_CSICFGR_CSITRIM RCC_CSICFGR_CSITRIM_Msk /*!< CSITRIM[5:0] bits */ +#define RCC_CSICFGR_CSITRIM_0 (0x01UL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x01000000 */ +#define RCC_CSICFGR_CSITRIM_1 (0x02UL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x02000000 */ +#define RCC_CSICFGR_CSITRIM_2 (0x04UL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x04000000 */ +#define RCC_CSICFGR_CSITRIM_3 (0x08UL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x08000000 */ +#define RCC_CSICFGR_CSITRIM_4 (0x10UL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x10000000 */ +#define RCC_CSICFGR_CSITRIM_5 (0x20UL << RCC_CSICFGR_CSITRIM_Pos) /*!< 0x20000000 */ + +/******************** Bit definition for RCC_CFGR register ******************/ +/*!< SW configuration */ +#define RCC_CFGR_SW_Pos (0U) +#define RCC_CFGR_SW_Msk (0x7UL << RCC_CFGR_SW_Pos) /*!< 0x00000007 */ +#define RCC_CFGR_SW RCC_CFGR_SW_Msk /*!< SW[2:0] bits (System clock switch) */ +#define RCC_CFGR_SW_0 (0x1UL << RCC_CFGR_SW_Pos) /*!< 0x00000001 */ +#define RCC_CFGR_SW_1 (0x2UL << RCC_CFGR_SW_Pos) /*!< 0x00000002 */ +#define RCC_CFGR_SW_2 (0x4UL << RCC_CFGR_SW_Pos) /*!< 0x00000004 */ + +/*!< SWS configuration */ +#define RCC_CFGR_SWS_Pos (3U) +#define RCC_CFGR_SWS_Msk (0x7UL << RCC_CFGR_SWS_Pos) /*!< 0x00000038 */ +#define RCC_CFGR_SWS RCC_CFGR_SWS_Msk /*!< SWS[2:0] bits (System clock switch status) */ +#define RCC_CFGR_SWS_0 (0x1UL << RCC_CFGR_SWS_Pos) /*!< 0x00000008 */ +#define RCC_CFGR_SWS_1 (0x2UL << RCC_CFGR_SWS_Pos) /*!< 0x00000010 */ +#define RCC_CFGR_SWS_2 (0x4UL << RCC_CFGR_SWS_Pos) /*!< 0x00000020 */ + +#define RCC_CFGR_STOPWUCK_Pos (6U) +#define RCC_CFGR_STOPWUCK_Msk (0x1UL << RCC_CFGR_STOPWUCK_Pos) /*!< 0x00000040 */ +#define RCC_CFGR_STOPWUCK RCC_CFGR_STOPWUCK_Msk /*!< Wake Up from stop and CSS backup clock selection */ +#define RCC_CFGR_STOPKERWUCK_Pos (7U) +#define RCC_CFGR_STOPKERWUCK_Msk (0x1UL << RCC_CFGR_STOPKERWUCK_Pos) /*!< 0x00000080 */ +#define RCC_CFGR_STOPKERWUCK RCC_CFGR_STOPKERWUCK_Msk /*!< Kernel Clock Selection after a Wake Up from Stop */ + +/*!< RTCPRE configuration */ +#define RCC_CFGR_RTCPRE_Pos (8U) +#define RCC_CFGR_RTCPRE_Msk (0x3FUL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00003F00 */ +#define RCC_CFGR_RTCPRE RCC_CFGR_RTCPRE_Msk /*!< RTCPRE[5:0] bits (HSE division factor for RTC clock) */ +#define RCC_CFGR_RTCPRE_0 (0x01UL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00000100 */ +#define RCC_CFGR_RTCPRE_1 (0x02UL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00000200 */ +#define RCC_CFGR_RTCPRE_2 (0x04UL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00000400 */ +#define RCC_CFGR_RTCPRE_3 (0x08UL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00000800 */ +#define RCC_CFGR_RTCPRE_4 (0x10UL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00001000 */ +#define RCC_CFGR_RTCPRE_5 (0x20UL << RCC_CFGR_RTCPRE_Pos) /*!< 0x00002000 */ + +#define RCC_CFGR_TIMPRE_Pos (15U) +#define RCC_CFGR_TIMPRE_Msk (0x1UL << RCC_CFGR_TIMPRE_Pos) /*!< 0x00008000 */ +#define RCC_CFGR_TIMPRE RCC_CFGR_TIMPRE_Msk /*!< TIMPRE configuration */ + +#define RCC_CFGR_MCO1PRE_Pos (18U) +#define RCC_CFGR_MCO1PRE_Msk (0xFUL << RCC_CFGR_MCO1PRE_Pos) /*!< 0x003C0000 */ +#define RCC_CFGR_MCO1PRE RCC_CFGR_MCO1PRE_Msk /*!< MCO1 configuration */ +#define RCC_CFGR_MCO1PRE_0 (0x1UL << RCC_CFGR_MCO1PRE_Pos) /*!< 0x00040000 */ +#define RCC_CFGR_MCO1PRE_1 (0x2UL << RCC_CFGR_MCO1PRE_Pos) /*!< 0x00080000 */ +#define RCC_CFGR_MCO1PRE_2 (0x4UL << RCC_CFGR_MCO1PRE_Pos) /*!< 0x00100000 */ +#define RCC_CFGR_MCO1PRE_3 (0x8UL << RCC_CFGR_MCO1PRE_Pos) /*!< 0x00200000 */ + +#define RCC_CFGR_MCO1SEL_Pos (22U) +#define RCC_CFGR_MCO1SEL_Msk (0x7UL << RCC_CFGR_MCO1SEL_Pos) /*!< 0x01C00000 */ +#define RCC_CFGR_MCO1SEL RCC_CFGR_MCO1SEL_Msk /*!< MCO1SEL [2:0] bits (MCO1 clock output selection) */ +#define RCC_CFGR_MCO1SEL_0 (0x1UL << RCC_CFGR_MCO1SEL_Pos) /*!< 0x00400000 */ +#define RCC_CFGR_MCO1SEL_1 (0x2UL << RCC_CFGR_MCO1SEL_Pos) /*!< 0x00800000 */ +#define RCC_CFGR_MCO1SEL_2 (0x4UL << RCC_CFGR_MCO1SEL_Pos) /*!< 0x01000000 */ + +#define RCC_CFGR_MCO2PRE_Pos (25U) +#define RCC_CFGR_MCO2PRE_Msk (0xFUL << RCC_CFGR_MCO2PRE_Pos) /*!< 0x1E000000 */ +#define RCC_CFGR_MCO2PRE RCC_CFGR_MCO2PRE_Msk /*!< MCO2 configuration */ +#define RCC_CFGR_MCO2PRE_0 (0x1UL << RCC_CFGR_MCO2PRE_Pos) /*!< 0x02000000 */ +#define RCC_CFGR_MCO2PRE_1 (0x2UL << RCC_CFGR_MCO2PRE_Pos) /*!< 0x04000000 */ +#define RCC_CFGR_MCO2PRE_2 (0x4UL << RCC_CFGR_MCO2PRE_Pos) /*!< 0x08000000 */ +#define RCC_CFGR_MCO2PRE_3 (0x8UL << RCC_CFGR_MCO2PRE_Pos) /*!< 0x10000000 */ + +#define RCC_CFGR_MCO2SEL_Pos (29U) +#define RCC_CFGR_MCO2SEL_Msk (0x7UL << RCC_CFGR_MCO2SEL_Pos) /*!< 0xE0000000 */ +#define RCC_CFGR_MCO2SEL RCC_CFGR_MCO2SEL_Msk /*!< MCO2SEL [2:0] bits (MCO2 clock output selection) */ +#define RCC_CFGR_MCO2SEL_0 (0x1UL << RCC_CFGR_MCO2SEL_Pos) /*!< 0x20000000 */ +#define RCC_CFGR_MCO2SEL_1 (0x2UL << RCC_CFGR_MCO2SEL_Pos) /*!< 0x40000000 */ +#define RCC_CFGR_MCO2SEL_2 (0x4UL << RCC_CFGR_MCO2SEL_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for RCC_CDCFGR register ****************/ +/*!< CPRE configuration */ +#define RCC_CDCFGR_CPRE_Pos (0U) +#define RCC_CDCFGR_CPRE_Msk (0xFUL << RCC_CDCFGR_CPRE_Pos) /*!< 0x0000000F */ +#define RCC_CDCFGR_CPRE RCC_CDCFGR_CPRE_Msk /*!< CPRE[3:0] bits */ +#define RCC_CDCFGR_CPRE_0 (0x1UL << RCC_CDCFGR_CPRE_Pos) /*!< 0x00000001 */ +#define RCC_CDCFGR_CPRE_1 (0x2UL << RCC_CDCFGR_CPRE_Pos) /*!< 0x00000002 */ +#define RCC_CDCFGR_CPRE_2 (0x4UL << RCC_CDCFGR_CPRE_Pos) /*!< 0x00000004 */ +#define RCC_CDCFGR_CPRE_3 (0x8UL << RCC_CDCFGR_CPRE_Pos) /*!< 0x00000008 */ + +/******************** Bit definition for RCC_BMCFGR register ****************/ +/*!< BMPRE configuration */ +#define RCC_BMCFGR_BMPRE_Pos (0U) +#define RCC_BMCFGR_BMPRE_Msk (0xFUL << RCC_BMCFGR_BMPRE_Pos) /*!< 0x0000000F */ +#define RCC_BMCFGR_BMPRE RCC_BMCFGR_BMPRE_Msk /*!< BMPRE[3:0] bits */ +#define RCC_BMCFGR_BMPRE_0 (0x1UL << RCC_BMCFGR_BMPRE_Pos) /*!< 0x00000001 */ +#define RCC_BMCFGR_BMPRE_1 (0x2UL << RCC_BMCFGR_BMPRE_Pos) /*!< 0x00000002 */ +#define RCC_BMCFGR_BMPRE_2 (0x4UL << RCC_BMCFGR_BMPRE_Pos) /*!< 0x00000004 */ +#define RCC_BMCFGR_BMPRE_3 (0x8UL << RCC_BMCFGR_BMPRE_Pos) /*!< 0x00000008 */ + +/******************** Bit definition for RCC_APBCFGR register ***************/ +/*!< APB1 prescaler configuration */ +#define RCC_APBCFGR_PPRE1_Pos (0U) +#define RCC_APBCFGR_PPRE1_Msk (0x7UL << RCC_APBCFGR_PPRE1_Pos) /*!< 0x00000007 */ +#define RCC_APBCFGR_PPRE1 RCC_APBCFGR_PPRE1_Msk /*!< PPRE1[2:0] bits */ +#define RCC_APBCFGR_PPRE1_0 (0x1UL << RCC_APBCFGR_PPRE1_Pos) /*!< 0x00000001 */ +#define RCC_APBCFGR_PPRE1_1 (0x2UL << RCC_APBCFGR_PPRE1_Pos) /*!< 0x00000002 */ +#define RCC_APBCFGR_PPRE1_2 (0x4UL << RCC_APBCFGR_PPRE1_Pos) /*!< 0x00000004 */ + +/*!< APB2 prescaler configuration */ +#define RCC_APBCFGR_PPRE2_Pos (4U) +#define RCC_APBCFGR_PPRE2_Msk (0x7UL << RCC_APBCFGR_PPRE2_Pos) /*!< 0x00000070 */ +#define RCC_APBCFGR_PPRE2 RCC_APBCFGR_PPRE2_Msk /*!< PPRE2[2:0] bits */ +#define RCC_APBCFGR_PPRE2_0 (0x1UL << RCC_APBCFGR_PPRE2_Pos) /*!< 0x00000010 */ +#define RCC_APBCFGR_PPRE2_1 (0x2UL << RCC_APBCFGR_PPRE2_Pos) /*!< 0x00000020 */ +#define RCC_APBCFGR_PPRE2_2 (0x4UL << RCC_APBCFGR_PPRE2_Pos) /*!< 0x00000040 */ + +/*!< APB4 prescaler configuration */ +#define RCC_APBCFGR_PPRE4_Pos (8U) +#define RCC_APBCFGR_PPRE4_Msk (0x7UL << RCC_APBCFGR_PPRE4_Pos) /*!< 0x00000700 */ +#define RCC_APBCFGR_PPRE4 RCC_APBCFGR_PPRE4_Msk /*!< PPRE4[2:0] bits */ +#define RCC_APBCFGR_PPRE4_0 (0x1UL << RCC_APBCFGR_PPRE4_Pos) /*!< 0x00000100 */ +#define RCC_APBCFGR_PPRE4_1 (0x2UL << RCC_APBCFGR_PPRE4_Pos) /*!< 0x00000200 */ +#define RCC_APBCFGR_PPRE4_2 (0x4UL << RCC_APBCFGR_PPRE4_Pos) /*!< 0x00000400 */ + +/*!< APB5 prescaler configuration */ +#define RCC_APBCFGR_PPRE5_Pos (12U) +#define RCC_APBCFGR_PPRE5_Msk (0x7UL << RCC_APBCFGR_PPRE5_Pos) /*!< 0x00007000 */ +#define RCC_APBCFGR_PPRE5 RCC_APBCFGR_PPRE5_Msk /*!< PPRE5[2:0] bits */ +#define RCC_APBCFGR_PPRE5_0 (0x1UL << RCC_APBCFGR_PPRE5_Pos) /*!< 0x00001000 */ +#define RCC_APBCFGR_PPRE5_1 (0x2UL << RCC_APBCFGR_PPRE5_Pos) /*!< 0x00002000 */ +#define RCC_APBCFGR_PPRE5_2 (0x4UL << RCC_APBCFGR_PPRE5_Pos) /*!< 0x00004000 */ + +/******************** Bit definition for RCC_PLLCKSELR register *************/ +#define RCC_PLLCKSELR_PLLSRC_Pos (0U) +#define RCC_PLLCKSELR_PLLSRC_Msk (0x3UL << RCC_PLLCKSELR_PLLSRC_Pos) /*!< 0x00000003 */ +#define RCC_PLLCKSELR_PLLSRC RCC_PLLCKSELR_PLLSRC_Msk /*!< DIVMx and PLLs clock source selection */ +#define RCC_PLLCKSELR_PLLSRC_0 (0x01UL << RCC_PLLCKSELR_PLLSRC_Pos) /*!< 0x00000010 */ +#define RCC_PLLCKSELR_PLLSRC_1 (0x02UL << RCC_PLLCKSELR_PLLSRC_Pos) /*!< 0x00000020 */ + +#define RCC_PLLCKSELR_DIVM1_Pos (4U) +#define RCC_PLLCKSELR_DIVM1_Msk (0x3FUL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x000003F0 */ +#define RCC_PLLCKSELR_DIVM1 RCC_PLLCKSELR_DIVM1_Msk /*!< DIVM1[5:0] bits */ +#define RCC_PLLCKSELR_DIVM1_0 (0x01UL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x00000010 */ +#define RCC_PLLCKSELR_DIVM1_1 (0x02UL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x00000020 */ +#define RCC_PLLCKSELR_DIVM1_2 (0x04UL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x00000040 */ +#define RCC_PLLCKSELR_DIVM1_3 (0x08UL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x00000080 */ +#define RCC_PLLCKSELR_DIVM1_4 (0x10UL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x00000100 */ +#define RCC_PLLCKSELR_DIVM1_5 (0x20UL << RCC_PLLCKSELR_DIVM1_Pos) /*!< 0x00000200 */ + +#define RCC_PLLCKSELR_DIVM2_Pos (12U) +#define RCC_PLLCKSELR_DIVM2_Msk (0x3FUL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x0003F000 */ +#define RCC_PLLCKSELR_DIVM2 RCC_PLLCKSELR_DIVM2_Msk /*!< DIVM2[5:0] bits */ +#define RCC_PLLCKSELR_DIVM2_0 (0x01UL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x00001000 */ +#define RCC_PLLCKSELR_DIVM2_1 (0x02UL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x00002000 */ +#define RCC_PLLCKSELR_DIVM2_2 (0x04UL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x00004000 */ +#define RCC_PLLCKSELR_DIVM2_3 (0x08UL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x00008000 */ +#define RCC_PLLCKSELR_DIVM2_4 (0x10UL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x00010000 */ +#define RCC_PLLCKSELR_DIVM2_5 (0x20UL << RCC_PLLCKSELR_DIVM2_Pos) /*!< 0x00020000 */ + +#define RCC_PLLCKSELR_DIVM3_Pos (20U) +#define RCC_PLLCKSELR_DIVM3_Msk (0x3FUL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x03F00000 */ +#define RCC_PLLCKSELR_DIVM3 RCC_PLLCKSELR_DIVM3_Msk /*!< DIVM3[5:0] bits */ +#define RCC_PLLCKSELR_DIVM3_0 (0x01UL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x00100000 */ +#define RCC_PLLCKSELR_DIVM3_1 (0x02UL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x00200000 */ +#define RCC_PLLCKSELR_DIVM3_2 (0x04UL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x00400000 */ +#define RCC_PLLCKSELR_DIVM3_3 (0x08UL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x00800000 */ +#define RCC_PLLCKSELR_DIVM3_4 (0x10UL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x01000000 */ +#define RCC_PLLCKSELR_DIVM3_5 (0x20UL << RCC_PLLCKSELR_DIVM3_Pos) /*!< 0x02000000 */ + +/******************** Bit definition for RCC_PLLCFGR register ***************/ +#define RCC_PLLCFGR_PLL1FRACEN_Pos (0U) +#define RCC_PLLCFGR_PLL1FRACEN_Msk (0x1UL << RCC_PLLCFGR_PLL1FRACEN_Pos) /*!< 0x00000001 */ +#define RCC_PLLCFGR_PLL1FRACEN RCC_PLLCFGR_PLL1FRACEN_Msk /*!< PLL1 fractional latch enable */ +#define RCC_PLLCFGR_PLL1VCOSEL_Pos (1U) +#define RCC_PLLCFGR_PLL1VCOSEL_Msk (0x1UL << RCC_PLLCFGR_PLL1VCOSEL_Pos) /*!< 0x00000002 */ +#define RCC_PLLCFGR_PLL1VCOSEL RCC_PLLCFGR_PLL1VCOSEL_Msk /*!< PLL1 VCO selection */ +#define RCC_PLLCFGR_PLL1SSCGEN_Pos (2U) +#define RCC_PLLCFGR_PLL1SSCGEN_Msk (0x1UL << RCC_PLLCFGR_PLL1SSCGEN_Pos) /*!< 0x00000004 */ +#define RCC_PLLCFGR_PLL1SSCGEN RCC_PLLCFGR_PLL1SSCGEN_Msk /*!< PLL1 Spread Spectrum Clock Generator enable */ +#define RCC_PLLCFGR_PLL1RGE_Pos (3U) +#define RCC_PLLCFGR_PLL1RGE_Msk (0x3UL << RCC_PLLCFGR_PLL1RGE_Pos) /*!< 0x00000018 */ +#define RCC_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_Msk /*!< PLL1RGE[1:0] bits: PLL1 input frequency range */ +#define RCC_PLLCFGR_PLL1RGE_0 (0x1UL << RCC_PLLCFGR_PLL1RGE_Pos) /*!< 0x00000008 */ +#define RCC_PLLCFGR_PLL1RGE_1 (0x2UL << RCC_PLLCFGR_PLL1RGE_Pos) /*!< 0x00000010 */ + +#define RCC_PLLCFGR_PLL1PEN_Pos (5U) +#define RCC_PLLCFGR_PLL1PEN_Msk (0x1UL << RCC_PLLCFGR_PLL1PEN_Pos) /*!< 0x00000020 */ +#define RCC_PLLCFGR_PLL1PEN RCC_PLLCFGR_PLL1PEN_Msk /*!< PLL1 DIVP divider output enable */ +#define RCC_PLLCFGR_PLL1QEN_Pos (6U) +#define RCC_PLLCFGR_PLL1QEN_Msk (0x1UL << RCC_PLLCFGR_PLL1QEN_Pos) /*!< 0x00000040 */ +#define RCC_PLLCFGR_PLL1QEN RCC_PLLCFGR_PLL1QEN_Msk /*!< PLL1 DIVQ divider output enable */ +#define RCC_PLLCFGR_PLL1REN_Pos (7U) +#define RCC_PLLCFGR_PLL1REN_Msk (0x1UL << RCC_PLLCFGR_PLL1REN_Pos) /*!< 0x00000080 */ +#define RCC_PLLCFGR_PLL1REN RCC_PLLCFGR_PLL1REN_Msk /*!< PLL1 DIVR divider output enable */ +#define RCC_PLLCFGR_PLL1SEN_Pos (8U) +#define RCC_PLLCFGR_PLL1SEN_Msk (0x1UL << RCC_PLLCFGR_PLL1SEN_Pos) /*!< 0x00000100 */ +#define RCC_PLLCFGR_PLL1SEN RCC_PLLCFGR_PLL1SEN_Msk /*!< PLL1 DIVS divider output enable */ + +#define RCC_PLLCFGR_PLL2FRACEN_Pos (11U) +#define RCC_PLLCFGR_PLL2FRACEN_Msk (0x1UL << RCC_PLLCFGR_PLL2FRACEN_Pos) /*!< 0x00000800 */ +#define RCC_PLLCFGR_PLL2FRACEN RCC_PLLCFGR_PLL2FRACEN_Msk /*!< PLL2 fractional latch enable */ +#define RCC_PLLCFGR_PLL2VCOSEL_Pos (12U) +#define RCC_PLLCFGR_PLL2VCOSEL_Msk (0x1UL << RCC_PLLCFGR_PLL2VCOSEL_Pos) /*!< 0x00001000 */ +#define RCC_PLLCFGR_PLL2VCOSEL RCC_PLLCFGR_PLL2VCOSEL_Msk /*!< PLL2 VCO selection */ +#define RCC_PLLCFGR_PLL2SSCGEN_Pos (13U) +#define RCC_PLLCFGR_PLL2SSCGEN_Msk (0x1UL << RCC_PLLCFGR_PLL2SSCGEN_Pos) /*!< 0x00002000 */ +#define RCC_PLLCFGR_PLL2SSCGEN RCC_PLLCFGR_PLL2SSCGEN_Msk /*!< PLL2 Spread Spectrum Clock Generator enable */ +#define RCC_PLLCFGR_PLL2RGE_Pos (14U) +#define RCC_PLLCFGR_PLL2RGE_Msk (0x3UL << RCC_PLLCFGR_PLL2RGE_Pos) /*!< 0x0000C000 */ +#define RCC_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_Msk /*!< PLL2RGE[1:0] bits: PLL2 input frequency range */ +#define RCC_PLLCFGR_PLL2RGE_0 (0x1UL << RCC_PLLCFGR_PLL2RGE_Pos) /*!< 0x00004000 */ +#define RCC_PLLCFGR_PLL2RGE_1 (0x2UL << RCC_PLLCFGR_PLL2RGE_Pos) /*!< 0x00008000 */ + +#define RCC_PLLCFGR_PLL2PEN_Pos (16U) +#define RCC_PLLCFGR_PLL2PEN_Msk (0x1UL << RCC_PLLCFGR_PLL2PEN_Pos) /*!< 0x00010000 */ +#define RCC_PLLCFGR_PLL2PEN RCC_PLLCFGR_PLL2PEN_Msk /*!< PLL2 DIVP divider output enable */ +#define RCC_PLLCFGR_PLL2QEN_Pos (17U) +#define RCC_PLLCFGR_PLL2QEN_Msk (0x1UL << RCC_PLLCFGR_PLL2QEN_Pos) /*!< 0x00020000 */ +#define RCC_PLLCFGR_PLL2QEN RCC_PLLCFGR_PLL2QEN_Msk /*!< PLL2 DIVQ divider output enable */ +#define RCC_PLLCFGR_PLL2REN_Pos (18U) +#define RCC_PLLCFGR_PLL2REN_Msk (0x1UL << RCC_PLLCFGR_PLL2REN_Pos) /*!< 0x00040000 */ +#define RCC_PLLCFGR_PLL2REN RCC_PLLCFGR_PLL2REN_Msk /*!< PLL2 DIVR divider output enable */ +#define RCC_PLLCFGR_PLL2SEN_Pos (19U) +#define RCC_PLLCFGR_PLL2SEN_Msk (0x1UL << RCC_PLLCFGR_PLL2SEN_Pos) /*!< 0x00080000 */ +#define RCC_PLLCFGR_PLL2SEN RCC_PLLCFGR_PLL2SEN_Msk /*!< PLL2 DIVS divider output enable */ +#define RCC_PLLCFGR_PLL2TEN_Pos (20U) +#define RCC_PLLCFGR_PLL2TEN_Msk (0x1UL << RCC_PLLCFGR_PLL2TEN_Pos) /*!< 0x00100000 */ +#define RCC_PLLCFGR_PLL2TEN RCC_PLLCFGR_PLL2TEN_Msk /*!< PLL2 DIVT divider output enable */ + +#define RCC_PLLCFGR_PLL3FRACEN_Pos (22U) +#define RCC_PLLCFGR_PLL3FRACEN_Msk (0x1UL << RCC_PLLCFGR_PLL3FRACEN_Pos) /*!< 0x00400000 */ +#define RCC_PLLCFGR_PLL3FRACEN RCC_PLLCFGR_PLL3FRACEN_Msk /*!< PLL3 fractional latch enable */ +#define RCC_PLLCFGR_PLL3VCOSEL_Pos (23U) +#define RCC_PLLCFGR_PLL3VCOSEL_Msk (0x1UL << RCC_PLLCFGR_PLL3VCOSEL_Pos) /*!< 0x00800000 */ +#define RCC_PLLCFGR_PLL3VCOSEL RCC_PLLCFGR_PLL3VCOSEL_Msk /*!< PLL3 VCO selection */ +#define RCC_PLLCFGR_PLL3SSCGEN_Pos (24U) +#define RCC_PLLCFGR_PLL3SSCGEN_Msk (0x1UL << RCC_PLLCFGR_PLL3SSCGEN_Pos) /*!< 0x01000000 */ +#define RCC_PLLCFGR_PLL3SSCGEN RCC_PLLCFGR_PLL3SSCGEN_Msk /*!< PLL3 Spread Spectrum Clock Generator enable */ +#define RCC_PLLCFGR_PLL3RGE_Pos (25U) +#define RCC_PLLCFGR_PLL3RGE_Msk (0x3UL << RCC_PLLCFGR_PLL3RGE_Pos) /*!< 0x06000000 */ +#define RCC_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_Msk /*!< PLL3RGE[1:0] bits: PLL3 input frequency range */ +#define RCC_PLLCFGR_PLL3RGE_0 (0x1UL << RCC_PLLCFGR_PLL3RGE_Pos) /*!< 0x02000000 */ +#define RCC_PLLCFGR_PLL3RGE_1 (0x2UL << RCC_PLLCFGR_PLL3RGE_Pos) /*!< 0x04000000 */ + +#define RCC_PLLCFGR_PLL3PEN_Pos (27U) +#define RCC_PLLCFGR_PLL3PEN_Msk (0x1UL << RCC_PLLCFGR_PLL3PEN_Pos) /*!< 0x08000000 */ +#define RCC_PLLCFGR_PLL3PEN RCC_PLLCFGR_PLL3PEN_Msk /*!< PLL3 DIVP divider output enable */ +#define RCC_PLLCFGR_PLL3QEN_Pos (28U) +#define RCC_PLLCFGR_PLL3QEN_Msk (0x1UL << RCC_PLLCFGR_PLL3QEN_Pos) /*!< 0x10000000 */ +#define RCC_PLLCFGR_PLL3QEN RCC_PLLCFGR_PLL3QEN_Msk /*!< PLL3 DIVQ divider output enable */ +#define RCC_PLLCFGR_PLL3REN_Pos (29U) +#define RCC_PLLCFGR_PLL3REN_Msk (0x1UL << RCC_PLLCFGR_PLL3REN_Pos) /*!< 0x20000000 */ +#define RCC_PLLCFGR_PLL3REN RCC_PLLCFGR_PLL3REN_Msk /*!< PLL3 DIVR divider output enable */ +#define RCC_PLLCFGR_PLL3SEN_Pos (30U) +#define RCC_PLLCFGR_PLL3SEN_Msk (0x1UL << RCC_PLLCFGR_PLL3SEN_Pos) /*!< 0x40000000 */ +#define RCC_PLLCFGR_PLL3SEN RCC_PLLCFGR_PLL3SEN_Msk /*!< PLL3 DIVS divider output enable */ + +/******************** Bit definition for RCC_PLL1DIVR1 register *************/ +#define RCC_PLL1DIVR1_DIVN_Pos (0U) +#define RCC_PLL1DIVR1_DIVN_Msk (0x1FFUL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x000001FF */ +#define RCC_PLL1DIVR1_DIVN RCC_PLL1DIVR1_DIVN_Msk /*!< DIVN1[8:0] bits: PLL1 DIVN division factor */ +#define RCC_PLL1DIVR1_DIVN_0 (0x001UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000001 */ +#define RCC_PLL1DIVR1_DIVN_1 (0x002UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000002 */ +#define RCC_PLL1DIVR1_DIVN_2 (0x004UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000004 */ +#define RCC_PLL1DIVR1_DIVN_3 (0x008UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000008 */ +#define RCC_PLL1DIVR1_DIVN_4 (0x010UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000010 */ +#define RCC_PLL1DIVR1_DIVN_5 (0x020UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000020 */ +#define RCC_PLL1DIVR1_DIVN_6 (0x040UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000040 */ +#define RCC_PLL1DIVR1_DIVN_7 (0x080UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000080 */ +#define RCC_PLL1DIVR1_DIVN_8 (0x100UL << RCC_PLL1DIVR1_DIVN_Pos) /*!< 0x00000100 */ + +#define RCC_PLL1DIVR1_DIVP_Pos (9U) +#define RCC_PLL1DIVR1_DIVP_Msk (0x7FUL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x0000FE00 */ +#define RCC_PLL1DIVR1_DIVP RCC_PLL1DIVR1_DIVP_Msk /*!< DIVP1[6:0] bits: PLL1 DIVP division factor */ +#define RCC_PLL1DIVR1_DIVP_0 (0x001UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00000200 */ +#define RCC_PLL1DIVR1_DIVP_1 (0x002UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00000400 */ +#define RCC_PLL1DIVR1_DIVP_2 (0x004UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00000800 */ +#define RCC_PLL1DIVR1_DIVP_3 (0x008UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00001000 */ +#define RCC_PLL1DIVR1_DIVP_4 (0x010UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00002000 */ +#define RCC_PLL1DIVR1_DIVP_5 (0x020UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00004000 */ +#define RCC_PLL1DIVR1_DIVP_6 (0x040UL << RCC_PLL1DIVR1_DIVP_Pos) /*!< 0x00008000 */ + +#define RCC_PLL1DIVR1_DIVQ_Pos (16U) +#define RCC_PLL1DIVR1_DIVQ_Msk (0x7FUL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x007F0000 */ +#define RCC_PLL1DIVR1_DIVQ RCC_PLL1DIVR1_DIVQ_Msk /*!< DIVQ1[6:0] bits: PLL1 DIVQ division factor */ +#define RCC_PLL1DIVR1_DIVQ_0 (0x001UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00010000 */ +#define RCC_PLL1DIVR1_DIVQ_1 (0x002UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00020000 */ +#define RCC_PLL1DIVR1_DIVQ_2 (0x004UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00040000 */ +#define RCC_PLL1DIVR1_DIVQ_3 (0x008UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00080000 */ +#define RCC_PLL1DIVR1_DIVQ_4 (0x010UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00100000 */ +#define RCC_PLL1DIVR1_DIVQ_5 (0x020UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00200000 */ +#define RCC_PLL1DIVR1_DIVQ_6 (0x040UL << RCC_PLL1DIVR1_DIVQ_Pos) /*!< 0x00400000 */ + +#define RCC_PLL1DIVR1_DIVR_Pos (24U) +#define RCC_PLL1DIVR1_DIVR_Msk (0x7FUL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x7F000000 */ +#define RCC_PLL1DIVR1_DIVR RCC_PLL1DIVR1_DIVR_Msk /*!< DIVR1[6:0] bits: PLL1 DIVR division factor */ +#define RCC_PLL1DIVR1_DIVR_0 (0x001UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x01000000 */ +#define RCC_PLL1DIVR1_DIVR_1 (0x002UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x02000000 */ +#define RCC_PLL1DIVR1_DIVR_2 (0x004UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x04000000 */ +#define RCC_PLL1DIVR1_DIVR_3 (0x008UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x08000000 */ +#define RCC_PLL1DIVR1_DIVR_4 (0x010UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x10000000 */ +#define RCC_PLL1DIVR1_DIVR_5 (0x020UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x20000000 */ +#define RCC_PLL1DIVR1_DIVR_6 (0x040UL << RCC_PLL1DIVR1_DIVR_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_PLL1FRACR register *************/ +#define RCC_PLL1FRACR_FRACN_Pos (3U) +#define RCC_PLL1FRACR_FRACN_Msk (0x1FFFUL << RCC_PLL1FRACR_FRACN_Pos) /*!< 0x0000FFF8 */ +#define RCC_PLL1FRACR_FRACN RCC_PLL1FRACR_FRACN_Msk /*!< FRACN[12:0] bits */ + +/******************** Bit definition for RCC_PLL2DIVR1 register *************/ +#define RCC_PLL2DIVR1_DIVN_Pos (0U) +#define RCC_PLL2DIVR1_DIVN_Msk (0x1FFUL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x000001FF */ +#define RCC_PLL2DIVR1_DIVN RCC_PLL2DIVR1_DIVN_Msk /*!< DIVN2[8:0] bits: PLL2 DIVN division factor */ +#define RCC_PLL2DIVR1_DIVN_0 (0x001UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000001 */ +#define RCC_PLL2DIVR1_DIVN_1 (0x002UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000002 */ +#define RCC_PLL2DIVR1_DIVN_2 (0x004UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000004 */ +#define RCC_PLL2DIVR1_DIVN_3 (0x008UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000008 */ +#define RCC_PLL2DIVR1_DIVN_4 (0x010UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000010 */ +#define RCC_PLL2DIVR1_DIVN_5 (0x020UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000020 */ +#define RCC_PLL2DIVR1_DIVN_6 (0x040UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000040 */ +#define RCC_PLL2DIVR1_DIVN_7 (0x080UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000080 */ +#define RCC_PLL2DIVR1_DIVN_8 (0x100UL << RCC_PLL2DIVR1_DIVN_Pos) /*!< 0x00000100 */ + +#define RCC_PLL2DIVR1_DIVP_Pos (9U) +#define RCC_PLL2DIVR1_DIVP_Msk (0x7FUL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x0000FE00 */ +#define RCC_PLL2DIVR1_DIVP RCC_PLL2DIVR1_DIVP_Msk /*!< DIVP2[6:0] bits: PLL2 DIVP division factor */ +#define RCC_PLL2DIVR1_DIVP_0 (0x001UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00000200 */ +#define RCC_PLL2DIVR1_DIVP_1 (0x002UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00000400 */ +#define RCC_PLL2DIVR1_DIVP_2 (0x004UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00000800 */ +#define RCC_PLL2DIVR1_DIVP_3 (0x008UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00001000 */ +#define RCC_PLL2DIVR1_DIVP_4 (0x010UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00002000 */ +#define RCC_PLL2DIVR1_DIVP_5 (0x020UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00004000 */ +#define RCC_PLL2DIVR1_DIVP_6 (0x040UL << RCC_PLL2DIVR1_DIVP_Pos) /*!< 0x00008000 */ + +#define RCC_PLL2DIVR1_DIVQ_Pos (16U) +#define RCC_PLL2DIVR1_DIVQ_Msk (0x7FUL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x007F0000 */ +#define RCC_PLL2DIVR1_DIVQ RCC_PLL2DIVR1_DIVQ_Msk /*!< DIVQ2[6:0] bits: PLL2 DIVQ division factor */ +#define RCC_PLL2DIVR1_DIVQ_0 (0x001UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00010000 */ +#define RCC_PLL2DIVR1_DIVQ_1 (0x002UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00020000 */ +#define RCC_PLL2DIVR1_DIVQ_2 (0x004UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00040000 */ +#define RCC_PLL2DIVR1_DIVQ_3 (0x008UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00080000 */ +#define RCC_PLL2DIVR1_DIVQ_4 (0x010UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00100000 */ +#define RCC_PLL2DIVR1_DIVQ_5 (0x020UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00200000 */ +#define RCC_PLL2DIVR1_DIVQ_6 (0x040UL << RCC_PLL2DIVR1_DIVQ_Pos) /*!< 0x00400000 */ + +#define RCC_PLL2DIVR1_DIVR_Pos (24U) +#define RCC_PLL2DIVR1_DIVR_Msk (0x7FUL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x7F000000 */ +#define RCC_PLL2DIVR1_DIVR RCC_PLL2DIVR1_DIVR_Msk /*!< DIVR2[6:0] bits: PLL2 DIVR division factor */ +#define RCC_PLL2DIVR1_DIVR_0 (0x001UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x01000000 */ +#define RCC_PLL2DIVR1_DIVR_1 (0x002UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x02000000 */ +#define RCC_PLL2DIVR1_DIVR_2 (0x004UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x04000000 */ +#define RCC_PLL2DIVR1_DIVR_3 (0x008UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x08000000 */ +#define RCC_PLL2DIVR1_DIVR_4 (0x010UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x10000000 */ +#define RCC_PLL2DIVR1_DIVR_5 (0x020UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x20000000 */ +#define RCC_PLL2DIVR1_DIVR_6 (0x040UL << RCC_PLL2DIVR1_DIVR_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_PLL2FRACR register *************/ +#define RCC_PLL2FRACR_FRACN_Pos (3U) +#define RCC_PLL2FRACR_FRACN_Msk (0x1FFFUL << RCC_PLL2FRACR_FRACN_Pos) /*!< 0x0000FFF8 */ +#define RCC_PLL2FRACR_FRACN RCC_PLL2FRACR_FRACN_Msk /*!< FRACN[12:0] bits */ + +/******************** Bit definition for RCC_PLL3DIVR1 register *************/ +#define RCC_PLL3DIVR1_DIVN_Pos (0U) +#define RCC_PLL3DIVR1_DIVN_Msk (0x1FFUL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x000001FF */ +#define RCC_PLL3DIVR1_DIVN RCC_PLL3DIVR1_DIVN_Msk /*!< DIVN3[8:0] bits: PLL3 DIVN division factor */ +#define RCC_PLL3DIVR1_DIVN_0 (0x001UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000001 */ +#define RCC_PLL3DIVR1_DIVN_1 (0x002UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000002 */ +#define RCC_PLL3DIVR1_DIVN_2 (0x004UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000004 */ +#define RCC_PLL3DIVR1_DIVN_3 (0x008UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000008 */ +#define RCC_PLL3DIVR1_DIVN_4 (0x010UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000010 */ +#define RCC_PLL3DIVR1_DIVN_5 (0x020UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000020 */ +#define RCC_PLL3DIVR1_DIVN_6 (0x040UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000040 */ +#define RCC_PLL3DIVR1_DIVN_7 (0x080UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000080 */ +#define RCC_PLL3DIVR1_DIVN_8 (0x100UL << RCC_PLL3DIVR1_DIVN_Pos) /*!< 0x00000100 */ + +#define RCC_PLL3DIVR1_DIVP_Pos (9U) +#define RCC_PLL3DIVR1_DIVP_Msk (0x7FUL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x0000FE00 */ +#define RCC_PLL3DIVR1_DIVP RCC_PLL3DIVR1_DIVP_Msk /*!< DIVP3[6:0] bits: PLL3 DIVP division factor */ +#define RCC_PLL3DIVR1_DIVP_0 (0x001UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00000200 */ +#define RCC_PLL3DIVR1_DIVP_1 (0x002UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00000400 */ +#define RCC_PLL3DIVR1_DIVP_2 (0x004UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00000800 */ +#define RCC_PLL3DIVR1_DIVP_3 (0x008UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00001000 */ +#define RCC_PLL3DIVR1_DIVP_4 (0x010UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00002000 */ +#define RCC_PLL3DIVR1_DIVP_5 (0x020UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00004000 */ +#define RCC_PLL3DIVR1_DIVP_6 (0x040UL << RCC_PLL3DIVR1_DIVP_Pos) /*!< 0x00008000 */ + +#define RCC_PLL3DIVR1_DIVQ_Pos (16U) +#define RCC_PLL3DIVR1_DIVQ_Msk (0x7FUL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x007F0000 */ +#define RCC_PLL3DIVR1_DIVQ RCC_PLL3DIVR1_DIVQ_Msk /*!< DIVQ3[6:0] bits: PLL3 DIVQ division factor */ +#define RCC_PLL3DIVR1_DIVQ_0 (0x001UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00010000 */ +#define RCC_PLL3DIVR1_DIVQ_1 (0x002UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00020000 */ +#define RCC_PLL3DIVR1_DIVQ_2 (0x004UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00040000 */ +#define RCC_PLL3DIVR1_DIVQ_3 (0x008UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00080000 */ +#define RCC_PLL3DIVR1_DIVQ_4 (0x010UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00100000 */ +#define RCC_PLL3DIVR1_DIVQ_5 (0x020UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00200000 */ +#define RCC_PLL3DIVR1_DIVQ_6 (0x040UL << RCC_PLL3DIVR1_DIVQ_Pos) /*!< 0x00400000 */ + +#define RCC_PLL3DIVR1_DIVR_Pos (24U) +#define RCC_PLL3DIVR1_DIVR_Msk (0x7FUL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x7F000000 */ +#define RCC_PLL3DIVR1_DIVR RCC_PLL3DIVR1_DIVR_Msk /*!< DIVR3[6:0] bits: PLL3 DIVR division factor */ +#define RCC_PLL3DIVR1_DIVR_0 (0x001UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x01000000 */ +#define RCC_PLL3DIVR1_DIVR_1 (0x002UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x02000000 */ +#define RCC_PLL3DIVR1_DIVR_2 (0x004UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x04000000 */ +#define RCC_PLL3DIVR1_DIVR_3 (0x008UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x08000000 */ +#define RCC_PLL3DIVR1_DIVR_4 (0x010UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x10000000 */ +#define RCC_PLL3DIVR1_DIVR_5 (0x020UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x20000000 */ +#define RCC_PLL3DIVR1_DIVR_6 (0x040UL << RCC_PLL3DIVR1_DIVR_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_PLL3FRACR register *************/ +#define RCC_PLL3FRACR_FRACN_Pos (3U) +#define RCC_PLL3FRACR_FRACN_Msk (0x1FFFUL << RCC_PLL3FRACR_FRACN_Pos) /*!< 0x0000FFF8 */ +#define RCC_PLL3FRACR_FRACN RCC_PLL3FRACR_FRACN_Msk /*!< FRACN[12:0] bits */ + +/******************** Bit definition for RCC_CCIPR1 register **************/ +#define RCC_CCIPR1_FMCSEL_Pos (0U) +#define RCC_CCIPR1_FMCSEL_Msk (0x3UL << RCC_CCIPR1_FMCSEL_Pos) /*!< 0x00000003 */ +#define RCC_CCIPR1_FMCSEL RCC_CCIPR1_FMCSEL_Msk +#define RCC_CCIPR1_FMCSEL_0 (0x1UL << RCC_CCIPR1_FMCSEL_Pos) /*!< 0x00000001 */ +#define RCC_CCIPR1_FMCSEL_1 (0x2UL << RCC_CCIPR1_FMCSEL_Pos) /*!< 0x00000002 */ + +#define RCC_CCIPR1_SDMMC12SEL_Pos (2U) +#define RCC_CCIPR1_SDMMC12SEL_Msk (0x1UL << RCC_CCIPR1_SDMMC12SEL_Pos) /*!< 0x00000004 */ +#define RCC_CCIPR1_SDMMC12SEL RCC_CCIPR1_SDMMC12SEL_Msk + +#define RCC_CCIPR1_XSPI1SEL_Pos (4U) +#define RCC_CCIPR1_XSPI1SEL_Msk (0x3UL << RCC_CCIPR1_XSPI1SEL_Pos) /*!< 0x00000030 */ +#define RCC_CCIPR1_XSPI1SEL RCC_CCIPR1_XSPI1SEL_Msk +#define RCC_CCIPR1_XSPI1SEL_0 (0x1UL << RCC_CCIPR1_XSPI1SEL_Pos) /*!< 0x00000010 */ +#define RCC_CCIPR1_XSPI1SEL_1 (0x2UL << RCC_CCIPR1_XSPI1SEL_Pos) /*!< 0x00000020 */ + +#define RCC_CCIPR1_XSPI2SEL_Pos (6U) +#define RCC_CCIPR1_XSPI2SEL_Msk (0x3UL << RCC_CCIPR1_XSPI2SEL_Pos) /*!< 0x000000C0 */ +#define RCC_CCIPR1_XSPI2SEL RCC_CCIPR1_XSPI2SEL_Msk +#define RCC_CCIPR1_XSPI2SEL_0 (0x1UL << RCC_CCIPR1_XSPI2SEL_Pos) /*!< 0x00000040 */ +#define RCC_CCIPR1_XSPI2SEL_1 (0x2UL << RCC_CCIPR1_XSPI2SEL_Pos) /*!< 0x00000080 */ + +#define RCC_CCIPR1_USBREFCKSEL_Pos (8U) +#define RCC_CCIPR1_USBREFCKSEL_Msk (0xFUL << RCC_CCIPR1_USBREFCKSEL_Pos) /*!< 0x00000F00 */ +#define RCC_CCIPR1_USBREFCKSEL RCC_CCIPR1_USBREFCKSEL_Msk +#define RCC_CCIPR1_USBREFCKSEL_0 (0x1UL << RCC_CCIPR1_USBREFCKSEL_Pos) /*!< 0x00000100 */ +#define RCC_CCIPR1_USBREFCKSEL_1 (0x2UL << RCC_CCIPR1_USBREFCKSEL_Pos) /*!< 0x00000200 */ +#define RCC_CCIPR1_USBREFCKSEL_2 (0x4UL << RCC_CCIPR1_USBREFCKSEL_Pos) /*!< 0x00000400 */ +#define RCC_CCIPR1_USBREFCKSEL_3 (0x8UL << RCC_CCIPR1_USBREFCKSEL_Pos) /*!< 0x00000800 */ + +#define RCC_CCIPR1_USBPHYCSEL_Pos (12U) +#define RCC_CCIPR1_USBPHYCSEL_Msk (0x3UL << RCC_CCIPR1_USBPHYCSEL_Pos) /*!< 0x00003000 */ +#define RCC_CCIPR1_USBPHYCSEL RCC_CCIPR1_USBPHYCSEL_Msk +#define RCC_CCIPR1_USBPHYCSEL_0 (0x1UL << RCC_CCIPR1_USBPHYCSEL_Pos) /*!< 0x00001000 */ +#define RCC_CCIPR1_USBPHYCSEL_1 (0x2UL << RCC_CCIPR1_USBPHYCSEL_Pos) /*!< 0x00002000 */ + +#define RCC_CCIPR1_OTGFSSEL_Pos (14U) +#define RCC_CCIPR1_OTGFSSEL_Msk (0x3UL << RCC_CCIPR1_OTGFSSEL_Pos) /*!< 0x0000C000 */ +#define RCC_CCIPR1_OTGFSSEL RCC_CCIPR1_OTGFSSEL_Msk +#define RCC_CCIPR1_OTGFSSEL_0 (0x1UL << RCC_CCIPR1_OTGFSSEL_Pos) /*!< 0x00004000 */ +#define RCC_CCIPR1_OTGFSSEL_1 (0x2UL << RCC_CCIPR1_OTGFSSEL_Pos) /*!< 0x00008000 */ + +#define RCC_CCIPR1_ETH1REFCKSEL_Pos (16U) +#define RCC_CCIPR1_ETH1REFCKSEL_Msk (0x3UL << RCC_CCIPR1_ETH1REFCKSEL_Pos) /*!< 0x00030000 */ +#define RCC_CCIPR1_ETH1REFCKSEL RCC_CCIPR1_ETH1REFCKSEL_Msk +#define RCC_CCIPR1_ETH1REFCKSEL_0 (0x1UL << RCC_CCIPR1_ETH1REFCKSEL_Pos) /*!< 0x00010000 */ +#define RCC_CCIPR1_ETH1REFCKSEL_1 (0x2UL << RCC_CCIPR1_ETH1REFCKSEL_Pos) /*!< 0x00020000 */ + +#define RCC_CCIPR1_ETH1PHYCKSEL_Pos (18U) +#define RCC_CCIPR1_ETH1PHYCKSEL_Msk (0x1UL << RCC_CCIPR1_ETH1PHYCKSEL_Pos) /*!< 0x00040000 */ +#define RCC_CCIPR1_ETH1PHYCKSEL RCC_CCIPR1_ETH1PHYCKSEL_Msk + +#define RCC_CCIPR1_ADF1SEL_Pos (20U) +#define RCC_CCIPR1_ADF1SEL_Msk (0x7UL << RCC_CCIPR1_ADF1SEL_Pos) /*!< 0x00700000 */ +#define RCC_CCIPR1_ADF1SEL RCC_CCIPR1_ADF1SEL_Msk +#define RCC_CCIPR1_ADF1SEL_0 (0x1UL << RCC_CCIPR1_ADF1SEL_Pos) /*!< 0x00100000 */ +#define RCC_CCIPR1_ADF1SEL_1 (0x2UL << RCC_CCIPR1_ADF1SEL_Pos) /*!< 0x00200000 */ +#define RCC_CCIPR1_ADF1SEL_2 (0x4UL << RCC_CCIPR1_ADF1SEL_Pos) /*!< 0x00400000 */ + +#define RCC_CCIPR1_ADCSEL_Pos (24U) +#define RCC_CCIPR1_ADCSEL_Msk (0x3UL << RCC_CCIPR1_ADCSEL_Pos) /*!< 0x03000000 */ +#define RCC_CCIPR1_ADCSEL RCC_CCIPR1_ADCSEL_Msk +#define RCC_CCIPR1_ADCSEL_0 (0x1UL << RCC_CCIPR1_ADCSEL_Pos) /*!< 0x01000000 */ +#define RCC_CCIPR1_ADCSEL_1 (0x2UL << RCC_CCIPR1_ADCSEL_Pos) /*!< 0x02000000 */ + +#define RCC_CCIPR1_PSSISEL_Pos (27U) +#define RCC_CCIPR1_PSSISEL_Msk (0x1UL << RCC_CCIPR1_PSSISEL_Pos) /*!< 0x08000000 */ +#define RCC_CCIPR1_PSSISEL RCC_CCIPR1_PSSISEL_Msk + +#define RCC_CCIPR1_CKPERSEL_Pos (28U) +#define RCC_CCIPR1_CKPERSEL_Msk (0x3UL << RCC_CCIPR1_CKPERSEL_Pos) /*!< 0x30000000 */ +#define RCC_CCIPR1_CKPERSEL RCC_CCIPR1_CKPERSEL_Msk +#define RCC_CCIPR1_CKPERSEL_0 (0x1UL << RCC_CCIPR1_CKPERSEL_Pos) /*!< 0x10000000 */ +#define RCC_CCIPR1_CKPERSEL_1 (0x2UL << RCC_CCIPR1_CKPERSEL_Pos) /*!< 0x20000000 */ + +/******************** Bit definition for RCC_CCIPR2 register *************/ +#define RCC_CCIPR2_UART234578SEL_Pos (0U) +#define RCC_CCIPR2_UART234578SEL_Msk (0x7UL << RCC_CCIPR2_UART234578SEL_Pos) /*!< 0x00000007 */ +#define RCC_CCIPR2_UART234578SEL RCC_CCIPR2_UART234578SEL_Msk +#define RCC_CCIPR2_UART234578SEL_0 (0x1UL << RCC_CCIPR2_UART234578SEL_Pos) /*!< 0x00000001 */ +#define RCC_CCIPR2_UART234578SEL_1 (0x2UL << RCC_CCIPR2_UART234578SEL_Pos) /*!< 0x00000002 */ +#define RCC_CCIPR2_UART234578SEL_2 (0x4UL << RCC_CCIPR2_UART234578SEL_Pos) /*!< 0x00000004 */ + +#define RCC_CCIPR2_SPI23SEL_Pos (4U) +#define RCC_CCIPR2_SPI23SEL_Msk (0x7UL << RCC_CCIPR2_SPI23SEL_Pos) /*!< 0x00000070 */ +#define RCC_CCIPR2_SPI23SEL RCC_CCIPR2_SPI23SEL_Msk +#define RCC_CCIPR2_SPI23SEL_0 (0x1UL << RCC_CCIPR2_SPI23SEL_Pos) /*!< 0x00000010 */ +#define RCC_CCIPR2_SPI23SEL_1 (0x2UL << RCC_CCIPR2_SPI23SEL_Pos) /*!< 0x00000020 */ +#define RCC_CCIPR2_SPI23SEL_2 (0x4UL << RCC_CCIPR2_SPI23SEL_Pos) /*!< 0x00000040 */ + +#define RCC_CCIPR2_I2C23SEL_Pos (8U) +#define RCC_CCIPR2_I2C23SEL_Msk (0x3UL << RCC_CCIPR2_I2C23SEL_Pos) /*!< 0x00000300 */ +#define RCC_CCIPR2_I2C23SEL RCC_CCIPR2_I2C23SEL_Msk +#define RCC_CCIPR2_I2C23SEL_0 (0x1UL << RCC_CCIPR2_I2C23SEL_Pos) /*!< 0x00000100 */ +#define RCC_CCIPR2_I2C23SEL_1 (0x2UL << RCC_CCIPR2_I2C23SEL_Pos) /*!< 0x00000200 */ + +#define RCC_CCIPR2_I2C1_I3C1SEL_Pos (12U) +#define RCC_CCIPR2_I2C1_I3C1SEL_Msk (0x3UL << RCC_CCIPR2_I2C1_I3C1SEL_Pos) /*!< 0x00003000 */ +#define RCC_CCIPR2_I2C1_I3C1SEL RCC_CCIPR2_I2C1_I3C1SEL_Msk +#define RCC_CCIPR2_I2C1_I3C1SEL_0 (0x1UL << RCC_CCIPR2_I2C1_I3C1SEL_Pos) /*!< 0x00001000 */ +#define RCC_CCIPR2_I2C1_I3C1SEL_1 (0x2UL << RCC_CCIPR2_I2C1_I3C1SEL_Pos) /*!< 0x00002000 */ + +#define RCC_CCIPR2_LPTIM1SEL_Pos (16U) +#define RCC_CCIPR2_LPTIM1SEL_Msk (0x7UL << RCC_CCIPR2_LPTIM1SEL_Pos) /*!< 0x00070000 */ +#define RCC_CCIPR2_LPTIM1SEL RCC_CCIPR2_LPTIM1SEL_Msk +#define RCC_CCIPR2_LPTIM1SEL_0 (0x1UL << RCC_CCIPR2_LPTIM1SEL_Pos) /*!< 0x00010000 */ +#define RCC_CCIPR2_LPTIM1SEL_1 (0x2UL << RCC_CCIPR2_LPTIM1SEL_Pos) /*!< 0x00020000 */ +#define RCC_CCIPR2_LPTIM1SEL_2 (0x4UL << RCC_CCIPR2_LPTIM1SEL_Pos) /*!< 0x00040000 */ + +#define RCC_CCIPR2_FDCANSEL_Pos (22U) +#define RCC_CCIPR2_FDCANSEL_Msk (0x3UL << RCC_CCIPR2_FDCANSEL_Pos) /*!< 0x00C00000 */ +#define RCC_CCIPR2_FDCANSEL RCC_CCIPR2_FDCANSEL_Msk +#define RCC_CCIPR2_FDCANSEL_0 (0x1UL << RCC_CCIPR2_FDCANSEL_Pos) /*!< 0x00400000 */ +#define RCC_CCIPR2_FDCANSEL_1 (0x2UL << RCC_CCIPR2_FDCANSEL_Pos) /*!< 0x00800000 */ + +#define RCC_CCIPR2_SPDIFRXSEL_Pos (24U) +#define RCC_CCIPR2_SPDIFRXSEL_Msk (0x3UL << RCC_CCIPR2_SPDIFRXSEL_Pos) /*!< 0x03000000 */ +#define RCC_CCIPR2_SPDIFRXSEL RCC_CCIPR2_SPDIFRXSEL_Msk +#define RCC_CCIPR2_SPDIFRXSEL_0 (0x1UL << RCC_CCIPR2_SPDIFRXSEL_Pos) /*!< 0x01000000 */ +#define RCC_CCIPR2_SPDIFRXSEL_1 (0x2UL << RCC_CCIPR2_SPDIFRXSEL_Pos) /*!< 0x02000000 */ + +#define RCC_CCIPR2_CECSEL_Pos (28U) +#define RCC_CCIPR2_CECSEL_Msk (0x3UL << RCC_CCIPR2_CECSEL_Pos) /*!< 0x03000000 */ +#define RCC_CCIPR2_CECSEL RCC_CCIPR2_CECSEL_Msk +#define RCC_CCIPR2_CECSEL_0 (0x1UL << RCC_CCIPR2_CECSEL_Pos) /*!< 0x01000000 */ +#define RCC_CCIPR2_CECSEL_1 (0x2UL << RCC_CCIPR2_CECSEL_Pos) /*!< 0x02000000 */ + +/******************** Bit definition for RCC_CCIPR3 register *************/ +#define RCC_CCIPR3_USART1SEL_Pos (0U) +#define RCC_CCIPR3_USART1SEL_Msk (0x7UL << RCC_CCIPR3_USART1SEL_Pos) /*!< 0x00000007 */ +#define RCC_CCIPR3_USART1SEL RCC_CCIPR3_USART1SEL_Msk +#define RCC_CCIPR3_USART1SEL_0 (0x1UL << RCC_CCIPR3_USART1SEL_Pos) /*!< 0x00000001 */ +#define RCC_CCIPR3_USART1SEL_1 (0x2UL << RCC_CCIPR3_USART1SEL_Pos) /*!< 0x00000002 */ +#define RCC_CCIPR3_USART1SEL_2 (0x4UL << RCC_CCIPR3_USART1SEL_Pos) /*!< 0x00000004 */ + +#define RCC_CCIPR3_SPI45SEL_Pos (4U) +#define RCC_CCIPR3_SPI45SEL_Msk (0x7UL << RCC_CCIPR3_SPI45SEL_Pos) /*!< 0x00000070 */ +#define RCC_CCIPR3_SPI45SEL RCC_CCIPR3_SPI45SEL_Msk +#define RCC_CCIPR3_SPI45SEL_0 (0x1UL << RCC_CCIPR3_SPI45SEL_Pos) /*!< 0x00000010 */ +#define RCC_CCIPR3_SPI45SEL_1 (0x2UL << RCC_CCIPR3_SPI45SEL_Pos) /*!< 0x00000020 */ +#define RCC_CCIPR3_SPI45SEL_2 (0x4UL << RCC_CCIPR3_SPI45SEL_Pos) /*!< 0x00000040 */ + +#define RCC_CCIPR3_SPI1SEL_Pos (8U) +#define RCC_CCIPR3_SPI1SEL_Msk (0x7UL << RCC_CCIPR3_SPI1SEL_Pos) /*!< 0x00000700 */ +#define RCC_CCIPR3_SPI1SEL RCC_CCIPR3_SPI1SEL_Msk +#define RCC_CCIPR3_SPI1SEL_0 (0x1UL << RCC_CCIPR3_SPI1SEL_Pos) /*!< 0x00000100 */ +#define RCC_CCIPR3_SPI1SEL_1 (0x2UL << RCC_CCIPR3_SPI1SEL_Pos) /*!< 0x00000200 */ +#define RCC_CCIPR3_SPI1SEL_2 (0x4UL << RCC_CCIPR3_SPI1SEL_Pos) /*!< 0x00000400 */ + +#define RCC_CCIPR3_SAI1SEL_Pos (16U) +#define RCC_CCIPR3_SAI1SEL_Msk (0x7UL << RCC_CCIPR3_SAI1SEL_Pos) /*!< 0x00070000 */ +#define RCC_CCIPR3_SAI1SEL RCC_CCIPR3_SAI1SEL_Msk +#define RCC_CCIPR3_SAI1SEL_0 (0x1UL << RCC_CCIPR3_SAI1SEL_Pos) /*!< 0x00010000 */ +#define RCC_CCIPR3_SAI1SEL_1 (0x2UL << RCC_CCIPR3_SAI1SEL_Pos) /*!< 0x00020000 */ +#define RCC_CCIPR3_SAI1SEL_2 (0x4UL << RCC_CCIPR3_SAI1SEL_Pos) /*!< 0x00040000 */ + +#define RCC_CCIPR3_SAI2SEL_Pos (20U) +#define RCC_CCIPR3_SAI2SEL_Msk (0x7UL << RCC_CCIPR3_SAI2SEL_Pos) /*!< 0x00700000 */ +#define RCC_CCIPR3_SAI2SEL RCC_CCIPR3_SAI2SEL_Msk +#define RCC_CCIPR3_SAI2SEL_0 (0x1UL << RCC_CCIPR3_SAI2SEL_Pos) /*!< 0x00100000 */ +#define RCC_CCIPR3_SAI2SEL_1 (0x2UL << RCC_CCIPR3_SAI2SEL_Pos) /*!< 0x00200000 */ +#define RCC_CCIPR3_SAI2SEL_2 (0x4UL << RCC_CCIPR3_SAI2SEL_Pos) /*!< 0x00400000 */ + +/******************** Bit definition for RCC_CCIPR4 register ************/ +#define RCC_CCIPR4_LPUART1SEL_Pos (0U) +#define RCC_CCIPR4_LPUART1SEL_Msk (0x7UL << RCC_CCIPR4_LPUART1SEL_Pos) /*!< 0x00000007 */ +#define RCC_CCIPR4_LPUART1SEL RCC_CCIPR4_LPUART1SEL_Msk +#define RCC_CCIPR4_LPUART1SEL_0 (0x1UL << RCC_CCIPR4_LPUART1SEL_Pos) /*!< 0x00000001 */ +#define RCC_CCIPR4_LPUART1SEL_1 (0x2UL << RCC_CCIPR4_LPUART1SEL_Pos) /*!< 0x00000002 */ +#define RCC_CCIPR4_LPUART1SEL_2 (0x4UL << RCC_CCIPR4_LPUART1SEL_Pos) /*!< 0x00000004 */ + +#define RCC_CCIPR4_SPI6SEL_Pos (4U) +#define RCC_CCIPR4_SPI6SEL_Msk (0x7UL << RCC_CCIPR4_SPI6SEL_Pos) /*!< 0x00000070 */ +#define RCC_CCIPR4_SPI6SEL RCC_CCIPR4_SPI6SEL_Msk +#define RCC_CCIPR4_SPI6SEL_0 (0x1UL << RCC_CCIPR4_SPI6SEL_Pos) /*!< 0x00000010 */ +#define RCC_CCIPR4_SPI6SEL_1 (0x2UL << RCC_CCIPR4_SPI6SEL_Pos) /*!< 0x00000020 */ +#define RCC_CCIPR4_SPI6SEL_2 (0x4UL << RCC_CCIPR4_SPI6SEL_Pos) /*!< 0x00000040 */ + +#define RCC_CCIPR4_LPTIM23SEL_Pos (8U) +#define RCC_CCIPR4_LPTIM23SEL_Msk (0x7UL << RCC_CCIPR4_LPTIM23SEL_Pos) /*!< 0x00000700 */ +#define RCC_CCIPR4_LPTIM23SEL RCC_CCIPR4_LPTIM23SEL_Msk +#define RCC_CCIPR4_LPTIM23SEL_0 (0x1UL << RCC_CCIPR4_LPTIM23SEL_Pos) /*!< 0x00000100 */ +#define RCC_CCIPR4_LPTIM23SEL_1 (0x2UL << RCC_CCIPR4_LPTIM23SEL_Pos) /*!< 0x00000200 */ +#define RCC_CCIPR4_LPTIM23SEL_2 (0x4UL << RCC_CCIPR4_LPTIM23SEL_Pos) /*!< 0x00000400 */ + +#define RCC_CCIPR4_LPTIM45SEL_Pos (12U) +#define RCC_CCIPR4_LPTIM45SEL_Msk (0x7UL << RCC_CCIPR4_LPTIM45SEL_Pos) /*!< 0x00007000 */ +#define RCC_CCIPR4_LPTIM45SEL RCC_CCIPR4_LPTIM45SEL_Msk +#define RCC_CCIPR4_LPTIM45SEL_0 (0x1UL << RCC_CCIPR4_LPTIM45SEL_Pos) /*!< 0x00001000 */ +#define RCC_CCIPR4_LPTIM45SEL_1 (0x2UL << RCC_CCIPR4_LPTIM45SEL_Pos) /*!< 0x00002000 */ +#define RCC_CCIPR4_LPTIM45SEL_2 (0x4UL << RCC_CCIPR4_LPTIM45SEL_Pos) /*!< 0x00004000 */ + +/******************** Bit definition for RCC_CIER register ******************/ +#define RCC_CIER_LSIRDYIE_Pos (0U) +#define RCC_CIER_LSIRDYIE_Msk (0x1UL << RCC_CIER_LSIRDYIE_Pos) /*!< 0x00000001 */ +#define RCC_CIER_LSIRDYIE RCC_CIER_LSIRDYIE_Msk +#define RCC_CIER_LSERDYIE_Pos (1U) +#define RCC_CIER_LSERDYIE_Msk (0x1UL << RCC_CIER_LSERDYIE_Pos) /*!< 0x00000002 */ +#define RCC_CIER_LSERDYIE RCC_CIER_LSERDYIE_Msk +#define RCC_CIER_HSIRDYIE_Pos (2U) +#define RCC_CIER_HSIRDYIE_Msk (0x1UL << RCC_CIER_HSIRDYIE_Pos) /*!< 0x00000004 */ +#define RCC_CIER_HSIRDYIE RCC_CIER_HSIRDYIE_Msk +#define RCC_CIER_HSERDYIE_Pos (3U) +#define RCC_CIER_HSERDYIE_Msk (0x1UL << RCC_CIER_HSERDYIE_Pos) /*!< 0x00000008 */ +#define RCC_CIER_HSERDYIE RCC_CIER_HSERDYIE_Msk +#define RCC_CIER_CSIRDYIE_Pos (4U) +#define RCC_CIER_CSIRDYIE_Msk (0x1UL << RCC_CIER_CSIRDYIE_Pos) /*!< 0x00000010 */ +#define RCC_CIER_CSIRDYIE RCC_CIER_CSIRDYIE_Msk +#define RCC_CIER_HSI48RDYIE_Pos (5U) +#define RCC_CIER_HSI48RDYIE_Msk (0x1UL << RCC_CIER_HSI48RDYIE_Pos) /*!< 0x00000020 */ +#define RCC_CIER_HSI48RDYIE RCC_CIER_HSI48RDYIE_Msk +#define RCC_CIER_PLL1RDYIE_Pos (6U) +#define RCC_CIER_PLL1RDYIE_Msk (0x1UL << RCC_CIER_PLL1RDYIE_Pos) /*!< 0x00000040 */ +#define RCC_CIER_PLL1RDYIE RCC_CIER_PLL1RDYIE_Msk +#define RCC_CIER_PLL2RDYIE_Pos (7U) +#define RCC_CIER_PLL2RDYIE_Msk (0x1UL << RCC_CIER_PLL2RDYIE_Pos) /*!< 0x00000080 */ +#define RCC_CIER_PLL2RDYIE RCC_CIER_PLL2RDYIE_Msk +#define RCC_CIER_PLL3RDYIE_Pos (8U) +#define RCC_CIER_PLL3RDYIE_Msk (0x1UL << RCC_CIER_PLL3RDYIE_Pos) /*!< 0x00000100 */ +#define RCC_CIER_PLL3RDYIE RCC_CIER_PLL3RDYIE_Msk +#define RCC_CIER_LSECSSIE_Pos (9U) +#define RCC_CIER_LSECSSIE_Msk (0x1UL << RCC_CIER_LSECSSIE_Pos) /*!< 0x00000200 */ +#define RCC_CIER_LSECSSIE RCC_CIER_LSECSSIE_Msk + +/******************** Bit definition for RCC_CIFR register ******************/ +#define RCC_CIFR_LSIRDYF_Pos (0U) +#define RCC_CIFR_LSIRDYF_Msk (0x1UL << RCC_CIFR_LSIRDYF_Pos) /*!< 0x00000001 */ +#define RCC_CIFR_LSIRDYF RCC_CIFR_LSIRDYF_Msk +#define RCC_CIFR_LSERDYF_Pos (1U) +#define RCC_CIFR_LSERDYF_Msk (0x1UL << RCC_CIFR_LSERDYF_Pos) /*!< 0x00000002 */ +#define RCC_CIFR_LSERDYF RCC_CIFR_LSERDYF_Msk +#define RCC_CIFR_HSIRDYF_Pos (2U) +#define RCC_CIFR_HSIRDYF_Msk (0x1UL << RCC_CIFR_HSIRDYF_Pos) /*!< 0x00000004 */ +#define RCC_CIFR_HSIRDYF RCC_CIFR_HSIRDYF_Msk +#define RCC_CIFR_HSERDYF_Pos (3U) +#define RCC_CIFR_HSERDYF_Msk (0x1UL << RCC_CIFR_HSERDYF_Pos) /*!< 0x00000008 */ +#define RCC_CIFR_HSERDYF RCC_CIFR_HSERDYF_Msk +#define RCC_CIFR_CSIRDYF_Pos (4U) +#define RCC_CIFR_CSIRDYF_Msk (0x1UL << RCC_CIFR_CSIRDYF_Pos) /*!< 0x00000010 */ +#define RCC_CIFR_CSIRDYF RCC_CIFR_CSIRDYF_Msk +#define RCC_CIFR_HSI48RDYF_Pos (5U) +#define RCC_CIFR_HSI48RDYF_Msk (0x1UL << RCC_CIFR_HSI48RDYF_Pos) /*!< 0x00000020 */ +#define RCC_CIFR_HSI48RDYF RCC_CIFR_HSI48RDYF_Msk +#define RCC_CIFR_PLL1RDYF_Pos (6U) +#define RCC_CIFR_PLL1RDYF_Msk (0x1UL << RCC_CIFR_PLL1RDYF_Pos) /*!< 0x00000040 */ +#define RCC_CIFR_PLL1RDYF RCC_CIFR_PLL1RDYF_Msk +#define RCC_CIFR_PLL2RDYF_Pos (7U) +#define RCC_CIFR_PLL2RDYF_Msk (0x1UL << RCC_CIFR_PLL2RDYF_Pos) /*!< 0x00000080 */ +#define RCC_CIFR_PLL2RDYF RCC_CIFR_PLL2RDYF_Msk +#define RCC_CIFR_PLL3RDYF_Pos (8U) +#define RCC_CIFR_PLL3RDYF_Msk (0x1UL << RCC_CIFR_PLL3RDYF_Pos) /*!< 0x00000100 */ +#define RCC_CIFR_PLL3RDYF RCC_CIFR_PLL3RDYF_Msk +#define RCC_CIFR_LSECSSF_Pos (9U) +#define RCC_CIFR_LSECSSF_Msk (0x1UL << RCC_CIFR_LSECSSF_Pos) /*!< 0x00000200 */ +#define RCC_CIFR_LSECSSF RCC_CIFR_LSECSSF_Msk +#define RCC_CIFR_HSECSSF_Pos (10U) +#define RCC_CIFR_HSECSSF_Msk (0x1UL << RCC_CIFR_HSECSSF_Pos) /*!< 0x00000400 */ +#define RCC_CIFR_HSECSSF RCC_CIFR_HSECSSF_Msk + +/******************** Bit definition for RCC_CICR register ******************/ +#define RCC_CICR_LSIRDYC_Pos (0U) +#define RCC_CICR_LSIRDYC_Msk (0x1UL << RCC_CICR_LSIRDYC_Pos) /*!< 0x00000001 */ +#define RCC_CICR_LSIRDYC RCC_CICR_LSIRDYC_Msk +#define RCC_CICR_LSERDYC_Pos (1U) +#define RCC_CICR_LSERDYC_Msk (0x1UL << RCC_CICR_LSERDYC_Pos) /*!< 0x00000002 */ +#define RCC_CICR_LSERDYC RCC_CICR_LSERDYC_Msk +#define RCC_CICR_HSIRDYC_Pos (2U) +#define RCC_CICR_HSIRDYC_Msk (0x1UL << RCC_CICR_HSIRDYC_Pos) /*!< 0x00000004 */ +#define RCC_CICR_HSIRDYC RCC_CICR_HSIRDYC_Msk +#define RCC_CICR_HSERDYC_Pos (3U) +#define RCC_CICR_HSERDYC_Msk (0x1UL << RCC_CICR_HSERDYC_Pos) /*!< 0x00000008 */ +#define RCC_CICR_HSERDYC RCC_CICR_HSERDYC_Msk +#define RCC_CICR_CSIRDYC_Pos (4U) +#define RCC_CICR_CSIRDYC_Msk (0x1UL << RCC_CICR_CSIRDYC_Pos) /*!< 0x00000010 */ +#define RCC_CICR_CSIRDYC RCC_CICR_CSIRDYC_Msk +#define RCC_CICR_HSI48RDYC_Pos (5U) +#define RCC_CICR_HSI48RDYC_Msk (0x1UL << RCC_CICR_HSI48RDYC_Pos) /*!< 0x00000020 */ +#define RCC_CICR_HSI48RDYC RCC_CICR_HSI48RDYC_Msk +#define RCC_CICR_PLL1RDYC_Pos (6U) +#define RCC_CICR_PLL1RDYC_Msk (0x1UL << RCC_CICR_PLL1RDYC_Pos) /*!< 0x00000040 */ +#define RCC_CICR_PLL1RDYC RCC_CICR_PLL1RDYC_Msk +#define RCC_CICR_PLL2RDYC_Pos (7U) +#define RCC_CICR_PLL2RDYC_Msk (0x1UL << RCC_CICR_PLL2RDYC_Pos) /*!< 0x00000080 */ +#define RCC_CICR_PLL2RDYC RCC_CICR_PLL2RDYC_Msk +#define RCC_CICR_PLL3RDYC_Pos (8U) +#define RCC_CICR_PLL3RDYC_Msk (0x1UL << RCC_CICR_PLL3RDYC_Pos) /*!< 0x00000100 */ +#define RCC_CICR_PLL3RDYC RCC_CICR_PLL3RDYC_Msk +#define RCC_CICR_LSECSSC_Pos (9U) +#define RCC_CICR_LSECSSC_Msk (0x1UL << RCC_CICR_LSECSSC_Pos) /*!< 0x00000200 */ +#define RCC_CICR_LSECSSC RCC_CICR_LSECSSC_Msk +#define RCC_CICR_HSECSSC_Pos (10U) +#define RCC_CICR_HSECSSC_Msk (0x1UL << RCC_CICR_HSECSSC_Pos) /*!< 0x00000400 */ +#define RCC_CICR_HSECSSC RCC_CICR_HSECSSC_Msk + +/******************** Bit definition for RCC_BDCR register ******************/ +#define RCC_BDCR_LSEON_Pos (0U) +#define RCC_BDCR_LSEON_Msk (0x1UL << RCC_BDCR_LSEON_Pos) /*!< 0x00000001 */ +#define RCC_BDCR_LSEON RCC_BDCR_LSEON_Msk +#define RCC_BDCR_LSERDY_Pos (1U) +#define RCC_BDCR_LSERDY_Msk (0x1UL << RCC_BDCR_LSERDY_Pos) /*!< 0x00000002 */ +#define RCC_BDCR_LSERDY RCC_BDCR_LSERDY_Msk +#define RCC_BDCR_LSEBYP_Pos (2U) +#define RCC_BDCR_LSEBYP_Msk (0x1UL << RCC_BDCR_LSEBYP_Pos) /*!< 0x00000004 */ +#define RCC_BDCR_LSEBYP RCC_BDCR_LSEBYP_Msk +#define RCC_BDCR_LSEDRV_Pos (3U) +#define RCC_BDCR_LSEDRV_Msk (0x3UL << RCC_BDCR_LSEDRV_Pos) /*!< 0x00000018 */ +#define RCC_BDCR_LSEDRV RCC_BDCR_LSEDRV_Msk +#define RCC_BDCR_LSEDRV_0 (0x1UL << RCC_BDCR_LSEDRV_Pos) /*!< 0x00000008 */ +#define RCC_BDCR_LSEDRV_1 (0x2UL << RCC_BDCR_LSEDRV_Pos) /*!< 0x00000010 */ + +#define RCC_BDCR_LSECSSON_Pos (5U) +#define RCC_BDCR_LSECSSON_Msk (0x1UL << RCC_BDCR_LSECSSON_Pos) /*!< 0x00000020 */ +#define RCC_BDCR_LSECSSON RCC_BDCR_LSECSSON_Msk +#define RCC_BDCR_LSECSSD_Pos (6U) +#define RCC_BDCR_LSECSSD_Msk (0x1UL << RCC_BDCR_LSECSSD_Pos) /*!< 0x00000040 */ +#define RCC_BDCR_LSECSSD RCC_BDCR_LSECSSD_Msk +#define RCC_BDCR_LSEEXT_Pos (7U) +#define RCC_BDCR_LSEEXT_Msk (0x1UL << RCC_BDCR_LSEEXT_Pos) /*!< 0x00000080 */ +#define RCC_BDCR_LSEEXT RCC_BDCR_LSEEXT_Msk +#define RCC_BDCR_RTCSEL_Pos (8U) +#define RCC_BDCR_RTCSEL_Msk (0x3UL << RCC_BDCR_RTCSEL_Pos) /*!< 0x00000300 */ +#define RCC_BDCR_RTCSEL RCC_BDCR_RTCSEL_Msk +#define RCC_BDCR_RTCSEL_0 (0x1UL << RCC_BDCR_RTCSEL_Pos) /*!< 0x00000100 */ +#define RCC_BDCR_RTCSEL_1 (0x2UL << RCC_BDCR_RTCSEL_Pos) /*!< 0x00000200 */ +#define RCC_BDCR_LSECSSRA_Pos (12U) +#define RCC_BDCR_LSECSSRA_Msk (0x1UL << RCC_BDCR_LSECSSRA_Pos) /*!< 0x00001000 */ +#define RCC_BDCR_LSECSSRA RCC_BDCR_LSECSSRA_Msk + +#define RCC_BDCR_RTCEN_Pos (15U) +#define RCC_BDCR_RTCEN_Msk (0x1UL << RCC_BDCR_RTCEN_Pos) /*!< 0x00008000 */ +#define RCC_BDCR_RTCEN RCC_BDCR_RTCEN_Msk +#define RCC_BDCR_VSWRST_Pos (16U) +#define RCC_BDCR_VSWRST_Msk (0x1UL << RCC_BDCR_VSWRST_Pos) /*!< 0x00010000 */ +#define RCC_BDCR_VSWRST RCC_BDCR_VSWRST_Msk + +/******************** Bit definition for RCC_CSR register *******************/ +#define RCC_CSR_LSION_Pos (0U) +#define RCC_CSR_LSION_Msk (0x1UL << RCC_CSR_LSION_Pos) /*!< 0x00000001 */ +#define RCC_CSR_LSION RCC_CSR_LSION_Msk +#define RCC_CSR_LSIRDY_Pos (1U) +#define RCC_CSR_LSIRDY_Msk (0x1UL << RCC_CSR_LSIRDY_Pos) /*!< 0x00000002 */ +#define RCC_CSR_LSIRDY RCC_CSR_LSIRDY_Msk + +/******************** Bit definition for RCC_AHB1RSTR register **************/ +#define RCC_AHB1RSTR_GPDMA1RST_Pos (4U) +#define RCC_AHB1RSTR_GPDMA1RST_Msk (0x1UL << RCC_AHB1RSTR_GPDMA1RST_Pos) /*!< 0x00000010 */ +#define RCC_AHB1RSTR_GPDMA1RST RCC_AHB1RSTR_GPDMA1RST_Msk +#define RCC_AHB1RSTR_ADC12RST_Pos (5U) +#define RCC_AHB1RSTR_ADC12RST_Msk (0x1UL << RCC_AHB1RSTR_ADC12RST_Pos) /*!< 0x00000020 */ +#define RCC_AHB1RSTR_ADC12RST RCC_AHB1RSTR_ADC12RST_Msk +#define RCC_AHB1RSTR_ETH1RST_Pos (15U) +#define RCC_AHB1RSTR_ETH1RST_Msk (0x1UL << RCC_AHB1RSTR_ETH1RST_Pos) /*!< 0x00008000 */ +#define RCC_AHB1RSTR_ETH1RST RCC_AHB1RSTR_ETH1RST_Msk +#define RCC_AHB1RSTR_OTGHSRST_Pos (25U) +#define RCC_AHB1RSTR_OTGHSRST_Msk (0x1UL << RCC_AHB1RSTR_OTGHSRST_Pos) /*!< 0x02000000 */ +#define RCC_AHB1RSTR_OTGHSRST RCC_AHB1RSTR_OTGHSRST_Msk +#define RCC_AHB1RSTR_USBPHYCRST_Pos (26U) +#define RCC_AHB1RSTR_USBPHYCRST_Msk (0x1UL << RCC_AHB1RSTR_USBPHYCRST_Pos) /*!< 0x04000000 */ +#define RCC_AHB1RSTR_USBPHYCRST RCC_AHB1RSTR_USBPHYCRST_Msk +#define RCC_AHB1RSTR_OTGFSRST_Pos (27U) +#define RCC_AHB1RSTR_OTGFSRST_Msk (0x1UL << RCC_AHB1RSTR_OTGFSRST_Pos) /*!< 0x08000000 */ +#define RCC_AHB1RSTR_OTGFSRST RCC_AHB1RSTR_OTGFSRST_Msk +#define RCC_AHB1RSTR_ADF1RST_Pos (31U) +#define RCC_AHB1RSTR_ADF1RST_Msk (0x1UL << RCC_AHB1RSTR_ADF1RST_Pos) /*!< 0x80000000 */ +#define RCC_AHB1RSTR_ADF1RST RCC_AHB1RSTR_ADF1RST_Msk + +/******************** Bit definition for RCC_AHB2RSTR register **************/ +#define RCC_AHB2RSTR_PSSIRST_Pos (1U) +#define RCC_AHB2RSTR_PSSIRST_Msk (0x1UL << RCC_AHB2RSTR_PSSIRST_Pos) /*!< 0x00000002 */ +#define RCC_AHB2RSTR_PSSIRST RCC_AHB2RSTR_PSSIRST_Msk +#define RCC_AHB2RSTR_SDMMC2RST_Pos (9U) +#define RCC_AHB2RSTR_SDMMC2RST_Msk (0x1UL << RCC_AHB2RSTR_SDMMC2RST_Pos) /*!< 0x00000200 */ +#define RCC_AHB2RSTR_SDMMC2RST RCC_AHB2RSTR_SDMMC2RST_Msk +#define RCC_AHB2RSTR_CORDICRST_Pos (14U) +#define RCC_AHB2RSTR_CORDICRST_Msk (0x1UL << RCC_AHB2RSTR_CORDICRST_Pos) /*!< 0x00004000 */ +#define RCC_AHB2RSTR_CORDICRST RCC_AHB2RSTR_CORDICRST_Msk + +/******************** Bit definition for RCC_AHB3RSTR register **************/ +#define RCC_AHB3RSTR_RNGRST_Pos (0U) +#define RCC_AHB3RSTR_RNGRST_Msk (0x1UL << RCC_AHB3RSTR_RNGRST_Pos) /*!< 0x00000001 */ +#define RCC_AHB3RSTR_RNGRST RCC_AHB3RSTR_RNGRST_Msk +#define RCC_AHB3RSTR_HASHRST_Pos (1U) +#define RCC_AHB3RSTR_HASHRST_Msk (0x1UL << RCC_AHB3RSTR_HASHRST_Pos) /*!< 0x00000002 */ +#define RCC_AHB3RSTR_HASHRST RCC_AHB3RSTR_HASHRST_Msk +#define RCC_AHB3RSTR_CRYPRST_Pos (2U) +#define RCC_AHB3RSTR_CRYPRST_Msk (0x1UL << RCC_AHB3RSTR_CRYPRST_Pos) /*!< 0x00000004 */ +#define RCC_AHB3RSTR_CRYPRST RCC_AHB3RSTR_CRYPRST_Msk +#define RCC_AHB3RSTR_SAESRST_Pos (4U) +#define RCC_AHB3RSTR_SAESRST_Msk (0x1UL << RCC_AHB3RSTR_SAESRST_Pos) /*!< 0x00000010 */ +#define RCC_AHB3RSTR_SAESRST RCC_AHB3RSTR_SAESRST_Msk +#define RCC_AHB3RSTR_PKARST_Pos (6U) +#define RCC_AHB3RSTR_PKARST_Msk (0x1UL << RCC_AHB3RSTR_PKARST_Pos) /*!< 0x00000040 */ +#define RCC_AHB3RSTR_PKARST RCC_AHB3RSTR_PKARST_Msk + +/******************** Bit definition for RCC_AHB4RSTR register **************/ +#define RCC_AHB4RSTR_GPIOARST_Pos (0U) +#define RCC_AHB4RSTR_GPIOARST_Msk (0x1UL << RCC_AHB4RSTR_GPIOARST_Pos) /*!< 0x00000001 */ +#define RCC_AHB4RSTR_GPIOARST RCC_AHB4RSTR_GPIOARST_Msk +#define RCC_AHB4RSTR_GPIOBRST_Pos (1U) +#define RCC_AHB4RSTR_GPIOBRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOBRST_Pos) /*!< 0x00000002 */ +#define RCC_AHB4RSTR_GPIOBRST RCC_AHB4RSTR_GPIOBRST_Msk +#define RCC_AHB4RSTR_GPIOCRST_Pos (2U) +#define RCC_AHB4RSTR_GPIOCRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOCRST_Pos) /*!< 0x00000004 */ +#define RCC_AHB4RSTR_GPIOCRST RCC_AHB4RSTR_GPIOCRST_Msk +#define RCC_AHB4RSTR_GPIODRST_Pos (3U) +#define RCC_AHB4RSTR_GPIODRST_Msk (0x1UL << RCC_AHB4RSTR_GPIODRST_Pos) /*!< 0x00000008 */ +#define RCC_AHB4RSTR_GPIODRST RCC_AHB4RSTR_GPIODRST_Msk +#define RCC_AHB4RSTR_GPIOERST_Pos (4U) +#define RCC_AHB4RSTR_GPIOERST_Msk (0x1UL << RCC_AHB4RSTR_GPIOERST_Pos) /*!< 0x00000010 */ +#define RCC_AHB4RSTR_GPIOERST RCC_AHB4RSTR_GPIOERST_Msk +#define RCC_AHB4RSTR_GPIOFRST_Pos (5U) +#define RCC_AHB4RSTR_GPIOFRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOFRST_Pos) /*!< 0x00000020 */ +#define RCC_AHB4RSTR_GPIOFRST RCC_AHB4RSTR_GPIOFRST_Msk +#define RCC_AHB4RSTR_GPIOGRST_Pos (6U) +#define RCC_AHB4RSTR_GPIOGRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOGRST_Pos) /*!< 0x00000040 */ +#define RCC_AHB4RSTR_GPIOGRST RCC_AHB4RSTR_GPIOGRST_Msk +#define RCC_AHB4RSTR_GPIOHRST_Pos (7U) +#define RCC_AHB4RSTR_GPIOHRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOHRST_Pos) /*!< 0x00000080 */ +#define RCC_AHB4RSTR_GPIOHRST RCC_AHB4RSTR_GPIOHRST_Msk +#define RCC_AHB4RSTR_GPIOMRST_Pos (12U) +#define RCC_AHB4RSTR_GPIOMRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOMRST_Pos) /*!< 0x00001000 */ +#define RCC_AHB4RSTR_GPIOMRST RCC_AHB4RSTR_GPIOMRST_Msk +#define RCC_AHB4RSTR_GPIONRST_Pos (13U) +#define RCC_AHB4RSTR_GPIONRST_Msk (0x1UL << RCC_AHB4RSTR_GPIONRST_Pos) /*!< 0x00002000 */ +#define RCC_AHB4RSTR_GPIONRST RCC_AHB4RSTR_GPIONRST_Msk +#define RCC_AHB4RSTR_GPIOORST_Pos (14U) +#define RCC_AHB4RSTR_GPIOORST_Msk (0x1UL << RCC_AHB4RSTR_GPIOORST_Pos) /*!< 0x00004000 */ +#define RCC_AHB4RSTR_GPIOORST RCC_AHB4RSTR_GPIOORST_Msk +#define RCC_AHB4RSTR_GPIOPRST_Pos (15U) +#define RCC_AHB4RSTR_GPIOPRST_Msk (0x1UL << RCC_AHB4RSTR_GPIOPRST_Pos) /*!< 0x00008000 */ +#define RCC_AHB4RSTR_GPIOPRST RCC_AHB4RSTR_GPIOPRST_Msk +#define RCC_AHB4RSTR_CRCRST_Pos (19U) +#define RCC_AHB4RSTR_CRCRST_Msk (0x1UL << RCC_AHB4RSTR_CRCRST_Pos) /*!< 0x00080000 */ +#define RCC_AHB4RSTR_CRCRST RCC_AHB4RSTR_CRCRST_Msk + +/******************** Bit definition for RCC_AHB5RSTR register **************/ +#define RCC_AHB5RSTR_HPDMA1RST_Pos (0U) +#define RCC_AHB5RSTR_HPDMA1RST_Msk (0x1UL << RCC_AHB5RSTR_HPDMA1RST_Pos) /*!< 0x00000001 */ +#define RCC_AHB5RSTR_HPDMA1RST RCC_AHB5RSTR_HPDMA1RST_Msk +#define RCC_AHB5RSTR_DMA2DRST_Pos (1U) +#define RCC_AHB5RSTR_DMA2DRST_Msk (0x1UL << RCC_AHB5RSTR_DMA2DRST_Pos) /*!< 0x00000002 */ +#define RCC_AHB5RSTR_DMA2DRST RCC_AHB5RSTR_DMA2DRST_Msk +#define RCC_AHB5RSTR_JPEGRST_Pos (3U) +#define RCC_AHB5RSTR_JPEGRST_Msk (0x1UL << RCC_AHB5RSTR_JPEGRST_Pos) /*!< 0x00000008 */ +#define RCC_AHB5RSTR_JPEGRST RCC_AHB5RSTR_JPEGRST_Msk +#define RCC_AHB5RSTR_FMCRST_Pos (4U) +#define RCC_AHB5RSTR_FMCRST_Msk (0x1UL << RCC_AHB5RSTR_FMCRST_Pos) /*!< 0x00000010 */ +#define RCC_AHB5RSTR_FMCRST RCC_AHB5RSTR_FMCRST_Msk +#define RCC_AHB5RSTR_XSPI1RST_Pos (5U) +#define RCC_AHB5RSTR_XSPI1RST_Msk (0x1UL << RCC_AHB5RSTR_XSPI1RST_Pos) /*!< 0x00000020 */ +#define RCC_AHB5RSTR_XSPI1RST RCC_AHB5RSTR_XSPI1RST_Msk +#define RCC_AHB5RSTR_SDMMC1RST_Pos (8U) +#define RCC_AHB5RSTR_SDMMC1RST_Msk (0x1UL << RCC_AHB5RSTR_SDMMC1RST_Pos) /*!< 0x00000100 */ +#define RCC_AHB5RSTR_SDMMC1RST RCC_AHB5RSTR_SDMMC1RST_Msk +#define RCC_AHB5RSTR_XSPI2RST_Pos (12U) +#define RCC_AHB5RSTR_XSPI2RST_Msk (0x1UL << RCC_AHB5RSTR_XSPI2RST_Pos) /*!< 0x00001000 */ +#define RCC_AHB5RSTR_XSPI2RST RCC_AHB5RSTR_XSPI2RST_Msk +#define RCC_AHB5RSTR_XSPIMRST_Pos (14U) +#define RCC_AHB5RSTR_XSPIMRST_Msk (0x1UL << RCC_AHB5RSTR_XSPIMRST_Pos) /*!< 0x00004000 */ +#define RCC_AHB5RSTR_XSPIMRST RCC_AHB5RSTR_XSPIMRST_Msk +#define RCC_AHB5RSTR_GFXMMURST_Pos (19U) +#define RCC_AHB5RSTR_GFXMMURST_Msk (0x1UL << RCC_AHB5RSTR_GFXMMURST_Pos) /*!< 0x00080000 */ +#define RCC_AHB5RSTR_GFXMMURST RCC_AHB5RSTR_GFXMMURST_Msk +#define RCC_AHB5RSTR_GPU2DRST_Pos (20U) +#define RCC_AHB5RSTR_GPU2DRST_Msk (0x1UL << RCC_AHB5RSTR_GPU2DRST_Pos) /*!< 0x00100000 */ +#define RCC_AHB5RSTR_GPU2DRST RCC_AHB5RSTR_GPU2DRST_Msk + +/******************** Bit definition for RCC_APB1RSTR1 register *************/ +#define RCC_APB1RSTR1_TIM2RST_Pos (0U) +#define RCC_APB1RSTR1_TIM2RST_Msk (0x1UL << RCC_APB1RSTR1_TIM2RST_Pos) /*!< 0x00000001 */ +#define RCC_APB1RSTR1_TIM2RST RCC_APB1RSTR1_TIM2RST_Msk +#define RCC_APB1RSTR1_TIM3RST_Pos (1U) +#define RCC_APB1RSTR1_TIM3RST_Msk (0x1UL << RCC_APB1RSTR1_TIM3RST_Pos) /*!< 0x00000002 */ +#define RCC_APB1RSTR1_TIM3RST RCC_APB1RSTR1_TIM3RST_Msk +#define RCC_APB1RSTR1_TIM4RST_Pos (2U) +#define RCC_APB1RSTR1_TIM4RST_Msk (0x1UL << RCC_APB1RSTR1_TIM4RST_Pos) /*!< 0x00000004 */ +#define RCC_APB1RSTR1_TIM4RST RCC_APB1RSTR1_TIM4RST_Msk +#define RCC_APB1RSTR1_TIM5RST_Pos (3U) +#define RCC_APB1RSTR1_TIM5RST_Msk (0x1UL << RCC_APB1RSTR1_TIM5RST_Pos) /*!< 0x00000008 */ +#define RCC_APB1RSTR1_TIM5RST RCC_APB1RSTR1_TIM5RST_Msk +#define RCC_APB1RSTR1_TIM6RST_Pos (4U) +#define RCC_APB1RSTR1_TIM6RST_Msk (0x1UL << RCC_APB1RSTR1_TIM6RST_Pos) /*!< 0x00000010 */ +#define RCC_APB1RSTR1_TIM6RST RCC_APB1RSTR1_TIM6RST_Msk +#define RCC_APB1RSTR1_TIM7RST_Pos (5U) +#define RCC_APB1RSTR1_TIM7RST_Msk (0x1UL << RCC_APB1RSTR1_TIM7RST_Pos) /*!< 0x00000020 */ +#define RCC_APB1RSTR1_TIM7RST RCC_APB1RSTR1_TIM7RST_Msk +#define RCC_APB1RSTR1_TIM12RST_Pos (6U) +#define RCC_APB1RSTR1_TIM12RST_Msk (0x1UL << RCC_APB1RSTR1_TIM12RST_Pos) /*!< 0x00000040 */ +#define RCC_APB1RSTR1_TIM12RST RCC_APB1RSTR1_TIM12RST_Msk +#define RCC_APB1RSTR1_TIM13RST_Pos (7U) +#define RCC_APB1RSTR1_TIM13RST_Msk (0x1UL << RCC_APB1RSTR1_TIM13RST_Pos) /*!< 0x00000080 */ +#define RCC_APB1RSTR1_TIM13RST RCC_APB1RSTR1_TIM13RST_Msk +#define RCC_APB1RSTR1_TIM14RST_Pos (8U) +#define RCC_APB1RSTR1_TIM14RST_Msk (0x1UL << RCC_APB1RSTR1_TIM14RST_Pos) /*!< 0x00000100 */ +#define RCC_APB1RSTR1_TIM14RST RCC_APB1RSTR1_TIM14RST_Msk +#define RCC_APB1RSTR1_LPTIM1RST_Pos (9U) +#define RCC_APB1RSTR1_LPTIM1RST_Msk (0x1UL << RCC_APB1RSTR1_LPTIM1RST_Pos) /*!< 0x00000200 */ +#define RCC_APB1RSTR1_LPTIM1RST RCC_APB1RSTR1_LPTIM1RST_Msk +#define RCC_APB1RSTR1_SPI2RST_Pos (14U) +#define RCC_APB1RSTR1_SPI2RST_Msk (0x1UL << RCC_APB1RSTR1_SPI2RST_Pos) /*!< 0x00004000 */ +#define RCC_APB1RSTR1_SPI2RST RCC_APB1RSTR1_SPI2RST_Msk +#define RCC_APB1RSTR1_SPI3RST_Pos (15U) +#define RCC_APB1RSTR1_SPI3RST_Msk (0x1UL << RCC_APB1RSTR1_SPI3RST_Pos) /*!< 0x00008000 */ +#define RCC_APB1RSTR1_SPI3RST RCC_APB1RSTR1_SPI3RST_Msk +#define RCC_APB1RSTR1_SPDIFRXRST_Pos (16U) +#define RCC_APB1RSTR1_SPDIFRXRST_Msk (0x1UL << RCC_APB1RSTR1_SPDIFRXRST_Pos) /*!< 0x00010000 */ +#define RCC_APB1RSTR1_SPDIFRXRST RCC_APB1RSTR1_SPDIFRXRST_Msk +#define RCC_APB1RSTR1_USART2RST_Pos (17U) +#define RCC_APB1RSTR1_USART2RST_Msk (0x1UL << RCC_APB1RSTR1_USART2RST_Pos) /*!< 0x00020000 */ +#define RCC_APB1RSTR1_USART2RST RCC_APB1RSTR1_USART2RST_Msk +#define RCC_APB1RSTR1_USART3RST_Pos (18U) +#define RCC_APB1RSTR1_USART3RST_Msk (0x1UL << RCC_APB1RSTR1_USART3RST_Pos) /*!< 0x00040000 */ +#define RCC_APB1RSTR1_USART3RST RCC_APB1RSTR1_USART3RST_Msk +#define RCC_APB1RSTR1_UART4RST_Pos (19U) +#define RCC_APB1RSTR1_UART4RST_Msk (0x1UL << RCC_APB1RSTR1_UART4RST_Pos) /*!< 0x00080000 */ +#define RCC_APB1RSTR1_UART4RST RCC_APB1RSTR1_UART4RST_Msk +#define RCC_APB1RSTR1_UART5RST_Pos (20U) +#define RCC_APB1RSTR1_UART5RST_Msk (0x1UL << RCC_APB1RSTR1_UART5RST_Pos) /*!< 0x00100000 */ +#define RCC_APB1RSTR1_UART5RST RCC_APB1RSTR1_UART5RST_Msk +#define RCC_APB1RSTR1_I2C1_I3C1RST_Pos (21U) +#define RCC_APB1RSTR1_I2C1_I3C1RST_Msk (0x1UL << RCC_APB1RSTR1_I2C1_I3C1RST_Pos) /*!< 0x00200000 */ +#define RCC_APB1RSTR1_I2C1_I3C1RST RCC_APB1RSTR1_I2C1_I3C1RST_Msk +#define RCC_APB1RSTR1_I2C2RST_Pos (22U) +#define RCC_APB1RSTR1_I2C2RST_Msk (0x1UL << RCC_APB1RSTR1_I2C2RST_Pos) /*!< 0x00400000 */ +#define RCC_APB1RSTR1_I2C2RST RCC_APB1RSTR1_I2C2RST_Msk +#define RCC_APB1RSTR1_I2C3RST_Pos (23U) +#define RCC_APB1RSTR1_I2C3RST_Msk (0x1UL << RCC_APB1RSTR1_I2C3RST_Pos) /*!< 0x00800000 */ +#define RCC_APB1RSTR1_I2C3RST RCC_APB1RSTR1_I2C3RST_Msk +#define RCC_APB1RSTR1_CECRST_Pos (27U) +#define RCC_APB1RSTR1_CECRST_Msk (0x1UL << RCC_APB1RSTR1_CECRST_Pos) /*!< 0x08000000 */ +#define RCC_APB1RSTR1_CECRST RCC_APB1RSTR1_CECRST_Msk +#define RCC_APB1RSTR1_UART7RST_Pos (30U) +#define RCC_APB1RSTR1_UART7RST_Msk (0x1UL << RCC_APB1RSTR1_UART7RST_Pos) /*!< 0x40000000 */ +#define RCC_APB1RSTR1_UART7RST RCC_APB1RSTR1_UART7RST_Msk +#define RCC_APB1RSTR1_UART8RST_Pos (31U) +#define RCC_APB1RSTR1_UART8RST_Msk (0x1UL << RCC_APB1RSTR1_UART8RST_Pos) /*!< 0x80000000 */ +#define RCC_APB1RSTR1_UART8RST RCC_APB1RSTR1_UART8RST_Msk + +/******************** Bit definition for RCC_APB1RSTR2 register *************/ +#define RCC_APB1RSTR2_CRSRST_Pos (1U) +#define RCC_APB1RSTR2_CRSRST_Msk (0x1UL << RCC_APB1RSTR2_CRSRST_Pos) /*!< 0x00000002 */ +#define RCC_APB1RSTR2_CRSRST RCC_APB1RSTR2_CRSRST_Msk +#define RCC_APB1RSTR2_MDIOSRST_Pos (5U) +#define RCC_APB1RSTR2_MDIOSRST_Msk (0x1UL << RCC_APB1RSTR2_MDIOSRST_Pos) /*!< 0x00000020 */ +#define RCC_APB1RSTR2_MDIOSRST RCC_APB1RSTR2_MDIOSRST_Msk +#define RCC_APB1RSTR2_FDCANRST_Pos (8U) +#define RCC_APB1RSTR2_FDCANRST_Msk (0x1UL << RCC_APB1RSTR2_FDCANRST_Pos) /*!< 0x00000100 */ +#define RCC_APB1RSTR2_FDCANRST RCC_APB1RSTR2_FDCANRST_Msk +#define RCC_APB1RSTR2_UCPD1RST_Pos (27U) +#define RCC_APB1RSTR2_UCPD1RST_Msk (0x1UL << RCC_APB1RSTR2_UCPD1RST_Pos) /*!< 0x08000000 */ +#define RCC_APB1RSTR2_UCPD1RST RCC_APB1RSTR2_UCPD1RST_Msk + +/******************** Bit definition for RCC_APB2RSTR register **************/ +#define RCC_APB2RSTR_TIM1RST_Pos (0U) +#define RCC_APB2RSTR_TIM1RST_Msk (0x1UL << RCC_APB2RSTR_TIM1RST_Pos) /*!< 0x00000001 */ +#define RCC_APB2RSTR_TIM1RST RCC_APB2RSTR_TIM1RST_Msk +#define RCC_APB2RSTR_USART1RST_Pos (4U) +#define RCC_APB2RSTR_USART1RST_Msk (0x1UL << RCC_APB2RSTR_USART1RST_Pos) /*!< 0x00000010 */ +#define RCC_APB2RSTR_USART1RST RCC_APB2RSTR_USART1RST_Msk +#define RCC_APB2RSTR_SPI1RST_Pos (12U) +#define RCC_APB2RSTR_SPI1RST_Msk (0x1UL << RCC_APB2RSTR_SPI1RST_Pos) /*!< 0x00001000 */ +#define RCC_APB2RSTR_SPI1RST RCC_APB2RSTR_SPI1RST_Msk +#define RCC_APB2RSTR_SPI4RST_Pos (13U) +#define RCC_APB2RSTR_SPI4RST_Msk (0x1UL << RCC_APB2RSTR_SPI4RST_Pos) /*!< 0x00002000 */ +#define RCC_APB2RSTR_SPI4RST RCC_APB2RSTR_SPI4RST_Msk +#define RCC_APB2RSTR_TIM15RST_Pos (16U) +#define RCC_APB2RSTR_TIM15RST_Msk (0x1UL << RCC_APB2RSTR_TIM15RST_Pos) /*!< 0x00010000 */ +#define RCC_APB2RSTR_TIM15RST RCC_APB2RSTR_TIM15RST_Msk +#define RCC_APB2RSTR_TIM16RST_Pos (17U) +#define RCC_APB2RSTR_TIM16RST_Msk (0x1UL << RCC_APB2RSTR_TIM16RST_Pos) /*!< 0x00020000 */ +#define RCC_APB2RSTR_TIM16RST RCC_APB2RSTR_TIM16RST_Msk +#define RCC_APB2RSTR_TIM17RST_Pos (18U) +#define RCC_APB2RSTR_TIM17RST_Msk (0x1UL << RCC_APB2RSTR_TIM17RST_Pos) /*!< 0x00040000 */ +#define RCC_APB2RSTR_TIM17RST RCC_APB2RSTR_TIM17RST_Msk +#define RCC_APB2RSTR_TIM9RST_Pos (19U) +#define RCC_APB2RSTR_TIM9RST_Msk (0x1UL << RCC_APB2RSTR_TIM9RST_Pos) /*!< 0x00080000 */ +#define RCC_APB2RSTR_TIM9RST RCC_APB2RSTR_TIM9RST_Msk +#define RCC_APB2RSTR_SPI5RST_Pos (20U) +#define RCC_APB2RSTR_SPI5RST_Msk (0x1UL << RCC_APB2RSTR_SPI5RST_Pos) /*!< 0x00100000 */ +#define RCC_APB2RSTR_SPI5RST RCC_APB2RSTR_SPI5RST_Msk +#define RCC_APB2RSTR_SAI1RST_Pos (22U) +#define RCC_APB2RSTR_SAI1RST_Msk (0x1UL << RCC_APB2RSTR_SAI1RST_Pos) /*!< 0x00400000 */ +#define RCC_APB2RSTR_SAI1RST RCC_APB2RSTR_SAI1RST_Msk +#define RCC_APB2RSTR_SAI2RST_Pos (23U) +#define RCC_APB2RSTR_SAI2RST_Msk (0x1UL << RCC_APB2RSTR_SAI2RST_Pos) /*!< 0x00800000 */ +#define RCC_APB2RSTR_SAI2RST RCC_APB2RSTR_SAI2RST_Msk + +/******************** Bit definition for RCC_APB4RSTR register **************/ +#define RCC_APB4RSTR_SBSRST_Pos (1U) +#define RCC_APB4RSTR_SBSRST_Msk (0x1UL << RCC_APB4RSTR_SBSRST_Pos) /*!< 0x00000002 */ +#define RCC_APB4RSTR_SBSRST RCC_APB4RSTR_SBSRST_Msk +#define RCC_APB4RSTR_LPUART1RST_Pos (3U) +#define RCC_APB4RSTR_LPUART1RST_Msk (0x1UL << RCC_APB4RSTR_LPUART1RST_Pos) /*!< 0x00000008 */ +#define RCC_APB4RSTR_LPUART1RST RCC_APB4RSTR_LPUART1RST_Msk +#define RCC_APB4RSTR_SPI6RST_Pos (5U) +#define RCC_APB4RSTR_SPI6RST_Msk (0x1UL << RCC_APB4RSTR_SPI6RST_Pos) /*!< 0x00000020 */ +#define RCC_APB4RSTR_SPI6RST RCC_APB4RSTR_SPI6RST_Msk +#define RCC_APB4RSTR_LPTIM2RST_Pos (9U) +#define RCC_APB4RSTR_LPTIM2RST_Msk (0x1UL << RCC_APB4RSTR_LPTIM2RST_Pos) /*!< 0x00000200 */ +#define RCC_APB4RSTR_LPTIM2RST RCC_APB4RSTR_LPTIM2RST_Msk +#define RCC_APB4RSTR_LPTIM3RST_Pos (10U) +#define RCC_APB4RSTR_LPTIM3RST_Msk (0x1UL << RCC_APB4RSTR_LPTIM3RST_Pos) /*!< 0x00000400 */ +#define RCC_APB4RSTR_LPTIM3RST RCC_APB4RSTR_LPTIM3RST_Msk +#define RCC_APB4RSTR_LPTIM4RST_Pos (11U) +#define RCC_APB4RSTR_LPTIM4RST_Msk (0x1UL << RCC_APB4RSTR_LPTIM4RST_Pos) /*!< 0x00000800 */ +#define RCC_APB4RSTR_LPTIM4RST RCC_APB4RSTR_LPTIM4RST_Msk +#define RCC_APB4RSTR_LPTIM5RST_Pos (12U) +#define RCC_APB4RSTR_LPTIM5RST_Msk (0x1UL << RCC_APB4RSTR_LPTIM5RST_Pos) /*!< 0x00001000 */ +#define RCC_APB4RSTR_LPTIM5RST RCC_APB4RSTR_LPTIM5RST_Msk +#define RCC_APB4RSTR_VREFRST_Pos (15U) +#define RCC_APB4RSTR_VREFRST_Msk (0x1UL << RCC_APB4RSTR_VREFRST_Pos) /*!< 0x00008000 */ +#define RCC_APB4RSTR_VREFRST RCC_APB4RSTR_VREFRST_Msk +#define RCC_APB4RSTR_DTSRST_Pos (26U) +#define RCC_APB4RSTR_DTSRST_Msk (0x1UL << RCC_APB4RSTR_DTSRST_Pos) /*!< 0x04000000 */ +#define RCC_APB4RSTR_DTSRST RCC_APB4RSTR_DTSRST_Msk + +/******************** Bit definition for RCC_APB5RSTR register **************/ +#define RCC_APB5RSTR_LTDCRST_Pos (1U) +#define RCC_APB5RSTR_LTDCRST_Msk (0x1UL << RCC_APB5RSTR_LTDCRST_Pos) /*!< 0x00000002 */ +#define RCC_APB5RSTR_LTDCRST RCC_APB5RSTR_LTDCRST_Msk +#define RCC_APB5RSTR_DCMIPPRST_Pos (2U) +#define RCC_APB5RSTR_DCMIPPRST_Msk (0x1UL << RCC_APB5RSTR_DCMIPPRST_Pos) /*!< 0x00000004 */ +#define RCC_APB5RSTR_DCMIPPRST RCC_APB5RSTR_DCMIPPRST_Msk +#define RCC_APB5RSTR_GFXTIMRST_Pos (4U) +#define RCC_APB5RSTR_GFXTIMRST_Msk (0x1UL << RCC_APB5RSTR_GFXTIMRST_Pos) /*!< 0x00000010 */ +#define RCC_APB5RSTR_GFXTIMRST RCC_APB5RSTR_GFXTIMRST_Msk + +/******************** Bit definition for RCC_CKGDISR register ***************/ +#define RCC_CKGDISR_AXICKG_Pos (0U) +#define RCC_CKGDISR_AXICKG_Msk (0x1UL << RCC_CKGDISR_AXICKG_Pos) /*!< 0x00000001 */ +#define RCC_CKGDISR_AXICKG RCC_CKGDISR_AXICKG_Msk +#define RCC_CKGDISR_AHBMCKG_Pos (1U) +#define RCC_CKGDISR_AHBMCKG_Msk (0x1UL << RCC_CKGDISR_AHBMCKG_Pos) /*!< 0x00000002 */ +#define RCC_CKGDISR_AHBMCKG RCC_CKGDISR_AHBMCKG_Msk +#define RCC_CKGDISR_SDMMC1CKG_Pos (2U) +#define RCC_CKGDISR_SDMMC1CKG_Msk (0x1UL << RCC_CKGDISR_SDMMC1CKG_Pos) /*!< 0x00000004 */ +#define RCC_CKGDISR_SDMMC1CKG RCC_CKGDISR_SDMMC1CKG_Msk +#define RCC_CKGDISR_HPDMA1CKG_Pos (3U) +#define RCC_CKGDISR_HPDMA1CKG_Msk (0x1UL << RCC_CKGDISR_HPDMA1CKG_Pos) /*!< 0x00000008 */ +#define RCC_CKGDISR_HPDMA1CKG RCC_CKGDISR_HPDMA1CKG_Msk +#define RCC_CKGDISR_CPUCKG_Pos (4U) +#define RCC_CKGDISR_CPUCKG_Msk (0x1UL << RCC_CKGDISR_CPUCKG_Pos) /*!< 0x00000010 */ +#define RCC_CKGDISR_CPUCKG RCC_CKGDISR_CPUCKG_Msk +#define RCC_CKGDISR_GPU2DS0CKG_Pos (5U) +#define RCC_CKGDISR_GPU2DS0CKG_Msk (0x1UL << RCC_CKGDISR_GPU2DS0CKG_Pos) /*!< 0x00000020 */ +#define RCC_CKGDISR_GPU2DS0CKG RCC_CKGDISR_GPU2DS0CKG_Msk +#define RCC_CKGDISR_GPU2DS1CKG_Pos (6U) +#define RCC_CKGDISR_GPU2DS1CKG_Msk (0x1UL << RCC_CKGDISR_GPU2DS1CKG_Pos) /*!< 0x00000040 */ +#define RCC_CKGDISR_GPU2DS1CKG RCC_CKGDISR_GPU2DS1CKG_Msk +#define RCC_CKGDISR_GPU2DCLCKG_Pos (7U) +#define RCC_CKGDISR_GPU2DCLCKG_Msk (0x1UL << RCC_CKGDISR_GPU2DCLCKG_Pos) /*!< 0x00000080 */ +#define RCC_CKGDISR_GPU2DCLCKG RCC_CKGDISR_GPU2DCLCKG_Msk +#define RCC_CKGDISR_DCMIPPCKG_Pos (8U) +#define RCC_CKGDISR_DCMIPPCKG_Msk (0x1UL << RCC_CKGDISR_DCMIPPCKG_Pos) /*!< 0x00000100 */ +#define RCC_CKGDISR_DCMIPPCKG RCC_CKGDISR_DCMIPPCKG_Msk +#define RCC_CKGDISR_DMA2DCKG_Pos (9U) +#define RCC_CKGDISR_DMA2DCKG_Msk (0x1UL << RCC_CKGDISR_DMA2DCKG_Pos) /*!< 0x00000200 */ +#define RCC_CKGDISR_DMA2DCKG RCC_CKGDISR_DMA2DCKG_Msk +#define RCC_CKGDISR_GFXMMUSCKG_Pos (10U) +#define RCC_CKGDISR_GFXMMUSCKG_Msk (0x1UL << RCC_CKGDISR_GFXMMUSCKG_Pos) /*!< 0x00000400 */ +#define RCC_CKGDISR_GFXMMUSCKG RCC_CKGDISR_GFXMMUSCKG_Msk +#define RCC_CKGDISR_LTDCCKG_Pos (11U) +#define RCC_CKGDISR_LTDCCKG_Msk (0x1UL << RCC_CKGDISR_LTDCCKG_Pos) /*!< 0x00000800 */ +#define RCC_CKGDISR_LTDCCKG RCC_CKGDISR_LTDCCKG_Msk +#define RCC_CKGDISR_GFXMMUMCKG_Pos (12U) +#define RCC_CKGDISR_GFXMMUMCKG_Msk (0x1UL << RCC_CKGDISR_GFXMMUMCKG_Pos) /*!< 0x00001000 */ +#define RCC_CKGDISR_GFXMMUMCKG RCC_CKGDISR_GFXMMUMCKG_Msk +#define RCC_CKGDISR_AHBSCKG_Pos (13U) +#define RCC_CKGDISR_AHBSCKG_Msk (0x1UL << RCC_CKGDISR_AHBSCKG_Pos) /*!< 0x00002000 */ +#define RCC_CKGDISR_AHBSCKG RCC_CKGDISR_AHBSCKG_Msk +#define RCC_CKGDISR_FMCCKG_Pos (14U) +#define RCC_CKGDISR_FMCCKG_Msk (0x1UL << RCC_CKGDISR_FMCCKG_Pos) /*!< 0x00004000 */ +#define RCC_CKGDISR_FMCCKG RCC_CKGDISR_FMCCKG_Msk +#define RCC_CKGDISR_XSPI1CKG_Pos (15U) +#define RCC_CKGDISR_XSPI1CKG_Msk (0x1UL << RCC_CKGDISR_XSPI1CKG_Pos) /*!< 0x00008000 */ +#define RCC_CKGDISR_XSPI1CKG RCC_CKGDISR_XSPI1CKG_Msk +#define RCC_CKGDISR_XSPI2CKG_Pos (16U) +#define RCC_CKGDISR_XSPI2CKG_Msk (0x1UL << RCC_CKGDISR_XSPI2CKG_Pos) /*!< 0x00010000 */ +#define RCC_CKGDISR_XSPI2CKG RCC_CKGDISR_XSPI2CKG_Msk +#define RCC_CKGDISR_AXISRAM4CKG_Pos (17U) +#define RCC_CKGDISR_AXISRAM4CKG_Msk (0x1UL << RCC_CKGDISR_AXISRAM4CKG_Pos) /*!< 0x00020000 */ +#define RCC_CKGDISR_AXISRAM4CKG RCC_CKGDISR_AXISRAM4CKG_Msk +#define RCC_CKGDISR_AXISRAM3CKG_Pos (18U) +#define RCC_CKGDISR_AXISRAM3CKG_Msk (0x1UL << RCC_CKGDISR_AXISRAM3CKG_Pos) /*!< 0x00040000 */ +#define RCC_CKGDISR_AXISRAM3CKG RCC_CKGDISR_AXISRAM3CKG_Msk +#define RCC_CKGDISR_AXISRAM2CKG_Pos (19U) +#define RCC_CKGDISR_AXISRAM2CKG_Msk (0x1UL << RCC_CKGDISR_AXISRAM2CKG_Pos) /*!< 0x00080000 */ +#define RCC_CKGDISR_AXISRAM2CKG RCC_CKGDISR_AXISRAM2CKG_Msk +#define RCC_CKGDISR_AXISRAM1CKG_Pos (20U) +#define RCC_CKGDISR_AXISRAM1CKG_Msk (0x1UL << RCC_CKGDISR_AXISRAM1CKG_Pos) /*!< 0x00100000 */ +#define RCC_CKGDISR_AXISRAM1CKG RCC_CKGDISR_AXISRAM1CKG_Msk +#define RCC_CKGDISR_FLASHCKG_Pos (21U) +#define RCC_CKGDISR_FLASHCKG_Msk (0x1UL << RCC_CKGDISR_FLASHCKG_Pos) /*!< 0x00200000 */ +#define RCC_CKGDISR_FLASHCKG RCC_CKGDISR_FLASHCKG_Msk +#define RCC_CKGDISR_EXTICKG_Pos (30U) +#define RCC_CKGDISR_EXTICKG_Msk (0x1UL << RCC_CKGDISR_EXTICKG_Pos) /*!< 0x40000000 */ +#define RCC_CKGDISR_EXTICKG RCC_CKGDISR_EXTICKG_Msk +#define RCC_CKGDISR_JTAGCKG_Pos (31U) +#define RCC_CKGDISR_JTAGCKG_Msk (0x1UL << RCC_CKGDISR_JTAGCKG_Pos) /*!< 0x80000000 */ +#define RCC_CKGDISR_JTAGCKG RCC_CKGDISR_JTAGCKG_Msk + +/******************** Bit definition for RCC_PLL1DIVR2 register *************/ +#define RCC_PLL1DIVR2_DIVS_Pos (0U) +#define RCC_PLL1DIVR2_DIVS_Msk (0x7UL << RCC_PLL1DIVR2_DIVS_Pos) /*!< 0x00000007 */ +#define RCC_PLL1DIVR2_DIVS RCC_PLL1DIVR2_DIVS_Msk /*!< DIVS1[2:0] bits: PLL1 DIVS division factor */ +#define RCC_PLL1DIVR2_DIVS_0 (0x1UL << RCC_PLL1DIVR2_DIVS_Pos) /*!< 0x00000001 */ +#define RCC_PLL1DIVR2_DIVS_1 (0x2UL << RCC_PLL1DIVR2_DIVS_Pos) /*!< 0x00000002 */ +#define RCC_PLL1DIVR2_DIVS_2 (0x4UL << RCC_PLL1DIVR2_DIVS_Pos) /*!< 0x00000004 */ + +/******************** Bit definition for RCC_PLL2DIVR2 register *************/ +#define RCC_PLL2DIVR2_DIVS_Pos (0U) +#define RCC_PLL2DIVR2_DIVS_Msk (0x7UL << RCC_PLL2DIVR2_DIVS_Pos) /*!< 0x00000007 */ +#define RCC_PLL2DIVR2_DIVS RCC_PLL2DIVR2_DIVS_Msk /*!< DIVS2[2:0] bits: PLL2 DIVS division factor */ +#define RCC_PLL2DIVR2_DIVS_0 (0x1UL << RCC_PLL2DIVR2_DIVS_Pos) /*!< 0x00000001 */ +#define RCC_PLL2DIVR2_DIVS_1 (0x2UL << RCC_PLL2DIVR2_DIVS_Pos) /*!< 0x00000002 */ +#define RCC_PLL2DIVR2_DIVS_2 (0x4UL << RCC_PLL2DIVR2_DIVS_Pos) /*!< 0x00000004 */ + +#define RCC_PLL2DIVR2_DIVT_Pos (8U) +#define RCC_PLL2DIVR2_DIVT_Msk (0x7UL << RCC_PLL2DIVR2_DIVT_Pos) /*!< 0x00000700 */ +#define RCC_PLL2DIVR2_DIVT RCC_PLL2DIVR2_DIVT_Msk /*!< DIVT2[2:0] bits: PLL2 DIVT division factor */ +#define RCC_PLL2DIVR2_DIVT_0 (0x1UL << RCC_PLL2DIVR2_DIVT_Pos) /*!< 0x00000100 */ +#define RCC_PLL2DIVR2_DIVT_1 (0x2UL << RCC_PLL2DIVR2_DIVT_Pos) /*!< 0x00000200 */ +#define RCC_PLL2DIVR2_DIVT_2 (0x4UL << RCC_PLL2DIVR2_DIVT_Pos) /*!< 0x00000400 */ + +/******************** Bit definition for RCC_PLL3DIVR2 register *************/ +#define RCC_PLL3DIVR2_DIVS_Pos (0U) +#define RCC_PLL3DIVR2_DIVS_Msk (0x7UL << RCC_PLL3DIVR2_DIVS_Pos) /*!< 0x00000007 */ +#define RCC_PLL3DIVR2_DIVS RCC_PLL3DIVR2_DIVS_Msk /*!< DIVS3[2:0] bits: PLL3 DIVS division factor */ +#define RCC_PLL3DIVR2_DIVS_0 (0x1UL << RCC_PLL3DIVR2_DIVS_Pos) /*!< 0x00000001 */ +#define RCC_PLL3DIVR2_DIVS_1 (0x2UL << RCC_PLL3DIVR2_DIVS_Pos) /*!< 0x00000002 */ +#define RCC_PLL3DIVR2_DIVS_2 (0x4UL << RCC_PLL3DIVR2_DIVS_Pos) /*!< 0x00000004 */ + +/******************** Bit definition for RCC_PLL1SSCGR register *************/ +#define RCC_PLL1SSCGR_MODPER_Pos (0U) +#define RCC_PLL1SSCGR_MODPER_Msk (0x1FFFUL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00001FFF */ +#define RCC_PLL1SSCGR_MODPER RCC_PLL1SSCGR_MODPER_Msk /*!< MODPER[12:0] bits: Modulation Period Adjustment */ +#define RCC_PLL1SSCGR_MODPER_0 (0x0001UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000001 */ +#define RCC_PLL1SSCGR_MODPER_1 (0x0002UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000002 */ +#define RCC_PLL1SSCGR_MODPER_2 (0x0004UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000004 */ +#define RCC_PLL1SSCGR_MODPER_3 (0x0008UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000008 */ +#define RCC_PLL1SSCGR_MODPER_4 (0x0010UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000010 */ +#define RCC_PLL1SSCGR_MODPER_5 (0x0020UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000020 */ +#define RCC_PLL1SSCGR_MODPER_6 (0x0040UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000040 */ +#define RCC_PLL1SSCGR_MODPER_7 (0x0080UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000080 */ +#define RCC_PLL1SSCGR_MODPER_8 (0x0100UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000100 */ +#define RCC_PLL1SSCGR_MODPER_9 (0x0200UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000200 */ +#define RCC_PLL1SSCGR_MODPER_10 (0x0400UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000400 */ +#define RCC_PLL1SSCGR_MODPER_11 (0x0800UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00000800 */ +#define RCC_PLL1SSCGR_MODPER_12 (0x1000UL << RCC_PLL1SSCGR_MODPER_Pos) /*!< 0x00001000 */ +#define RCC_PLL1SSCGR_TPDFNDIS_Pos (13U) +#define RCC_PLL1SSCGR_TPDFNDIS_Msk (0x1UL << RCC_PLL1SSCGR_TPDFNDIS_Pos) /*!< 0x00002000 */ +#define RCC_PLL1SSCGR_TPDFNDIS RCC_PLL1SSCGR_TPDFNDIS_Msk +#define RCC_PLL1SSCGR_RPDFNDIS_Pos (14U) +#define RCC_PLL1SSCGR_RPDFNDIS_Msk (0x1UL << RCC_PLL1SSCGR_RPDFNDIS_Pos) /*!< 0x00004000 */ +#define RCC_PLL1SSCGR_RPDFNDIS RCC_PLL1SSCGR_RPDFNDIS_Msk +#define RCC_PLL1SSCGR_SPREADSEL_Pos (15U) +#define RCC_PLL1SSCGR_SPREADSEL_Msk (0x1UL << RCC_PLL1SSCGR_SPREADSEL_Pos) /*!< 0x00008000 */ +#define RCC_PLL1SSCGR_SPREADSEL RCC_PLL1SSCGR_SPREADSEL_Msk +#define RCC_PLL1SSCGR_INCSTEP_Pos (16U) +#define RCC_PLL1SSCGR_INCSTEP_Msk (0x7FFFUL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x7FFF0000 */ +#define RCC_PLL1SSCGR_INCSTEP RCC_PLL1SSCGR_INCSTEP_Msk /*!< INCSTEP[14:0] bits: Modulation Depth Adjustment */ +#define RCC_PLL1SSCGR_INCSTEP_0 (0x0001UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00010000 */ +#define RCC_PLL1SSCGR_INCSTEP_1 (0x0002UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00020000 */ +#define RCC_PLL1SSCGR_INCSTEP_2 (0x0004UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00040000 */ +#define RCC_PLL1SSCGR_INCSTEP_3 (0x0008UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00080000 */ +#define RCC_PLL1SSCGR_INCSTEP_4 (0x0010UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00100000 */ +#define RCC_PLL1SSCGR_INCSTEP_5 (0x0020UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00200000 */ +#define RCC_PLL1SSCGR_INCSTEP_6 (0x0040UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00400000 */ +#define RCC_PLL1SSCGR_INCSTEP_7 (0x0080UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x00800000 */ +#define RCC_PLL1SSCGR_INCSTEP_8 (0x0100UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x01000000 */ +#define RCC_PLL1SSCGR_INCSTEP_9 (0x0200UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x02000000 */ +#define RCC_PLL1SSCGR_INCSTEP_10 (0x0400UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x04000000 */ +#define RCC_PLL1SSCGR_INCSTEP_11 (0x0800UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x08000000 */ +#define RCC_PLL1SSCGR_INCSTEP_12 (0x1000UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x10000000 */ +#define RCC_PLL1SSCGR_INCSTEP_13 (0x2000UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x20000000 */ +#define RCC_PLL1SSCGR_INCSTEP_14 (0x4000UL << RCC_PLL1SSCGR_INCSTEP_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_PLL2SSCGR register *************/ +#define RCC_PLL2SSCGR_MODPER_Pos (0U) +#define RCC_PLL2SSCGR_MODPER_Msk (0x1FFFUL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00001FFF */ +#define RCC_PLL2SSCGR_MODPER RCC_PLL2SSCGR_MODPER_Msk /*!< MODPER[12:0] bits: Modulation Period Adjustment */ +#define RCC_PLL2SSCGR_MODPER_0 (0x0001UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000001 */ +#define RCC_PLL2SSCGR_MODPER_1 (0x0002UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000002 */ +#define RCC_PLL2SSCGR_MODPER_2 (0x0004UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000004 */ +#define RCC_PLL2SSCGR_MODPER_3 (0x0008UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000008 */ +#define RCC_PLL2SSCGR_MODPER_4 (0x0010UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000010 */ +#define RCC_PLL2SSCGR_MODPER_5 (0x0020UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000020 */ +#define RCC_PLL2SSCGR_MODPER_6 (0x0040UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000040 */ +#define RCC_PLL2SSCGR_MODPER_7 (0x0080UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000080 */ +#define RCC_PLL2SSCGR_MODPER_8 (0x0100UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000100 */ +#define RCC_PLL2SSCGR_MODPER_9 (0x0200UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000200 */ +#define RCC_PLL2SSCGR_MODPER_10 (0x0400UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000400 */ +#define RCC_PLL2SSCGR_MODPER_11 (0x0800UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00000800 */ +#define RCC_PLL2SSCGR_MODPER_12 (0x1000UL << RCC_PLL2SSCGR_MODPER_Pos) /*!< 0x00001000 */ +#define RCC_PLL2SSCGR_TPDFNDIS_Pos (13U) +#define RCC_PLL2SSCGR_TPDFNDIS_Msk (0x1UL << RCC_PLL2SSCGR_TPDFNDIS_Pos) /*!< 0x00002000 */ +#define RCC_PLL2SSCGR_TPDFNDIS RCC_PLL2SSCGR_TPDFNDIS_Msk +#define RCC_PLL2SSCGR_RPDFNDIS_Pos (14U) +#define RCC_PLL2SSCGR_RPDFNDIS_Msk (0x1UL << RCC_PLL2SSCGR_RPDFNDIS_Pos) /*!< 0x00004000 */ +#define RCC_PLL2SSCGR_RPDFNDIS RCC_PLL2SSCGR_RPDFNDIS_Msk +#define RCC_PLL2SSCGR_SPREADSEL_Pos (15U) +#define RCC_PLL2SSCGR_SPREADSEL_Msk (0x1UL << RCC_PLL2SSCGR_SPREADSEL_Pos) /*!< 0x00008000 */ +#define RCC_PLL2SSCGR_SPREADSEL RCC_PLL2SSCGR_SPREADSEL_Msk +#define RCC_PLL2SSCGR_INCSTEP_Pos (16U) +#define RCC_PLL2SSCGR_INCSTEP_Msk (0x7FFFUL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x7FFF0000 */ +#define RCC_PLL2SSCGR_INCSTEP RCC_PLL2SSCGR_INCSTEP_Msk /*!< INCSTEP[14:0] bits: Modulation Depth Adjustment */ +#define RCC_PLL2SSCGR_INCSTEP_0 (0x0001UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00010000 */ +#define RCC_PLL2SSCGR_INCSTEP_1 (0x0002UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00020000 */ +#define RCC_PLL2SSCGR_INCSTEP_2 (0x0004UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00040000 */ +#define RCC_PLL2SSCGR_INCSTEP_3 (0x0008UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00080000 */ +#define RCC_PLL2SSCGR_INCSTEP_4 (0x0010UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00100000 */ +#define RCC_PLL2SSCGR_INCSTEP_5 (0x0020UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00200000 */ +#define RCC_PLL2SSCGR_INCSTEP_6 (0x0040UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00400000 */ +#define RCC_PLL2SSCGR_INCSTEP_7 (0x0080UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x00800000 */ +#define RCC_PLL2SSCGR_INCSTEP_8 (0x0100UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x01000000 */ +#define RCC_PLL2SSCGR_INCSTEP_9 (0x0200UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x02000000 */ +#define RCC_PLL2SSCGR_INCSTEP_10 (0x0400UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x04000000 */ +#define RCC_PLL2SSCGR_INCSTEP_11 (0x0800UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x08000000 */ +#define RCC_PLL2SSCGR_INCSTEP_12 (0x1000UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x10000000 */ +#define RCC_PLL2SSCGR_INCSTEP_13 (0x2000UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x20000000 */ +#define RCC_PLL2SSCGR_INCSTEP_14 (0x4000UL << RCC_PLL2SSCGR_INCSTEP_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_PLL3SSCGR register *************/ +#define RCC_PLL3SSCGR_MODPER_Pos (0U) +#define RCC_PLL3SSCGR_MODPER_Msk (0x1FFFUL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00001FFF */ +#define RCC_PLL3SSCGR_MODPER RCC_PLL3SSCGR_MODPER_Msk /*!< MODPER[12:0] bits: Modulation Period Adjustment */ +#define RCC_PLL3SSCGR_MODPER_0 (0x0001UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000001 */ +#define RCC_PLL3SSCGR_MODPER_1 (0x0002UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000002 */ +#define RCC_PLL3SSCGR_MODPER_2 (0x0004UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000004 */ +#define RCC_PLL3SSCGR_MODPER_3 (0x0008UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000008 */ +#define RCC_PLL3SSCGR_MODPER_4 (0x0010UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000010 */ +#define RCC_PLL3SSCGR_MODPER_5 (0x0020UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000020 */ +#define RCC_PLL3SSCGR_MODPER_6 (0x0040UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000040 */ +#define RCC_PLL3SSCGR_MODPER_7 (0x0080UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000080 */ +#define RCC_PLL3SSCGR_MODPER_8 (0x0100UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000100 */ +#define RCC_PLL3SSCGR_MODPER_9 (0x0200UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000200 */ +#define RCC_PLL3SSCGR_MODPER_10 (0x0400UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000400 */ +#define RCC_PLL3SSCGR_MODPER_11 (0x0800UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00000800 */ +#define RCC_PLL3SSCGR_MODPER_12 (0x1000UL << RCC_PLL3SSCGR_MODPER_Pos) /*!< 0x00001000 */ +#define RCC_PLL3SSCGR_TPDFNDIS_Pos (13U) +#define RCC_PLL3SSCGR_TPDFNDIS_Msk (0x1UL << RCC_PLL3SSCGR_TPDFNDIS_Pos) /*!< 0x00002000 */ +#define RCC_PLL3SSCGR_TPDFNDIS RCC_PLL3SSCGR_TPDFNDIS_Msk +#define RCC_PLL3SSCGR_RPDFNDIS_Pos (14U) +#define RCC_PLL3SSCGR_RPDFNDIS_Msk (0x1UL << RCC_PLL3SSCGR_RPDFNDIS_Pos) /*!< 0x00004000 */ +#define RCC_PLL3SSCGR_RPDFNDIS RCC_PLL3SSCGR_RPDFNDIS_Msk +#define RCC_PLL3SSCGR_SPREADSEL_Pos (15U) +#define RCC_PLL3SSCGR_SPREADSEL_Msk (0x1UL << RCC_PLL3SSCGR_SPREADSEL_Pos) /*!< 0x00008000 */ +#define RCC_PLL3SSCGR_SPREADSEL RCC_PLL3SSCGR_SPREADSEL_Msk +#define RCC_PLL3SSCGR_INCSTEP_Pos (16U) +#define RCC_PLL3SSCGR_INCSTEP_Msk (0x7FFFUL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x7FFF0000 */ +#define RCC_PLL3SSCGR_INCSTEP RCC_PLL3SSCGR_INCSTEP_Msk /*!< INCSTEP[14:0] bits: Modulation Depth Adjustment */ +#define RCC_PLL3SSCGR_INCSTEP_0 (0x0001UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00010000 */ +#define RCC_PLL3SSCGR_INCSTEP_1 (0x0002UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00020000 */ +#define RCC_PLL3SSCGR_INCSTEP_2 (0x0004UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00040000 */ +#define RCC_PLL3SSCGR_INCSTEP_3 (0x0008UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00080000 */ +#define RCC_PLL3SSCGR_INCSTEP_4 (0x0010UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00100000 */ +#define RCC_PLL3SSCGR_INCSTEP_5 (0x0020UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00200000 */ +#define RCC_PLL3SSCGR_INCSTEP_6 (0x0040UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00400000 */ +#define RCC_PLL3SSCGR_INCSTEP_7 (0x0080UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x00800000 */ +#define RCC_PLL3SSCGR_INCSTEP_8 (0x0100UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x01000000 */ +#define RCC_PLL3SSCGR_INCSTEP_9 (0x0200UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x02000000 */ +#define RCC_PLL3SSCGR_INCSTEP_10 (0x0400UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x04000000 */ +#define RCC_PLL3SSCGR_INCSTEP_11 (0x0800UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x08000000 */ +#define RCC_PLL3SSCGR_INCSTEP_12 (0x1000UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x10000000 */ +#define RCC_PLL3SSCGR_INCSTEP_13 (0x2000UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x20000000 */ +#define RCC_PLL3SSCGR_INCSTEP_14 (0x4000UL << RCC_PLL3SSCGR_INCSTEP_Pos) /*!< 0x40000000 */ + +/******************** Bit definition for RCC_CKPROTR register ***************/ +#define RCC_CKPROTR_XSPICKP_Pos (0U) +#define RCC_CKPROTR_XSPICKP_Msk (0x1UL << RCC_CKPROTR_XSPICKP_Pos) /*!< 0x00000001 */ +#define RCC_CKPROTR_XSPICKP RCC_CKPROTR_XSPICKP_Msk +#define RCC_CKPROTR_FMCCKP_Pos (1U) +#define RCC_CKPROTR_FMCCKP_Msk (0x1UL << RCC_CKPROTR_FMCCKP_Pos) /*!< 0x00000002 */ +#define RCC_CKPROTR_FMCCKP RCC_CKPROTR_FMCCKP_Msk +#define RCC_CKPROTR_XSPI1SWP_Pos (4U) +#define RCC_CKPROTR_XSPI1SWP_Msk (0x7UL << RCC_CKPROTR_XSPI1SWP_Pos) /*!< 0x00000070 */ +#define RCC_CKPROTR_XSPI1SWP RCC_CKPROTR_XSPI1SWP_Msk +#define RCC_CKPROTR_XSPI1SWP_0 (0x1UL << RCC_CKPROTR_XSPI1SWP_Pos) /*!< 0x00000010 */ +#define RCC_CKPROTR_XSPI1SWP_1 (0x2UL << RCC_CKPROTR_XSPI1SWP_Pos) /*!< 0x00000020 */ +#define RCC_CKPROTR_XSPI1SWP_2 (0x4UL << RCC_CKPROTR_XSPI1SWP_Pos) /*!< 0x00000040 */ +#define RCC_CKPROTR_XSPI2SWP_Pos (8U) +#define RCC_CKPROTR_XSPI2SWP_Msk (0x7UL << RCC_CKPROTR_XSPI2SWP_Pos) /*!< 0x00000700 */ +#define RCC_CKPROTR_XSPI2SWP RCC_CKPROTR_XSPI2SWP_Msk +#define RCC_CKPROTR_XSPI2SWP_0 (0x1UL << RCC_CKPROTR_XSPI2SWP_Pos) /*!< 0x00000100 */ +#define RCC_CKPROTR_XSPI2SWP_1 (0x2UL << RCC_CKPROTR_XSPI2SWP_Pos) /*!< 0x00000200 */ +#define RCC_CKPROTR_XSPI2SWP_2 (0x4UL << RCC_CKPROTR_XSPI2SWP_Pos) /*!< 0x00000400 */ +#define RCC_CKPROTR_FMCSWP_Pos (12U) +#define RCC_CKPROTR_FMCSWP_Msk (0x7UL << RCC_CKPROTR_FMCSWP_Pos) /*!< 0x00007000 */ +#define RCC_CKPROTR_FMCSWP RCC_CKPROTR_FMCSWP_Msk +#define RCC_CKPROTR_FMCSWP_0 (0x1UL << RCC_CKPROTR_FMCSWP_Pos) /*!< 0x00001000 */ +#define RCC_CKPROTR_FMCSWP_1 (0x2UL << RCC_CKPROTR_FMCSWP_Pos) /*!< 0x00002000 */ +#define RCC_CKPROTR_FMCSWP_2 (0x4UL << RCC_CKPROTR_FMCSWP_Pos) /*!< 0x00004000 */ + +/******************** Bit definition for RCC_RSR register *******************/ +#define RCC_RSR_RMVF_Pos (16U) +#define RCC_RSR_RMVF_Msk (0x1UL << RCC_RSR_RMVF_Pos) /*!< 0x00010000 */ +#define RCC_RSR_RMVF RCC_RSR_RMVF_Msk +#define RCC_RSR_OBLRSTF_Pos (17U) +#define RCC_RSR_OBLRSTF_Msk (0x1UL << RCC_RSR_OBLRSTF_Pos) /*!< 0x00020000 */ +#define RCC_RSR_OBLRSTF RCC_RSR_OBLRSTF_Msk +#define RCC_RSR_BORRSTF_Pos (21U) +#define RCC_RSR_BORRSTF_Msk (0x1UL << RCC_RSR_BORRSTF_Pos) /*!< 0x00200000 */ +#define RCC_RSR_BORRSTF RCC_RSR_BORRSTF_Msk +#define RCC_RSR_PINRSTF_Pos (22U) +#define RCC_RSR_PINRSTF_Msk (0x1UL << RCC_RSR_PINRSTF_Pos) /*!< 0x00400000 */ +#define RCC_RSR_PINRSTF RCC_RSR_PINRSTF_Msk +#define RCC_RSR_PORRSTF_Pos (23U) +#define RCC_RSR_PORRSTF_Msk (0x1UL << RCC_RSR_PORRSTF_Pos) /*!< 0x00800000 */ +#define RCC_RSR_PORRSTF RCC_RSR_PORRSTF_Msk +#define RCC_RSR_SFTRSTF_Pos (24U) +#define RCC_RSR_SFTRSTF_Msk (0x1UL << RCC_RSR_SFTRSTF_Pos) /*!< 0x01000000 */ +#define RCC_RSR_SFTRSTF RCC_RSR_SFTRSTF_Msk +#define RCC_RSR_IWDGRSTF_Pos (26U) +#define RCC_RSR_IWDGRSTF_Msk (0x1UL << RCC_RSR_IWDGRSTF_Pos) /*!< 0x04000000 */ +#define RCC_RSR_IWDGRSTF RCC_RSR_IWDGRSTF_Msk +#define RCC_RSR_WWDGRSTF_Pos (28U) +#define RCC_RSR_WWDGRSTF_Msk (0x1UL << RCC_RSR_WWDGRSTF_Pos) /*!< 0x10000000 */ +#define RCC_RSR_WWDGRSTF RCC_RSR_WWDGRSTF_Msk +#define RCC_RSR_LPWRRSTF_Pos (30U) +#define RCC_RSR_LPWRRSTF_Msk (0x1UL << RCC_RSR_LPWRRSTF_Pos) /*!< 0x40000000 */ +#define RCC_RSR_LPWRRSTF RCC_RSR_LPWRRSTF_Msk + +/******************** Bit definition for RCC_AHB1ENR register ***************/ +#define RCC_AHB1ENR_GPDMA1EN_Pos (4U) +#define RCC_AHB1ENR_GPDMA1EN_Msk (0x1UL << RCC_AHB1ENR_GPDMA1EN_Pos) /*!< 0x00000010 */ +#define RCC_AHB1ENR_GPDMA1EN RCC_AHB1ENR_GPDMA1EN_Msk +#define RCC_AHB1ENR_ADC12EN_Pos (5U) +#define RCC_AHB1ENR_ADC12EN_Msk (0x1UL << RCC_AHB1ENR_ADC12EN_Pos) /*!< 0x00000020 */ +#define RCC_AHB1ENR_ADC12EN RCC_AHB1ENR_ADC12EN_Msk +#define RCC_AHB1ENR_ETH1MACEN_Pos (15U) +#define RCC_AHB1ENR_ETH1MACEN_Msk (0x1UL << RCC_AHB1ENR_ETH1MACEN_Pos) /*!< 0x00008000 */ +#define RCC_AHB1ENR_ETH1MACEN RCC_AHB1ENR_ETH1MACEN_Msk +#define RCC_AHB1ENR_ETH1TXEN_Pos (16U) +#define RCC_AHB1ENR_ETH1TXEN_Msk (0x1UL << RCC_AHB1ENR_ETH1TXEN_Pos) /*!< 0x00010000 */ +#define RCC_AHB1ENR_ETH1TXEN RCC_AHB1ENR_ETH1TXEN_Msk +#define RCC_AHB1ENR_ETH1RXEN_Pos (17U) +#define RCC_AHB1ENR_ETH1RXEN_Msk (0x1UL << RCC_AHB1ENR_ETH1RXEN_Pos) /*!< 0x00020000 */ +#define RCC_AHB1ENR_ETH1RXEN RCC_AHB1ENR_ETH1RXEN_Msk +#define RCC_AHB1ENR_OTGHSEN_Pos (25U) +#define RCC_AHB1ENR_OTGHSEN_Msk (0x1UL << RCC_AHB1ENR_OTGHSEN_Pos) /*!< 0x02000000 */ +#define RCC_AHB1ENR_OTGHSEN RCC_AHB1ENR_OTGHSEN_Msk +#define RCC_AHB1ENR_USBPHYCEN_Pos (26U) +#define RCC_AHB1ENR_USBPHYCEN_Msk (0x1UL << RCC_AHB1ENR_USBPHYCEN_Pos) /*!< 0x04000000 */ +#define RCC_AHB1ENR_USBPHYCEN RCC_AHB1ENR_USBPHYCEN_Msk +#define RCC_AHB1ENR_OTGFSEN_Pos (27U) +#define RCC_AHB1ENR_OTGFSEN_Msk (0x1UL << RCC_AHB1ENR_OTGFSEN_Pos) /*!< 0x08000000 */ +#define RCC_AHB1ENR_OTGFSEN RCC_AHB1ENR_OTGFSEN_Msk +#define RCC_AHB1ENR_ADF1EN_Pos (31U) +#define RCC_AHB1ENR_ADF1EN_Msk (0x1UL << RCC_AHB1ENR_ADF1EN_Pos) /*!< 0x80000000 */ +#define RCC_AHB1ENR_ADF1EN RCC_AHB1ENR_ADF1EN_Msk + +/******************** Bit definition for RCC_AHB2ENR register ***************/ +#define RCC_AHB2ENR_PSSIEN_Pos (1U) +#define RCC_AHB2ENR_PSSIEN_Msk (0x1UL << RCC_AHB2ENR_PSSIEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB2ENR_PSSIEN RCC_AHB2ENR_PSSIEN_Msk +#define RCC_AHB2ENR_SDMMC2EN_Pos (9U) +#define RCC_AHB2ENR_SDMMC2EN_Msk (0x1UL << RCC_AHB2ENR_SDMMC2EN_Pos) /*!< 0x00000200 */ +#define RCC_AHB2ENR_SDMMC2EN RCC_AHB2ENR_SDMMC2EN_Msk +#define RCC_AHB2ENR_CORDICEN_Pos (14U) +#define RCC_AHB2ENR_CORDICEN_Msk (0x1UL << RCC_AHB2ENR_CORDICEN_Pos) /*!< 0x00004000 */ +#define RCC_AHB2ENR_CORDICEN RCC_AHB2ENR_CORDICEN_Msk +#define RCC_AHB2ENR_SRAM1EN_Pos (29U) +#define RCC_AHB2ENR_SRAM1EN_Msk (0x1UL << RCC_AHB2ENR_SRAM1EN_Pos) /*!< 0x20000000 */ +#define RCC_AHB2ENR_SRAM1EN RCC_AHB2ENR_SRAM1EN_Msk +#define RCC_AHB2ENR_SRAM2EN_Pos (30U) +#define RCC_AHB2ENR_SRAM2EN_Msk (0x1UL << RCC_AHB2ENR_SRAM2EN_Pos) /*!< 0x40000000 */ +#define RCC_AHB2ENR_SRAM2EN RCC_AHB2ENR_SRAM2EN_Msk + +/******************** Bit definition for RCC_AHB3ENR register ***************/ +#define RCC_AHB3ENR_RNGEN_Pos (0U) +#define RCC_AHB3ENR_RNGEN_Msk (0x1UL << RCC_AHB3ENR_RNGEN_Pos) /*!< 0x00000001 */ +#define RCC_AHB3ENR_RNGEN RCC_AHB3ENR_RNGEN_Msk +#define RCC_AHB3ENR_HASHEN_Pos (1U) +#define RCC_AHB3ENR_HASHEN_Msk (0x1UL << RCC_AHB3ENR_HASHEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB3ENR_HASHEN RCC_AHB3ENR_HASHEN_Msk +#define RCC_AHB3ENR_CRYPEN_Pos (2U) +#define RCC_AHB3ENR_CRYPEN_Msk (0x1UL << RCC_AHB3ENR_CRYPEN_Pos) /*!< 0x00000004 */ +#define RCC_AHB3ENR_CRYPEN RCC_AHB3ENR_CRYPEN_Msk +#define RCC_AHB3ENR_SAESEN_Pos (4U) +#define RCC_AHB3ENR_SAESEN_Msk (0x1UL << RCC_AHB3ENR_SAESEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB3ENR_SAESEN RCC_AHB3ENR_SAESEN_Msk +#define RCC_AHB3ENR_PKAEN_Pos (6U) +#define RCC_AHB3ENR_PKAEN_Msk (0x1UL << RCC_AHB3ENR_PKAEN_Pos) /*!< 0x00000040 */ +#define RCC_AHB3ENR_PKAEN RCC_AHB3ENR_PKAEN_Msk + +/******************** Bit definition for RCC_AHB4ENR register ***************/ +#define RCC_AHB4ENR_GPIOAEN_Pos (0U) +#define RCC_AHB4ENR_GPIOAEN_Msk (0x1UL << RCC_AHB4ENR_GPIOAEN_Pos) /*!< 0x00000001 */ +#define RCC_AHB4ENR_GPIOAEN RCC_AHB4ENR_GPIOAEN_Msk +#define RCC_AHB4ENR_GPIOBEN_Pos (1U) +#define RCC_AHB4ENR_GPIOBEN_Msk (0x1UL << RCC_AHB4ENR_GPIOBEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB4ENR_GPIOBEN RCC_AHB4ENR_GPIOBEN_Msk +#define RCC_AHB4ENR_GPIOCEN_Pos (2U) +#define RCC_AHB4ENR_GPIOCEN_Msk (0x1UL << RCC_AHB4ENR_GPIOCEN_Pos) /*!< 0x00000004 */ +#define RCC_AHB4ENR_GPIOCEN RCC_AHB4ENR_GPIOCEN_Msk +#define RCC_AHB4ENR_GPIODEN_Pos (3U) +#define RCC_AHB4ENR_GPIODEN_Msk (0x1UL << RCC_AHB4ENR_GPIODEN_Pos) /*!< 0x00000008 */ +#define RCC_AHB4ENR_GPIODEN RCC_AHB4ENR_GPIODEN_Msk +#define RCC_AHB4ENR_GPIOEEN_Pos (4U) +#define RCC_AHB4ENR_GPIOEEN_Msk (0x1UL << RCC_AHB4ENR_GPIOEEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB4ENR_GPIOEEN RCC_AHB4ENR_GPIOEEN_Msk +#define RCC_AHB4ENR_GPIOFEN_Pos (5U) +#define RCC_AHB4ENR_GPIOFEN_Msk (0x1UL << RCC_AHB4ENR_GPIOFEN_Pos) /*!< 0x00000020 */ +#define RCC_AHB4ENR_GPIOFEN RCC_AHB4ENR_GPIOFEN_Msk +#define RCC_AHB4ENR_GPIOGEN_Pos (6U) +#define RCC_AHB4ENR_GPIOGEN_Msk (0x1UL << RCC_AHB4ENR_GPIOGEN_Pos) /*!< 0x00000040 */ +#define RCC_AHB4ENR_GPIOGEN RCC_AHB4ENR_GPIOGEN_Msk +#define RCC_AHB4ENR_GPIOHEN_Pos (7U) +#define RCC_AHB4ENR_GPIOHEN_Msk (0x1UL << RCC_AHB4ENR_GPIOHEN_Pos) /*!< 0x00000080 */ +#define RCC_AHB4ENR_GPIOHEN RCC_AHB4ENR_GPIOHEN_Msk +#define RCC_AHB4ENR_GPIOMEN_Pos (12U) +#define RCC_AHB4ENR_GPIOMEN_Msk (0x1UL << RCC_AHB4ENR_GPIOMEN_Pos) /*!< 0x00001000 */ +#define RCC_AHB4ENR_GPIOMEN RCC_AHB4ENR_GPIOMEN_Msk +#define RCC_AHB4ENR_GPIONEN_Pos (13U) +#define RCC_AHB4ENR_GPIONEN_Msk (0x1UL << RCC_AHB4ENR_GPIONEN_Pos) /*!< 0x00002000 */ +#define RCC_AHB4ENR_GPIONEN RCC_AHB4ENR_GPIONEN_Msk +#define RCC_AHB4ENR_GPIOOEN_Pos (14U) +#define RCC_AHB4ENR_GPIOOEN_Msk (0x1UL << RCC_AHB4ENR_GPIOOEN_Pos) /*!< 0x00004000 */ +#define RCC_AHB4ENR_GPIOOEN RCC_AHB4ENR_GPIOOEN_Msk +#define RCC_AHB4ENR_GPIOPEN_Pos (15U) +#define RCC_AHB4ENR_GPIOPEN_Msk (0x1UL << RCC_AHB4ENR_GPIOPEN_Pos) /*!< 0x00008000 */ +#define RCC_AHB4ENR_GPIOPEN RCC_AHB4ENR_GPIOPEN_Msk +#define RCC_AHB4ENR_CRCEN_Pos (19U) +#define RCC_AHB4ENR_CRCEN_Msk (0x1UL << RCC_AHB4ENR_CRCEN_Pos) /*!< 0x00080000 */ +#define RCC_AHB4ENR_CRCEN RCC_AHB4ENR_CRCEN_Msk +#define RCC_AHB4ENR_BKPRAMEN_Pos (28U) +#define RCC_AHB4ENR_BKPRAMEN_Msk (0x1UL << RCC_AHB4ENR_BKPRAMEN_Pos) /*!< 0x10000000 */ +#define RCC_AHB4ENR_BKPRAMEN RCC_AHB4ENR_BKPRAMEN_Msk + +/******************** Bit definition for RCC_AHB5ENR register ***************/ +#define RCC_AHB5ENR_HPDMA1EN_Pos (0U) +#define RCC_AHB5ENR_HPDMA1EN_Msk (0x1UL << RCC_AHB5ENR_HPDMA1EN_Pos) /*!< 0x00000001 */ +#define RCC_AHB5ENR_HPDMA1EN RCC_AHB5ENR_HPDMA1EN_Msk +#define RCC_AHB5ENR_DMA2DEN_Pos (1U) +#define RCC_AHB5ENR_DMA2DEN_Msk (0x1UL << RCC_AHB5ENR_DMA2DEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB5ENR_DMA2DEN RCC_AHB5ENR_DMA2DEN_Msk +#define RCC_AHB5ENR_JPEGEN_Pos (3U) +#define RCC_AHB5ENR_JPEGEN_Msk (0x1UL << RCC_AHB5ENR_JPEGEN_Pos) /*!< 0x00000008 */ +#define RCC_AHB5ENR_JPEGEN RCC_AHB5ENR_JPEGEN_Msk +#define RCC_AHB5ENR_FMCEN_Pos (4U) +#define RCC_AHB5ENR_FMCEN_Msk (0x1UL << RCC_AHB5ENR_FMCEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB5ENR_FMCEN RCC_AHB5ENR_FMCEN_Msk +#define RCC_AHB5ENR_XSPI1EN_Pos (5U) +#define RCC_AHB5ENR_XSPI1EN_Msk (0x1UL << RCC_AHB5ENR_XSPI1EN_Pos) /*!< 0x00000020 */ +#define RCC_AHB5ENR_XSPI1EN RCC_AHB5ENR_XSPI1EN_Msk +#define RCC_AHB5ENR_SDMMC1EN_Pos (8U) +#define RCC_AHB5ENR_SDMMC1EN_Msk (0x1UL << RCC_AHB5ENR_SDMMC1EN_Pos) /*!< 0x00000100 */ +#define RCC_AHB5ENR_SDMMC1EN RCC_AHB5ENR_SDMMC1EN_Msk +#define RCC_AHB5ENR_XSPI2EN_Pos (12U) +#define RCC_AHB5ENR_XSPI2EN_Msk (0x1UL << RCC_AHB5ENR_XSPI2EN_Pos) /*!< 0x00001000 */ +#define RCC_AHB5ENR_XSPI2EN RCC_AHB5ENR_XSPI2EN_Msk +#define RCC_AHB5ENR_XSPIMEN_Pos (14U) +#define RCC_AHB5ENR_XSPIMEN_Msk (0x1UL << RCC_AHB5ENR_XSPIMEN_Pos) /*!< 0x00004000 */ +#define RCC_AHB5ENR_XSPIMEN RCC_AHB5ENR_XSPIMEN_Msk +#define RCC_AHB5ENR_GFXMMUEN_Pos (19U) +#define RCC_AHB5ENR_GFXMMUEN_Msk (0x1UL << RCC_AHB5ENR_GFXMMUEN_Pos) /*!< 0x00080000 */ +#define RCC_AHB5ENR_GFXMMUEN RCC_AHB5ENR_GFXMMUEN_Msk +#define RCC_AHB5ENR_GPU2DEN_Pos (20U) +#define RCC_AHB5ENR_GPU2DEN_Msk (0x1UL << RCC_AHB5ENR_GPU2DEN_Pos) /*!< 0x00100000 */ +#define RCC_AHB5ENR_GPU2DEN RCC_AHB5ENR_GPU2DEN_Msk + +/******************** Bit definition for RCC_APB1ENR1 register **************/ +#define RCC_APB1ENR1_TIM2EN_Pos (0U) +#define RCC_APB1ENR1_TIM2EN_Msk (0x1UL << RCC_APB1ENR1_TIM2EN_Pos) /*!< 0x00000001 */ +#define RCC_APB1ENR1_TIM2EN RCC_APB1ENR1_TIM2EN_Msk +#define RCC_APB1ENR1_TIM3EN_Pos (1U) +#define RCC_APB1ENR1_TIM3EN_Msk (0x1UL << RCC_APB1ENR1_TIM3EN_Pos) /*!< 0x00000002 */ +#define RCC_APB1ENR1_TIM3EN RCC_APB1ENR1_TIM3EN_Msk +#define RCC_APB1ENR1_TIM4EN_Pos (2U) +#define RCC_APB1ENR1_TIM4EN_Msk (0x1UL << RCC_APB1ENR1_TIM4EN_Pos) /*!< 0x00000004 */ +#define RCC_APB1ENR1_TIM4EN RCC_APB1ENR1_TIM4EN_Msk +#define RCC_APB1ENR1_TIM5EN_Pos (3U) +#define RCC_APB1ENR1_TIM5EN_Msk (0x1UL << RCC_APB1ENR1_TIM5EN_Pos) /*!< 0x00000008 */ +#define RCC_APB1ENR1_TIM5EN RCC_APB1ENR1_TIM5EN_Msk +#define RCC_APB1ENR1_TIM6EN_Pos (4U) +#define RCC_APB1ENR1_TIM6EN_Msk (0x1UL << RCC_APB1ENR1_TIM6EN_Pos) /*!< 0x00000010 */ +#define RCC_APB1ENR1_TIM6EN RCC_APB1ENR1_TIM6EN_Msk +#define RCC_APB1ENR1_TIM7EN_Pos (5U) +#define RCC_APB1ENR1_TIM7EN_Msk (0x1UL << RCC_APB1ENR1_TIM7EN_Pos) /*!< 0x00000020 */ +#define RCC_APB1ENR1_TIM7EN RCC_APB1ENR1_TIM7EN_Msk +#define RCC_APB1ENR1_TIM12EN_Pos (6U) +#define RCC_APB1ENR1_TIM12EN_Msk (0x1UL << RCC_APB1ENR1_TIM12EN_Pos) /*!< 0x00000040 */ +#define RCC_APB1ENR1_TIM12EN RCC_APB1ENR1_TIM12EN_Msk +#define RCC_APB1ENR1_TIM13EN_Pos (7U) +#define RCC_APB1ENR1_TIM13EN_Msk (0x1UL << RCC_APB1ENR1_TIM13EN_Pos) /*!< 0x00000080 */ +#define RCC_APB1ENR1_TIM13EN RCC_APB1ENR1_TIM13EN_Msk +#define RCC_APB1ENR1_TIM14EN_Pos (8U) +#define RCC_APB1ENR1_TIM14EN_Msk (0x1UL << RCC_APB1ENR1_TIM14EN_Pos) /*!< 0x00000100 */ +#define RCC_APB1ENR1_TIM14EN RCC_APB1ENR1_TIM14EN_Msk +#define RCC_APB1ENR1_LPTIM1EN_Pos (9U) +#define RCC_APB1ENR1_LPTIM1EN_Msk (0x1UL << RCC_APB1ENR1_LPTIM1EN_Pos) /*!< 0x00000200 */ +#define RCC_APB1ENR1_LPTIM1EN RCC_APB1ENR1_LPTIM1EN_Msk +#define RCC_APB1ENR1_WWDGEN_Pos (11U) +#define RCC_APB1ENR1_WWDGEN_Msk (0x1UL << RCC_APB1ENR1_WWDGEN_Pos) /*!< 0x00000800 */ +#define RCC_APB1ENR1_WWDGEN RCC_APB1ENR1_WWDGEN_Msk +#define RCC_APB1ENR1_SPI2EN_Pos (14U) +#define RCC_APB1ENR1_SPI2EN_Msk (0x1UL << RCC_APB1ENR1_SPI2EN_Pos) /*!< 0x00004000 */ +#define RCC_APB1ENR1_SPI2EN RCC_APB1ENR1_SPI2EN_Msk +#define RCC_APB1ENR1_SPI3EN_Pos (15U) +#define RCC_APB1ENR1_SPI3EN_Msk (0x1UL << RCC_APB1ENR1_SPI3EN_Pos) /*!< 0x00008000 */ +#define RCC_APB1ENR1_SPI3EN RCC_APB1ENR1_SPI3EN_Msk +#define RCC_APB1ENR1_SPDIFRXEN_Pos (16U) +#define RCC_APB1ENR1_SPDIFRXEN_Msk (0x1UL << RCC_APB1ENR1_SPDIFRXEN_Pos) /*!< 0x00010000 */ +#define RCC_APB1ENR1_SPDIFRXEN RCC_APB1ENR1_SPDIFRXEN_Msk +#define RCC_APB1ENR1_USART2EN_Pos (17U) +#define RCC_APB1ENR1_USART2EN_Msk (0x1UL << RCC_APB1ENR1_USART2EN_Pos) /*!< 0x00020000 */ +#define RCC_APB1ENR1_USART2EN RCC_APB1ENR1_USART2EN_Msk +#define RCC_APB1ENR1_USART3EN_Pos (18U) +#define RCC_APB1ENR1_USART3EN_Msk (0x1UL << RCC_APB1ENR1_USART3EN_Pos) /*!< 0x00040000 */ +#define RCC_APB1ENR1_USART3EN RCC_APB1ENR1_USART3EN_Msk +#define RCC_APB1ENR1_UART4EN_Pos (19U) +#define RCC_APB1ENR1_UART4EN_Msk (0x1UL << RCC_APB1ENR1_UART4EN_Pos) /*!< 0x00080000 */ +#define RCC_APB1ENR1_UART4EN RCC_APB1ENR1_UART4EN_Msk +#define RCC_APB1ENR1_UART5EN_Pos (20U) +#define RCC_APB1ENR1_UART5EN_Msk (0x1UL << RCC_APB1ENR1_UART5EN_Pos) /*!< 0x00100000 */ +#define RCC_APB1ENR1_UART5EN RCC_APB1ENR1_UART5EN_Msk +#define RCC_APB1ENR1_I2C1_I3C1EN_Pos (21U) +#define RCC_APB1ENR1_I2C1_I3C1EN_Msk (0x1UL << RCC_APB1ENR1_I2C1_I3C1EN_Pos) /*!< 0x00200000 */ +#define RCC_APB1ENR1_I2C1_I3C1EN RCC_APB1ENR1_I2C1_I3C1EN_Msk +#define RCC_APB1ENR1_I2C2EN_Pos (22U) +#define RCC_APB1ENR1_I2C2EN_Msk (0x1UL << RCC_APB1ENR1_I2C2EN_Pos) /*!< 0x00400000 */ +#define RCC_APB1ENR1_I2C2EN RCC_APB1ENR1_I2C2EN_Msk +#define RCC_APB1ENR1_I2C3EN_Pos (23U) +#define RCC_APB1ENR1_I2C3EN_Msk (0x1UL << RCC_APB1ENR1_I2C3EN_Pos) /*!< 0x00800000 */ +#define RCC_APB1ENR1_I2C3EN RCC_APB1ENR1_I2C3EN_Msk +#define RCC_APB1ENR1_CECEN_Pos (27U) +#define RCC_APB1ENR1_CECEN_Msk (0x1UL << RCC_APB1ENR1_CECEN_Pos) /*!< 0x08000000 */ +#define RCC_APB1ENR1_CECEN RCC_APB1ENR1_CECEN_Msk +#define RCC_APB1ENR1_UART7EN_Pos (30U) +#define RCC_APB1ENR1_UART7EN_Msk (0x1UL << RCC_APB1ENR1_UART7EN_Pos) /*!< 0x40000000 */ +#define RCC_APB1ENR1_UART7EN RCC_APB1ENR1_UART7EN_Msk +#define RCC_APB1ENR1_UART8EN_Pos (31U) +#define RCC_APB1ENR1_UART8EN_Msk (0x1UL << RCC_APB1ENR1_UART8EN_Pos) /*!< 0x80000000 */ +#define RCC_APB1ENR1_UART8EN RCC_APB1ENR1_UART8EN_Msk + +/******************** Bit definition for RCC_APB1ENR2 register **************/ +#define RCC_APB1ENR2_CRSEN_Pos (1U) +#define RCC_APB1ENR2_CRSEN_Msk (0x1UL << RCC_APB1ENR2_CRSEN_Pos) /*!< 0x00000002 */ +#define RCC_APB1ENR2_CRSEN RCC_APB1ENR2_CRSEN_Msk +#define RCC_APB1ENR2_MDIOSEN_Pos (5U) +#define RCC_APB1ENR2_MDIOSEN_Msk (0x1UL << RCC_APB1ENR2_MDIOSEN_Pos) /*!< 0x00000020 */ +#define RCC_APB1ENR2_MDIOSEN RCC_APB1ENR2_MDIOSEN_Msk +#define RCC_APB1ENR2_FDCANEN_Pos (8U) +#define RCC_APB1ENR2_FDCANEN_Msk (0x1UL << RCC_APB1ENR2_FDCANEN_Pos) /*!< 0x00000100 */ +#define RCC_APB1ENR2_FDCANEN RCC_APB1ENR2_FDCANEN_Msk +#define RCC_APB1ENR2_UCPD1EN_Pos (27U) +#define RCC_APB1ENR2_UCPD1EN_Msk (0x1UL << RCC_APB1ENR2_UCPD1EN_Pos) /*!< 0x08000000 */ +#define RCC_APB1ENR2_UCPD1EN RCC_APB1ENR2_UCPD1EN_Msk + +/******************** Bit definition for RCC_APB2ENR register ***************/ +#define RCC_APB2ENR_TIM1EN_Pos (0U) +#define RCC_APB2ENR_TIM1EN_Msk (0x1UL << RCC_APB2ENR_TIM1EN_Pos) /*!< 0x00000001 */ +#define RCC_APB2ENR_TIM1EN RCC_APB2ENR_TIM1EN_Msk +#define RCC_APB2ENR_USART1EN_Pos (4U) +#define RCC_APB2ENR_USART1EN_Msk (0x1UL << RCC_APB2ENR_USART1EN_Pos) /*!< 0x00000010 */ +#define RCC_APB2ENR_USART1EN RCC_APB2ENR_USART1EN_Msk +#define RCC_APB2ENR_SPI1EN_Pos (12U) +#define RCC_APB2ENR_SPI1EN_Msk (0x1UL << RCC_APB2ENR_SPI1EN_Pos) /*!< 0x00001000 */ +#define RCC_APB2ENR_SPI1EN RCC_APB2ENR_SPI1EN_Msk +#define RCC_APB2ENR_SPI4EN_Pos (13U) +#define RCC_APB2ENR_SPI4EN_Msk (0x1UL << RCC_APB2ENR_SPI4EN_Pos) /*!< 0x00002000 */ +#define RCC_APB2ENR_SPI4EN RCC_APB2ENR_SPI4EN_Msk +#define RCC_APB2ENR_TIM15EN_Pos (16U) +#define RCC_APB2ENR_TIM15EN_Msk (0x1UL << RCC_APB2ENR_TIM15EN_Pos) /*!< 0x00010000 */ +#define RCC_APB2ENR_TIM15EN RCC_APB2ENR_TIM15EN_Msk +#define RCC_APB2ENR_TIM16EN_Pos (17U) +#define RCC_APB2ENR_TIM16EN_Msk (0x1UL << RCC_APB2ENR_TIM16EN_Pos) /*!< 0x00020000 */ +#define RCC_APB2ENR_TIM16EN RCC_APB2ENR_TIM16EN_Msk +#define RCC_APB2ENR_TIM17EN_Pos (18U) +#define RCC_APB2ENR_TIM17EN_Msk (0x1UL << RCC_APB2ENR_TIM17EN_Pos) /*!< 0x00040000 */ +#define RCC_APB2ENR_TIM17EN RCC_APB2ENR_TIM17EN_Msk +#define RCC_APB2ENR_TIM9EN_Pos (19U) +#define RCC_APB2ENR_TIM9EN_Msk (0x1UL << RCC_APB2ENR_TIM9EN_Pos) /*!< 0x00080000 */ +#define RCC_APB2ENR_TIM9EN RCC_APB2ENR_TIM9EN_Msk +#define RCC_APB2ENR_SPI5EN_Pos (20U) +#define RCC_APB2ENR_SPI5EN_Msk (0x1UL << RCC_APB2ENR_SPI5EN_Pos) /*!< 0x00100000 */ +#define RCC_APB2ENR_SPI5EN RCC_APB2ENR_SPI5EN_Msk +#define RCC_APB2ENR_SAI1EN_Pos (22U) +#define RCC_APB2ENR_SAI1EN_Msk (0x1UL << RCC_APB2ENR_SAI1EN_Pos) /*!< 0x00400000 */ +#define RCC_APB2ENR_SAI1EN RCC_APB2ENR_SAI1EN_Msk +#define RCC_APB2ENR_SAI2EN_Pos (23U) +#define RCC_APB2ENR_SAI2EN_Msk (0x1UL << RCC_APB2ENR_SAI2EN_Pos) /*!< 0x00800000 */ +#define RCC_APB2ENR_SAI2EN RCC_APB2ENR_SAI2EN_Msk + +/******************** Bit definition for RCC_APB4ENR register ***************/ +#define RCC_APB4ENR_SBSEN_Pos (1U) +#define RCC_APB4ENR_SBSEN_Msk (0x1UL << RCC_APB4ENR_SBSEN_Pos) /*!< 0x00000002 */ +#define RCC_APB4ENR_SBSEN RCC_APB4ENR_SBSEN_Msk +#define RCC_APB4ENR_LPUART1EN_Pos (3U) +#define RCC_APB4ENR_LPUART1EN_Msk (0x1UL << RCC_APB4ENR_LPUART1EN_Pos) /*!< 0x00000008 */ +#define RCC_APB4ENR_LPUART1EN RCC_APB4ENR_LPUART1EN_Msk +#define RCC_APB4ENR_SPI6EN_Pos (5U) +#define RCC_APB4ENR_SPI6EN_Msk (0x1UL << RCC_APB4ENR_SPI6EN_Pos) /*!< 0x00000020 */ +#define RCC_APB4ENR_SPI6EN RCC_APB4ENR_SPI6EN_Msk +#define RCC_APB4ENR_LPTIM2EN_Pos (9U) +#define RCC_APB4ENR_LPTIM2EN_Msk (0x1UL << RCC_APB4ENR_LPTIM2EN_Pos) /*!< 0x00000200 */ +#define RCC_APB4ENR_LPTIM2EN RCC_APB4ENR_LPTIM2EN_Msk +#define RCC_APB4ENR_LPTIM3EN_Pos (10U) +#define RCC_APB4ENR_LPTIM3EN_Msk (0x1UL << RCC_APB4ENR_LPTIM3EN_Pos) /*!< 0x00000400 */ +#define RCC_APB4ENR_LPTIM3EN RCC_APB4ENR_LPTIM3EN_Msk +#define RCC_APB4ENR_LPTIM4EN_Pos (11U) +#define RCC_APB4ENR_LPTIM4EN_Msk (0x1UL << RCC_APB4ENR_LPTIM4EN_Pos) /*!< 0x00000800 */ +#define RCC_APB4ENR_LPTIM4EN RCC_APB4ENR_LPTIM4EN_Msk +#define RCC_APB4ENR_LPTIM5EN_Pos (12U) +#define RCC_APB4ENR_LPTIM5EN_Msk (0x1UL << RCC_APB4ENR_LPTIM5EN_Pos) /*!< 0x00001000 */ +#define RCC_APB4ENR_LPTIM5EN RCC_APB4ENR_LPTIM5EN_Msk +#define RCC_APB4ENR_VREFEN_Pos (15U) +#define RCC_APB4ENR_VREFEN_Msk (0x1UL << RCC_APB4ENR_VREFEN_Pos) /*!< 0x00008000 */ +#define RCC_APB4ENR_VREFEN RCC_APB4ENR_VREFEN_Msk +#define RCC_APB4ENR_RTCAPBEN_Pos (16U) +#define RCC_APB4ENR_RTCAPBEN_Msk (0x1UL << RCC_APB4ENR_RTCAPBEN_Pos) /*!< 0x00010000 */ +#define RCC_APB4ENR_RTCAPBEN RCC_APB4ENR_RTCAPBEN_Msk +#define RCC_APB4ENR_DTSEN_Pos (26U) +#define RCC_APB4ENR_DTSEN_Msk (0x1UL << RCC_APB4ENR_DTSEN_Pos) /*!< 0x04000000 */ +#define RCC_APB4ENR_DTSEN RCC_APB4ENR_DTSEN_Msk + +/******************** Bit definition for RCC_APB5ENR register ***************/ +#define RCC_APB5ENR_LTDCEN_Pos (1U) +#define RCC_APB5ENR_LTDCEN_Msk (0x1UL << RCC_APB5ENR_LTDCEN_Pos) /*!< 0x00000002 */ +#define RCC_APB5ENR_LTDCEN RCC_APB5ENR_LTDCEN_Msk +#define RCC_APB5ENR_DCMIPPEN_Pos (2U) +#define RCC_APB5ENR_DCMIPPEN_Msk (0x1UL << RCC_APB5ENR_DCMIPPEN_Pos) /*!< 0x00000004 */ +#define RCC_APB5ENR_DCMIPPEN RCC_APB5ENR_DCMIPPEN_Msk +#define RCC_APB5ENR_GFXTIMEN_Pos (4U) +#define RCC_APB5ENR_GFXTIMEN_Msk (0x1UL << RCC_APB5ENR_GFXTIMEN_Pos) /*!< 0x00000010 */ +#define RCC_APB5ENR_GFXTIMEN RCC_APB5ENR_GFXTIMEN_Msk + +/******************** Bit definition for RCC_AHB1LPENR register *************/ +#define RCC_AHB1LPENR_GPDMA1LPEN_Pos (4U) +#define RCC_AHB1LPENR_GPDMA1LPEN_Msk (0x1UL << RCC_AHB1LPENR_GPDMA1LPEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB1LPENR_GPDMA1LPEN RCC_AHB1LPENR_GPDMA1LPEN_Msk +#define RCC_AHB1LPENR_ADC12LPEN_Pos (5U) +#define RCC_AHB1LPENR_ADC12LPEN_Msk (0x1UL << RCC_AHB1LPENR_ADC12LPEN_Pos) /*!< 0x00000020 */ +#define RCC_AHB1LPENR_ADC12LPEN RCC_AHB1LPENR_ADC12LPEN_Msk +#define RCC_AHB1LPENR_ETH1MACLPEN_Pos (15U) +#define RCC_AHB1LPENR_ETH1MACLPEN_Msk (0x1UL << RCC_AHB1LPENR_ETH1MACLPEN_Pos) /*!< 0x00008000 */ +#define RCC_AHB1LPENR_ETH1MACLPEN RCC_AHB1LPENR_ETH1MACLPEN_Msk +#define RCC_AHB1LPENR_ETH1TXLPEN_Pos (16U) +#define RCC_AHB1LPENR_ETH1TXLPEN_Msk (0x1UL << RCC_AHB1LPENR_ETH1TXLPEN_Pos) /*!< 0x00010000 */ +#define RCC_AHB1LPENR_ETH1TXLPEN RCC_AHB1LPENR_ETH1TXLPEN_Msk +#define RCC_AHB1LPENR_ETH1RXLPEN_Pos (17U) +#define RCC_AHB1LPENR_ETH1RXLPEN_Msk (0x1UL << RCC_AHB1LPENR_ETH1RXLPEN_Pos) /*!< 0x00020000 */ +#define RCC_AHB1LPENR_ETH1RXLPEN RCC_AHB1LPENR_ETH1RXLPEN_Msk +#define RCC_AHB1LPENR_UCPDCTRL_Pos (24U) +#define RCC_AHB1LPENR_UCPDCTRL_Msk (0x1UL << RCC_AHB1LPENR_UCPDCTRL_Pos) /*!< 0x01000000 */ +#define RCC_AHB1LPENR_UCPDCTRL RCC_AHB1LPENR_UCPDCTRL_Msk +#define RCC_AHB1LPENR_OTGHSLPEN_Pos (25U) +#define RCC_AHB1LPENR_OTGHSLPEN_Msk (0x1UL << RCC_AHB1LPENR_OTGHSLPEN_Pos) /*!< 0x02000000 */ +#define RCC_AHB1LPENR_OTGHSLPEN RCC_AHB1LPENR_OTGHSLPEN_Msk +#define RCC_AHB1LPENR_USBPHYCLPEN_Pos (26U) +#define RCC_AHB1LPENR_USBPHYCLPEN_Msk (0x1UL << RCC_AHB1LPENR_USBPHYCLPEN_Pos)/*!< 0x04000000 */ +#define RCC_AHB1LPENR_USBPHYCLPEN RCC_AHB1LPENR_USBPHYCLPEN_Msk +#define RCC_AHB1LPENR_OTGFSLPEN_Pos (27U) +#define RCC_AHB1LPENR_OTGFSLPEN_Msk (0x1UL << RCC_AHB1LPENR_OTGFSLPEN_Pos) /*!< 0x08000000 */ +#define RCC_AHB1LPENR_OTGFSLPEN RCC_AHB1LPENR_OTGFSLPEN_Msk +#define RCC_AHB1LPENR_ADF1LPEN_Pos (31U) +#define RCC_AHB1LPENR_ADF1LPEN_Msk (0x1UL << RCC_AHB1LPENR_ADF1LPEN_Pos) /*!< 0x80000000 */ +#define RCC_AHB1LPENR_ADF1LPEN RCC_AHB1LPENR_ADF1LPEN_Msk + +/******************** Bit definition for RCC_AHB2LPENR register *************/ +#define RCC_AHB2LPENR_PSSILPEN_Pos (1U) +#define RCC_AHB2LPENR_PSSILPEN_Msk (0x1UL << RCC_AHB2LPENR_PSSILPEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB2LPENR_PSSILPEN RCC_AHB2LPENR_PSSILPEN_Msk +#define RCC_AHB2LPENR_SDMMC2LPEN_Pos (9U) +#define RCC_AHB2LPENR_SDMMC2LPEN_Msk (0x1UL << RCC_AHB2LPENR_SDMMC2LPEN_Pos) /*!< 0x00000200 */ +#define RCC_AHB2LPENR_SDMMC2LPEN RCC_AHB2LPENR_SDMMC2LPEN_Msk +#define RCC_AHB2LPENR_CORDICLPEN_Pos (14U) +#define RCC_AHB2LPENR_CORDICLPEN_Msk (0x1UL << RCC_AHB2LPENR_CORDICLPEN_Pos) /*!< 0x00004000 */ +#define RCC_AHB2LPENR_CORDICLPEN RCC_AHB2LPENR_CORDICLPEN_Msk +#define RCC_AHB2LPENR_SRAM1LPEN_Pos (29U) +#define RCC_AHB2LPENR_SRAM1LPEN_Msk (0x1UL << RCC_AHB2LPENR_SRAM1LPEN_Pos) /*!< 0x20000000 */ +#define RCC_AHB2LPENR_SRAM1LPEN RCC_AHB2LPENR_SRAM1LPEN_Msk +#define RCC_AHB2LPENR_SRAM2LPEN_Pos (30U) +#define RCC_AHB2LPENR_SRAM2LPEN_Msk (0x1UL << RCC_AHB2LPENR_SRAM2LPEN_Pos) /*!< 0x40000000 */ +#define RCC_AHB2LPENR_SRAM2LPEN RCC_AHB2LPENR_SRAM2LPEN_Msk + +/******************** Bit definition for RCC_AHB3LPENR register *************/ +#define RCC_AHB3LPENR_RNGLPEN_Pos (0U) +#define RCC_AHB3LPENR_RNGLPEN_Msk (0x1UL << RCC_AHB3LPENR_RNGLPEN_Pos) /*!< 0x00000001 */ +#define RCC_AHB3LPENR_RNGLPEN RCC_AHB3LPENR_RNGLPEN_Msk +#define RCC_AHB3LPENR_HASHLPEN_Pos (1U) +#define RCC_AHB3LPENR_HASHLPEN_Msk (0x1UL << RCC_AHB3LPENR_HASHLPEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB3LPENR_HASHLPEN RCC_AHB3LPENR_HASHLPEN_Msk +#define RCC_AHB3LPENR_CRYPLPEN_Pos (2U) +#define RCC_AHB3LPENR_CRYPLPEN_Msk (0x1UL << RCC_AHB3LPENR_CRYPLPEN_Pos) /*!< 0x00000004 */ +#define RCC_AHB3LPENR_CRYPLPEN RCC_AHB3LPENR_CRYPLPEN_Msk +#define RCC_AHB3LPENR_SAESLPEN_Pos (4U) +#define RCC_AHB3LPENR_SAESLPEN_Msk (0x1UL << RCC_AHB3LPENR_SAESLPEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB3LPENR_SAESLPEN RCC_AHB3LPENR_SAESLPEN_Msk +#define RCC_AHB3LPENR_PKALPEN_Pos (6U) +#define RCC_AHB3LPENR_PKALPEN_Msk (0x1UL << RCC_AHB3LPENR_PKALPEN_Pos) /*!< 0x00000040 */ +#define RCC_AHB3LPENR_PKALPEN RCC_AHB3LPENR_PKALPEN_Msk + +/******************** Bit definition for RCC_AHB4LPENR register *************/ +#define RCC_AHB4LPENR_GPIOALPEN_Pos (0U) +#define RCC_AHB4LPENR_GPIOALPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOALPEN_Pos) /*!< 0x00000001 */ +#define RCC_AHB4LPENR_GPIOALPEN RCC_AHB4LPENR_GPIOALPEN_Msk +#define RCC_AHB4LPENR_GPIOBLPEN_Pos (1U) +#define RCC_AHB4LPENR_GPIOBLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOBLPEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB4LPENR_GPIOBLPEN RCC_AHB4LPENR_GPIOBLPEN_Msk +#define RCC_AHB4LPENR_GPIOCLPEN_Pos (2U) +#define RCC_AHB4LPENR_GPIOCLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOCLPEN_Pos) /*!< 0x00000004 */ +#define RCC_AHB4LPENR_GPIOCLPEN RCC_AHB4LPENR_GPIOCLPEN_Msk +#define RCC_AHB4LPENR_GPIODLPEN_Pos (3U) +#define RCC_AHB4LPENR_GPIODLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIODLPEN_Pos) /*!< 0x00000008 */ +#define RCC_AHB4LPENR_GPIODLPEN RCC_AHB4LPENR_GPIODLPEN_Msk +#define RCC_AHB4LPENR_GPIOELPEN_Pos (4U) +#define RCC_AHB4LPENR_GPIOELPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOELPEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB4LPENR_GPIOELPEN RCC_AHB4LPENR_GPIOELPEN_Msk +#define RCC_AHB4LPENR_GPIOFLPEN_Pos (5U) +#define RCC_AHB4LPENR_GPIOFLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOFLPEN_Pos) /*!< 0x00000020 */ +#define RCC_AHB4LPENR_GPIOFLPEN RCC_AHB4LPENR_GPIOFLPEN_Msk +#define RCC_AHB4LPENR_GPIOGLPEN_Pos (6U) +#define RCC_AHB4LPENR_GPIOGLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOGLPEN_Pos) /*!< 0x00000040 */ +#define RCC_AHB4LPENR_GPIOGLPEN RCC_AHB4LPENR_GPIOGLPEN_Msk +#define RCC_AHB4LPENR_GPIOHLPEN_Pos (7U) +#define RCC_AHB4LPENR_GPIOHLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOHLPEN_Pos) /*!< 0x00000080 */ +#define RCC_AHB4LPENR_GPIOHLPEN RCC_AHB4LPENR_GPIOHLPEN_Msk +#define RCC_AHB4LPENR_GPIOMLPEN_Pos (12U) +#define RCC_AHB4LPENR_GPIOMLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOMLPEN_Pos) /*!< 0x00001000 */ +#define RCC_AHB4LPENR_GPIOMLPEN RCC_AHB4LPENR_GPIOMLPEN_Msk +#define RCC_AHB4LPENR_GPIONLPEN_Pos (13U) +#define RCC_AHB4LPENR_GPIONLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIONLPEN_Pos) /*!< 0x00002000 */ +#define RCC_AHB4LPENR_GPIONLPEN RCC_AHB4LPENR_GPIONLPEN_Msk +#define RCC_AHB4LPENR_GPIOOLPEN_Pos (14U) +#define RCC_AHB4LPENR_GPIOOLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOOLPEN_Pos) /*!< 0x00004000 */ +#define RCC_AHB4LPENR_GPIOOLPEN RCC_AHB4LPENR_GPIOOLPEN_Msk +#define RCC_AHB4LPENR_GPIOPLPEN_Pos (15U) +#define RCC_AHB4LPENR_GPIOPLPEN_Msk (0x1UL << RCC_AHB4LPENR_GPIOPLPEN_Pos) /*!< 0x00008000 */ +#define RCC_AHB4LPENR_GPIOPLPEN RCC_AHB4LPENR_GPIOPLPEN_Msk +#define RCC_AHB4LPENR_CRCLPEN_Pos (19U) +#define RCC_AHB4LPENR_CRCLPEN_Msk (0x1UL << RCC_AHB4LPENR_CRCLPEN_Pos) /*!< 0x00080000 */ +#define RCC_AHB4LPENR_CRCLPEN RCC_AHB4LPENR_CRCLPEN_Msk +#define RCC_AHB4LPENR_BKPRAMLPEN_Pos (28U) +#define RCC_AHB4LPENR_BKPRAMLPEN_Msk (0x1UL << RCC_AHB4LPENR_BKPRAMLPEN_Pos) /*!< 0x10000000 */ +#define RCC_AHB4LPENR_BKPRAMLPEN RCC_AHB4LPENR_BKPRAMLPEN_Msk + +/******************** Bit definition for RCC_AHB5LPENR register *************/ +#define RCC_AHB5LPENR_HPDMA1LPEN_Pos (0U) +#define RCC_AHB5LPENR_HPDMA1LPEN_Msk (0x1UL << RCC_AHB5LPENR_HPDMA1LPEN_Pos) /*!< 0x00000001 */ +#define RCC_AHB5LPENR_HPDMA1LPEN RCC_AHB5LPENR_HPDMA1LPEN_Msk +#define RCC_AHB5LPENR_DMA2DLPEN_Pos (1U) +#define RCC_AHB5LPENR_DMA2DLPEN_Msk (0x1UL << RCC_AHB5LPENR_DMA2DLPEN_Pos) /*!< 0x00000002 */ +#define RCC_AHB5LPENR_DMA2DLPEN RCC_AHB5LPENR_DMA2DLPEN_Msk +#define RCC_AHB5LPENR_FLASHLPEN_Pos (2U) +#define RCC_AHB5LPENR_FLASHLPEN_Msk (0x1UL << RCC_AHB5LPENR_FLASHLPEN_Pos) /*!< 0x00000004 */ +#define RCC_AHB5LPENR_FLASHLPEN RCC_AHB5LPENR_FLASHLPEN_Msk +#define RCC_AHB5LPENR_JPEGLPEN_Pos (3U) +#define RCC_AHB5LPENR_JPEGLPEN_Msk (0x1UL << RCC_AHB5LPENR_JPEGLPEN_Pos) /*!< 0x00000008 */ +#define RCC_AHB5LPENR_JPEGLPEN RCC_AHB5LPENR_JPEGLPEN_Msk +#define RCC_AHB5LPENR_FMCLPEN_Pos (4U) +#define RCC_AHB5LPENR_FMCLPEN_Msk (0x1UL << RCC_AHB5LPENR_FMCLPEN_Pos) /*!< 0x00000010 */ +#define RCC_AHB5LPENR_FMCLPEN RCC_AHB5LPENR_FMCLPEN_Msk +#define RCC_AHB5LPENR_XSPI1LPEN_Pos (5U) +#define RCC_AHB5LPENR_XSPI1LPEN_Msk (0x1UL << RCC_AHB5LPENR_XSPI1LPEN_Pos) /*!< 0x00000020 */ +#define RCC_AHB5LPENR_XSPI1LPEN RCC_AHB5LPENR_XSPI1LPEN_Msk +#define RCC_AHB5LPENR_SDMMC1LPEN_Pos (8U) +#define RCC_AHB5LPENR_SDMMC1LPEN_Msk (0x1UL << RCC_AHB5LPENR_SDMMC1LPEN_Pos) /*!< 0x00000100 */ +#define RCC_AHB5LPENR_SDMMC1LPEN RCC_AHB5LPENR_SDMMC1LPEN_Msk +#define RCC_AHB5LPENR_XSPI2LPEN_Pos (12U) +#define RCC_AHB5LPENR_XSPI2LPEN_Msk (0x1UL << RCC_AHB5LPENR_XSPI2LPEN_Pos) /*!< 0x00001000 */ +#define RCC_AHB5LPENR_XSPI2LPEN RCC_AHB5LPENR_XSPI2LPEN_Msk +#define RCC_AHB5LPENR_XSPIMLPEN_Pos (14U) +#define RCC_AHB5LPENR_XSPIMLPEN_Msk (0x1UL << RCC_AHB5LPENR_XSPIMLPEN_Pos) /*!< 0x00004000 */ +#define RCC_AHB5LPENR_XSPIMLPEN RCC_AHB5LPENR_XSPIMLPEN_Msk +#define RCC_AHB5LPENR_GFXMMULPEN_Pos (19U) +#define RCC_AHB5LPENR_GFXMMULPEN_Msk (0x1UL << RCC_AHB5LPENR_GFXMMULPEN_Pos) /*!< 0x00080000 */ +#define RCC_AHB5LPENR_GFXMMULPEN RCC_AHB5LPENR_GFXMMULPEN_Msk +#define RCC_AHB5LPENR_GPU2DLPEN_Pos (20U) +#define RCC_AHB5LPENR_GPU2DLPEN_Msk (0x1UL << RCC_AHB5LPENR_GPU2DLPEN_Pos) /*!< 0x00100000 */ +#define RCC_AHB5LPENR_GPU2DLPEN RCC_AHB5LPENR_GPU2DLPEN_Msk +#define RCC_AHB5LPENR_DTCM1LPEN_Pos (28U) +#define RCC_AHB5LPENR_DTCM1LPEN_Msk (0x1UL << RCC_AHB5LPENR_DTCM1LPEN_Pos) /*!< 0x10000000 */ +#define RCC_AHB5LPENR_DTCM1LPEN RCC_AHB5LPENR_DTCM1LPEN_Msk +#define RCC_AHB5LPENR_DTCM2LPEN_Pos (29U) +#define RCC_AHB5LPENR_DTCM2LPEN_Msk (0x1UL << RCC_AHB5LPENR_DTCM2LPEN_Pos) /*!< 0x20000000 */ +#define RCC_AHB5LPENR_DTCM2LPEN RCC_AHB5LPENR_DTCM2LPEN_Msk +#define RCC_AHB5LPENR_ITCMLPEN_Pos (30U) +#define RCC_AHB5LPENR_ITCMLPEN_Msk (0x1UL << RCC_AHB5LPENR_ITCMLPEN_Pos) /*!< 0x40000000 */ +#define RCC_AHB5LPENR_ITCMLPEN RCC_AHB5LPENR_ITCMLPEN_Msk +#define RCC_AHB5LPENR_AXISRAMLPEN_Pos (31U) +#define RCC_AHB5LPENR_AXISRAMLPEN_Msk (0x1UL << RCC_AHB5LPENR_AXISRAMLPEN_Pos) /*!< 0x80000000 */ +#define RCC_AHB5LPENR_AXISRAMLPEN RCC_AHB5LPENR_AXISRAMLPEN_Msk + +/******************** Bit definition for RCC_APB1LPENR1 register ************/ +#define RCC_APB1LPENR1_TIM2LPEN_Pos (0U) +#define RCC_APB1LPENR1_TIM2LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM2LPEN_Pos) /*!< 0x00000001 */ +#define RCC_APB1LPENR1_TIM2LPEN RCC_APB1LPENR1_TIM2LPEN_Msk +#define RCC_APB1LPENR1_TIM3LPEN_Pos (1U) +#define RCC_APB1LPENR1_TIM3LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM3LPEN_Pos) /*!< 0x00000002 */ +#define RCC_APB1LPENR1_TIM3LPEN RCC_APB1LPENR1_TIM3LPEN_Msk +#define RCC_APB1LPENR1_TIM4LPEN_Pos (2U) +#define RCC_APB1LPENR1_TIM4LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM4LPEN_Pos) /*!< 0x00000004 */ +#define RCC_APB1LPENR1_TIM4LPEN RCC_APB1LPENR1_TIM4LPEN_Msk +#define RCC_APB1LPENR1_TIM5LPEN_Pos (3U) +#define RCC_APB1LPENR1_TIM5LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM5LPEN_Pos) /*!< 0x00000008 */ +#define RCC_APB1LPENR1_TIM5LPEN RCC_APB1LPENR1_TIM5LPEN_Msk +#define RCC_APB1LPENR1_TIM6LPEN_Pos (4U) +#define RCC_APB1LPENR1_TIM6LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM6LPEN_Pos) /*!< 0x00000010 */ +#define RCC_APB1LPENR1_TIM6LPEN RCC_APB1LPENR1_TIM6LPEN_Msk +#define RCC_APB1LPENR1_TIM7LPEN_Pos (5U) +#define RCC_APB1LPENR1_TIM7LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM7LPEN_Pos) /*!< 0x00000020 */ +#define RCC_APB1LPENR1_TIM7LPEN RCC_APB1LPENR1_TIM7LPEN_Msk +#define RCC_APB1LPENR1_TIM12LPEN_Pos (6U) +#define RCC_APB1LPENR1_TIM12LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM12LPEN_Pos) /*!< 0x00000040 */ +#define RCC_APB1LPENR1_TIM12LPEN RCC_APB1LPENR1_TIM12LPEN_Msk +#define RCC_APB1LPENR1_TIM13LPEN_Pos (7U) +#define RCC_APB1LPENR1_TIM13LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM13LPEN_Pos) /*!< 0x00000080 */ +#define RCC_APB1LPENR1_TIM13LPEN RCC_APB1LPENR1_TIM13LPEN_Msk +#define RCC_APB1LPENR1_TIM14LPEN_Pos (8U) +#define RCC_APB1LPENR1_TIM14LPEN_Msk (0x1UL << RCC_APB1LPENR1_TIM14LPEN_Pos) /*!< 0x00000100 */ +#define RCC_APB1LPENR1_TIM14LPEN RCC_APB1LPENR1_TIM14LPEN_Msk +#define RCC_APB1LPENR1_LPTIM1LPEN_Pos (9U) +#define RCC_APB1LPENR1_LPTIM1LPEN_Msk (0x1UL << RCC_APB1LPENR1_LPTIM1LPEN_Pos)/*!< 0x00000200 */ +#define RCC_APB1LPENR1_LPTIM1LPEN RCC_APB1LPENR1_LPTIM1LPEN_Msk +#define RCC_APB1LPENR1_WWDGLPEN_Pos (11U) +#define RCC_APB1LPENR1_WWDGLPEN_Msk (0x1UL << RCC_APB1LPENR1_WWDGLPEN_Pos) /*!< 0x00000800 */ +#define RCC_APB1LPENR1_WWDGLPEN RCC_APB1LPENR1_WWDGLPEN_Msk +#define RCC_APB1LPENR1_SPI2LPEN_Pos (14U) +#define RCC_APB1LPENR1_SPI2LPEN_Msk (0x1UL << RCC_APB1LPENR1_SPI2LPEN_Pos) /*!< 0x00004000 */ +#define RCC_APB1LPENR1_SPI2LPEN RCC_APB1LPENR1_SPI2LPEN_Msk +#define RCC_APB1LPENR1_SPI3LPEN_Pos (15U) +#define RCC_APB1LPENR1_SPI3LPEN_Msk (0x1UL << RCC_APB1LPENR1_SPI3LPEN_Pos) /*!< 0x00008000 */ +#define RCC_APB1LPENR1_SPI3LPEN RCC_APB1LPENR1_SPI3LPEN_Msk +#define RCC_APB1LPENR1_SPDIFRXLPEN_Pos (16U) +#define RCC_APB1LPENR1_SPDIFRXLPEN_Msk (0x1UL << RCC_APB1LPENR1_SPDIFRXLPEN_Pos)/*!< 0x00010000 */ +#define RCC_APB1LPENR1_SPDIFRXLPEN RCC_APB1LPENR1_SPDIFRXLPEN_Msk +#define RCC_APB1LPENR1_USART2LPEN_Pos (17U) +#define RCC_APB1LPENR1_USART2LPEN_Msk (0x1UL << RCC_APB1LPENR1_USART2LPEN_Pos)/*!< 0x00020000 */ +#define RCC_APB1LPENR1_USART2LPEN RCC_APB1LPENR1_USART2LPEN_Msk +#define RCC_APB1LPENR1_USART3LPEN_Pos (18U) +#define RCC_APB1LPENR1_USART3LPEN_Msk (0x1UL << RCC_APB1LPENR1_USART3LPEN_Pos)/*!< 0x00040000 */ +#define RCC_APB1LPENR1_USART3LPEN RCC_APB1LPENR1_USART3LPEN_Msk +#define RCC_APB1LPENR1_UART4LPEN_Pos (19U) +#define RCC_APB1LPENR1_UART4LPEN_Msk (0x1UL << RCC_APB1LPENR1_UART4LPEN_Pos) /*!< 0x00080000 */ +#define RCC_APB1LPENR1_UART4LPEN RCC_APB1LPENR1_UART4LPEN_Msk +#define RCC_APB1LPENR1_UART5LPEN_Pos (20U) +#define RCC_APB1LPENR1_UART5LPEN_Msk (0x1UL << RCC_APB1LPENR1_UART5LPEN_Pos) /*!< 0x00100000 */ +#define RCC_APB1LPENR1_UART5LPEN RCC_APB1LPENR1_UART5LPEN_Msk +#define RCC_APB1LPENR1_I2C1_I3C1LPEN_Pos (21U) +#define RCC_APB1LPENR1_I2C1_I3C1LPEN_Msk (0x1UL << RCC_APB1LPENR1_I2C1_I3C1LPEN_Pos) /*!< 0x00200000 */ +#define RCC_APB1LPENR1_I2C1_I3C1LPEN RCC_APB1LPENR1_I2C1_I3C1LPEN_Msk +#define RCC_APB1LPENR1_I2C2LPEN_Pos (22U) +#define RCC_APB1LPENR1_I2C2LPEN_Msk (0x1UL << RCC_APB1LPENR1_I2C2LPEN_Pos) /*!< 0x00400000 */ +#define RCC_APB1LPENR1_I2C2LPEN RCC_APB1LPENR1_I2C2LPEN_Msk +#define RCC_APB1LPENR1_I2C3LPEN_Pos (23U) +#define RCC_APB1LPENR1_I2C3LPEN_Msk (0x1UL << RCC_APB1LPENR1_I2C3LPEN_Pos) /*!< 0x00800000 */ +#define RCC_APB1LPENR1_I2C3LPEN RCC_APB1LPENR1_I2C3LPEN_Msk +#define RCC_APB1LPENR1_CECLPEN_Pos (27U) +#define RCC_APB1LPENR1_CECLPEN_Msk (0x1UL << RCC_APB1LPENR1_CECLPEN_Pos) /*!< 0x08000000 */ +#define RCC_APB1LPENR1_CECLPEN RCC_APB1LPENR1_CECLPEN_Msk +#define RCC_APB1LPENR1_UART7LPEN_Pos (30U) +#define RCC_APB1LPENR1_UART7LPEN_Msk (0x1UL << RCC_APB1LPENR1_UART7LPEN_Pos) /*!< 0x40000000 */ +#define RCC_APB1LPENR1_UART7LPEN RCC_APB1LPENR1_UART7LPEN_Msk +#define RCC_APB1LPENR1_UART8LPEN_Pos (31U) +#define RCC_APB1LPENR1_UART8LPEN_Msk (0x1UL << RCC_APB1LPENR1_UART8LPEN_Pos) /*!< 0x80000000 */ +#define RCC_APB1LPENR1_UART8LPEN RCC_APB1LPENR1_UART8LPEN_Msk + +/******************** Bit definition for RCC_PB1LPENR2 register ************/ +#define RCC_APB1LPENR2_CRSLPEN_Pos (1U) +#define RCC_APB1LPENR2_CRSLPEN_Msk (0x1UL << RCC_APB1LPENR2_CRSLPEN_Pos) /*!< 0x00000002 */ +#define RCC_APB1LPENR2_CRSLPEN RCC_APB1LPENR2_CRSLPEN_Msk +#define RCC_APB1LPENR2_MDIOSLPEN_Pos (5U) +#define RCC_APB1LPENR2_MDIOSLPEN_Msk (0x1UL << RCC_APB1LPENR2_MDIOSLPEN_Pos) /*!< 0x00000020 */ +#define RCC_APB1LPENR2_MDIOSLPEN RCC_APB1LPENR2_MDIOSLPEN_Msk +#define RCC_APB1LPENR2_FDCANLPEN_Pos (8U) +#define RCC_APB1LPENR2_FDCANLPEN_Msk (0x1UL << RCC_APB1LPENR2_FDCANLPEN_Pos) /*!< 0x00000100 */ +#define RCC_APB1LPENR2_FDCANLPEN RCC_APB1LPENR2_FDCANLPEN_Msk +#define RCC_APB1LPENR2_UCPD1LPEN_Pos (27U) +#define RCC_APB1LPENR2_UCPD1LPEN_Msk (0x1UL << RCC_APB1LPENR2_UCPD1LPEN_Pos) /*!< 0x08000000 */ +#define RCC_APB1LPENR2_UCPD1LPEN RCC_APB1LPENR2_UCPD1LPEN_Msk + +/******************** Bit definition for RCC_APB2LPENR register *************/ +#define RCC_APB2LPENR_TIM1LPEN_Pos (0U) +#define RCC_APB2LPENR_TIM1LPEN_Msk (0x1UL << RCC_APB2LPENR_TIM1LPEN_Pos) /*!< 0x00000001 */ +#define RCC_APB2LPENR_TIM1LPEN RCC_APB2LPENR_TIM1LPEN_Msk +#define RCC_APB2LPENR_USART1LPEN_Pos (4U) +#define RCC_APB2LPENR_USART1LPEN_Msk (0x1UL << RCC_APB2LPENR_USART1LPEN_Pos) /*!< 0x00000010 */ +#define RCC_APB2LPENR_USART1LPEN RCC_APB2LPENR_USART1LPEN_Msk +#define RCC_APB2LPENR_SPI1LPEN_Pos (12U) +#define RCC_APB2LPENR_SPI1LPEN_Msk (0x1UL << RCC_APB2LPENR_SPI1LPEN_Pos) /*!< 0x00001000 */ +#define RCC_APB2LPENR_SPI1LPEN RCC_APB2LPENR_SPI1LPEN_Msk +#define RCC_APB2LPENR_SPI4LPEN_Pos (13U) +#define RCC_APB2LPENR_SPI4LPEN_Msk (0x1UL << RCC_APB2LPENR_SPI4LPEN_Pos) /*!< 0x00002000 */ +#define RCC_APB2LPENR_SPI4LPEN RCC_APB2LPENR_SPI4LPEN_Msk +#define RCC_APB2LPENR_TIM15LPEN_Pos (16U) +#define RCC_APB2LPENR_TIM15LPEN_Msk (0x1UL << RCC_APB2LPENR_TIM15LPEN_Pos) /*!< 0x00010000 */ +#define RCC_APB2LPENR_TIM15LPEN RCC_APB2LPENR_TIM15LPEN_Msk +#define RCC_APB2LPENR_TIM16LPEN_Pos (17U) +#define RCC_APB2LPENR_TIM16LPEN_Msk (0x1UL << RCC_APB2LPENR_TIM16LPEN_Pos) /*!< 0x00020000 */ +#define RCC_APB2LPENR_TIM16LPEN RCC_APB2LPENR_TIM16LPEN_Msk +#define RCC_APB2LPENR_TIM17LPEN_Pos (18U) +#define RCC_APB2LPENR_TIM17LPEN_Msk (0x1UL << RCC_APB2LPENR_TIM17LPEN_Pos) /*!< 0x00040000 */ +#define RCC_APB2LPENR_TIM17LPEN RCC_APB2LPENR_TIM17LPEN_Msk +#define RCC_APB2LPENR_TIM9LPEN_Pos (19U) +#define RCC_APB2LPENR_TIM9LPEN_Msk (0x1UL << RCC_APB2LPENR_TIM9LPEN_Pos) /*!< 0x00080000 */ +#define RCC_APB2LPENR_TIM9LPEN RCC_APB2LPENR_TIM9LPEN_Msk +#define RCC_APB2LPENR_SPI5LPEN_Pos (20U) +#define RCC_APB2LPENR_SPI5LPEN_Msk (0x1UL << RCC_APB2LPENR_SPI5LPEN_Pos) /*!< 0x00100000 */ +#define RCC_APB2LPENR_SPI5LPEN RCC_APB2LPENR_SPI5LPEN_Msk +#define RCC_APB2LPENR_SAI1LPEN_Pos (22U) +#define RCC_APB2LPENR_SAI1LPEN_Msk (0x1UL << RCC_APB2LPENR_SAI1LPEN_Pos) /*!< 0x00400000 */ +#define RCC_APB2LPENR_SAI1LPEN RCC_APB2LPENR_SAI1LPEN_Msk +#define RCC_APB2LPENR_SAI2LPEN_Pos (23U) +#define RCC_APB2LPENR_SAI2LPEN_Msk (0x1UL << RCC_APB2LPENR_SAI2LPEN_Pos) /*!< 0x00800000 */ +#define RCC_APB2LPENR_SAI2LPEN RCC_APB2LPENR_SAI2LPEN_Msk + +/******************** Bit definition for RCC_APB4LPENR register *************/ +#define RCC_APB4LPENR_SBSLPEN_Pos (1U) +#define RCC_APB4LPENR_SBSLPEN_Msk (0x1UL << RCC_APB4LPENR_SBSLPEN_Pos) /*!< 0x00000002 */ +#define RCC_APB4LPENR_SBSLPEN RCC_APB4LPENR_SBSLPEN_Msk +#define RCC_APB4LPENR_LPUART1LPEN_Pos (3U) +#define RCC_APB4LPENR_LPUART1LPEN_Msk (0x1UL << RCC_APB4LPENR_LPUART1LPEN_Pos)/*!< 0x00000008 */ +#define RCC_APB4LPENR_LPUART1LPEN RCC_APB4LPENR_LPUART1LPEN_Msk +#define RCC_APB4LPENR_SPI6LPEN_Pos (5U) +#define RCC_APB4LPENR_SPI6LPEN_Msk (0x1UL << RCC_APB4LPENR_SPI6LPEN_Pos) /*!< 0x00000020 */ +#define RCC_APB4LPENR_SPI6LPEN RCC_APB4LPENR_SPI6LPEN_Msk +#define RCC_APB4LPENR_LPTIM2LPEN_Pos (9U) +#define RCC_APB4LPENR_LPTIM2LPEN_Msk (0x1UL << RCC_APB4LPENR_LPTIM2LPEN_Pos) /*!< 0x00000200 */ +#define RCC_APB4LPENR_LPTIM2LPEN RCC_APB4LPENR_LPTIM2LPEN_Msk +#define RCC_APB4LPENR_LPTIM3LPEN_Pos (10U) +#define RCC_APB4LPENR_LPTIM3LPEN_Msk (0x1UL << RCC_APB4LPENR_LPTIM3LPEN_Pos) /*!< 0x00000400 */ +#define RCC_APB4LPENR_LPTIM3LPEN RCC_APB4LPENR_LPTIM3LPEN_Msk +#define RCC_APB4LPENR_LPTIM4LPEN_Pos (11U) +#define RCC_APB4LPENR_LPTIM4LPEN_Msk (0x1UL << RCC_APB4LPENR_LPTIM4LPEN_Pos) /*!< 0x00000800 */ +#define RCC_APB4LPENR_LPTIM4LPEN RCC_APB4LPENR_LPTIM4LPEN_Msk +#define RCC_APB4LPENR_LPTIM5LPEN_Pos (12U) +#define RCC_APB4LPENR_LPTIM5LPEN_Msk (0x1UL << RCC_APB4LPENR_LPTIM5LPEN_Pos) /*!< 0x00001000 */ +#define RCC_APB4LPENR_LPTIM5LPEN RCC_APB4LPENR_LPTIM5LPEN_Msk +#define RCC_APB4LPENR_VREFLPEN_Pos (15U) +#define RCC_APB4LPENR_VREFLPEN_Msk (0x1UL << RCC_APB4LPENR_VREFLPEN_Pos) /*!< 0x00008000 */ +#define RCC_APB4LPENR_VREFLPEN RCC_APB4LPENR_VREFLPEN_Msk +#define RCC_APB4LPENR_RTCAPBLPEN_Pos (16U) +#define RCC_APB4LPENR_RTCAPBLPEN_Msk (0x1UL << RCC_APB4LPENR_RTCAPBLPEN_Pos) /*!< 0x00010000 */ +#define RCC_APB4LPENR_RTCAPBLPEN RCC_APB4LPENR_RTCAPBLPEN_Msk +#define RCC_APB4LPENR_DTSLPEN_Pos (26U) +#define RCC_APB4LPENR_DTSLPEN_Msk (0x1UL << RCC_APB4LPENR_DTSLPEN_Pos) /*!< 0x04000000 */ +#define RCC_APB4LPENR_DTSLPEN RCC_APB4LPENR_DTSLPEN_Msk + +/******************** Bit definition for RCC_APB5LPENR register *************/ +#define RCC_APB5LPENR_LTDCLPEN_Pos (1U) +#define RCC_APB5LPENR_LTDCLPEN_Msk (0x1UL << RCC_APB5LPENR_LTDCLPEN_Pos) /*!< 0x00000002 */ +#define RCC_APB5LPENR_LTDCLPEN RCC_APB5LPENR_LTDCLPEN_Msk +#define RCC_APB5LPENR_DCMIPPLPEN_Pos (2U) +#define RCC_APB5LPENR_DCMIPPLPEN_Msk (0x1UL << RCC_APB5LPENR_DCMIPPLPEN_Pos) /*!< 0x00000004 */ +#define RCC_APB5LPENR_DCMIPPLPEN RCC_APB5LPENR_DCMIPPLPEN_Msk +#define RCC_APB5LPENR_GFXTIMLPEN_Pos (4U) +#define RCC_APB5LPENR_GFXTIMLPEN_Msk (0x1UL << RCC_APB5LPENR_GFXTIMLPEN_Pos) /*!< 0x00000010 */ +#define RCC_APB5LPENR_GFXTIMLPEN RCC_APB5LPENR_GFXTIMLPEN_Msk + + +/******************************************************************************/ +/* */ +/* 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 + + +/******************************************************************************/ +/* */ +/* Real-Time Clock (RTC) */ +/* */ +/******************************************************************************/ +/******************** Bits definition for RTC_TR register *******************/ +#define RTC_TR_SU_Pos (0U) +#define RTC_TR_SU_Msk (0xFUL << RTC_TR_SU_Pos) /*!< 0x0000000F */ +#define RTC_TR_SU RTC_TR_SU_Msk +#define RTC_TR_SU_0 (0x1UL << RTC_TR_SU_Pos) /*!< 0x00000001 */ +#define RTC_TR_SU_1 (0x2UL << RTC_TR_SU_Pos) /*!< 0x00000002 */ +#define RTC_TR_SU_2 (0x4UL << RTC_TR_SU_Pos) /*!< 0x00000004 */ +#define RTC_TR_SU_3 (0x8UL << RTC_TR_SU_Pos) /*!< 0x00000008 */ +#define RTC_TR_ST_Pos (4U) +#define RTC_TR_ST_Msk (0x7UL << RTC_TR_ST_Pos) /*!< 0x00000070 */ +#define RTC_TR_ST RTC_TR_ST_Msk +#define RTC_TR_ST_0 (0x1UL << RTC_TR_ST_Pos) /*!< 0x00000010 */ +#define RTC_TR_ST_1 (0x2UL << RTC_TR_ST_Pos) /*!< 0x00000020 */ +#define RTC_TR_ST_2 (0x4UL << RTC_TR_ST_Pos) /*!< 0x00000040 */ +#define RTC_TR_MNU_Pos (8U) +#define RTC_TR_MNU_Msk (0xFUL << RTC_TR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_TR_MNU RTC_TR_MNU_Msk +#define RTC_TR_MNU_0 (0x1UL << RTC_TR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_TR_MNU_1 (0x2UL << RTC_TR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_TR_MNU_2 (0x4UL << RTC_TR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_TR_MNU_3 (0x8UL << RTC_TR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_TR_MNT_Pos (12U) +#define RTC_TR_MNT_Msk (0x7UL << RTC_TR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_TR_MNT RTC_TR_MNT_Msk +#define RTC_TR_MNT_0 (0x1UL << RTC_TR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_TR_MNT_1 (0x2UL << RTC_TR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_TR_MNT_2 (0x4UL << RTC_TR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_TR_HU_Pos (16U) +#define RTC_TR_HU_Msk (0xFUL << RTC_TR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_TR_HU RTC_TR_HU_Msk +#define RTC_TR_HU_0 (0x1UL << RTC_TR_HU_Pos) /*!< 0x00010000 */ +#define RTC_TR_HU_1 (0x2UL << RTC_TR_HU_Pos) /*!< 0x00020000 */ +#define RTC_TR_HU_2 (0x4UL << RTC_TR_HU_Pos) /*!< 0x00040000 */ +#define RTC_TR_HU_3 (0x8UL << RTC_TR_HU_Pos) /*!< 0x00080000 */ +#define RTC_TR_HT_Pos (20U) +#define RTC_TR_HT_Msk (0x3UL << RTC_TR_HT_Pos) /*!< 0x00300000 */ +#define RTC_TR_HT RTC_TR_HT_Msk +#define RTC_TR_HT_0 (0x1UL << RTC_TR_HT_Pos) /*!< 0x00100000 */ +#define RTC_TR_HT_1 (0x2UL << RTC_TR_HT_Pos) /*!< 0x00200000 */ +#define RTC_TR_PM_Pos (22U) +#define RTC_TR_PM_Msk (0x1UL << RTC_TR_PM_Pos) /*!< 0x00400000 */ +#define RTC_TR_PM RTC_TR_PM_Msk + +/******************** Bits definition for RTC_DR register *******************/ +#define RTC_DR_DU_Pos (0U) +#define RTC_DR_DU_Msk (0xFUL << RTC_DR_DU_Pos) /*!< 0x0000000F */ +#define RTC_DR_DU RTC_DR_DU_Msk +#define RTC_DR_DU_0 (0x1UL << RTC_DR_DU_Pos) /*!< 0x00000001 */ +#define RTC_DR_DU_1 (0x2UL << RTC_DR_DU_Pos) /*!< 0x00000002 */ +#define RTC_DR_DU_2 (0x4UL << RTC_DR_DU_Pos) /*!< 0x00000004 */ +#define RTC_DR_DU_3 (0x8UL << RTC_DR_DU_Pos) /*!< 0x00000008 */ +#define RTC_DR_DT_Pos (4U) +#define RTC_DR_DT_Msk (0x3UL << RTC_DR_DT_Pos) /*!< 0x00000030 */ +#define RTC_DR_DT RTC_DR_DT_Msk +#define RTC_DR_DT_0 (0x1UL << RTC_DR_DT_Pos) /*!< 0x00000010 */ +#define RTC_DR_DT_1 (0x2UL << RTC_DR_DT_Pos) /*!< 0x00000020 */ +#define RTC_DR_MU_Pos (8U) +#define RTC_DR_MU_Msk (0xFUL << RTC_DR_MU_Pos) /*!< 0x00000F00 */ +#define RTC_DR_MU RTC_DR_MU_Msk +#define RTC_DR_MU_0 (0x1UL << RTC_DR_MU_Pos) /*!< 0x00000100 */ +#define RTC_DR_MU_1 (0x2UL << RTC_DR_MU_Pos) /*!< 0x00000200 */ +#define RTC_DR_MU_2 (0x4UL << RTC_DR_MU_Pos) /*!< 0x00000400 */ +#define RTC_DR_MU_3 (0x8UL << RTC_DR_MU_Pos) /*!< 0x00000800 */ +#define RTC_DR_MT_Pos (12U) +#define RTC_DR_MT_Msk (0x1UL << RTC_DR_MT_Pos) /*!< 0x00001000 */ +#define RTC_DR_MT RTC_DR_MT_Msk +#define RTC_DR_WDU_Pos (13U) +#define RTC_DR_WDU_Msk (0x7UL << RTC_DR_WDU_Pos) /*!< 0x0000E000 */ +#define RTC_DR_WDU RTC_DR_WDU_Msk +#define RTC_DR_WDU_0 (0x1UL << RTC_DR_WDU_Pos) /*!< 0x00002000 */ +#define RTC_DR_WDU_1 (0x2UL << RTC_DR_WDU_Pos) /*!< 0x00004000 */ +#define RTC_DR_WDU_2 (0x4UL << RTC_DR_WDU_Pos) /*!< 0x00008000 */ +#define RTC_DR_YU_Pos (16U) +#define RTC_DR_YU_Msk (0xFUL << RTC_DR_YU_Pos) /*!< 0x000F0000 */ +#define RTC_DR_YU RTC_DR_YU_Msk +#define RTC_DR_YU_0 (0x1UL << RTC_DR_YU_Pos) /*!< 0x00010000 */ +#define RTC_DR_YU_1 (0x2UL << RTC_DR_YU_Pos) /*!< 0x00020000 */ +#define RTC_DR_YU_2 (0x4UL << RTC_DR_YU_Pos) /*!< 0x00040000 */ +#define RTC_DR_YU_3 (0x8UL << RTC_DR_YU_Pos) /*!< 0x00080000 */ +#define RTC_DR_YT_Pos (20U) +#define RTC_DR_YT_Msk (0xFUL << RTC_DR_YT_Pos) /*!< 0x00F00000 */ +#define RTC_DR_YT RTC_DR_YT_Msk +#define RTC_DR_YT_0 (0x1UL << RTC_DR_YT_Pos) /*!< 0x00100000 */ +#define RTC_DR_YT_1 (0x2UL << RTC_DR_YT_Pos) /*!< 0x00200000 */ +#define RTC_DR_YT_2 (0x4UL << RTC_DR_YT_Pos) /*!< 0x00400000 */ +#define RTC_DR_YT_3 (0x8UL << RTC_DR_YT_Pos) /*!< 0x00800000 */ + +/******************** Bits definition for RTC_SSR register ******************/ +#define RTC_SSR_SS_Pos (0U) +#define RTC_SSR_SS_Msk (0xFFFFFFFFUL << RTC_SSR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_SSR_SS RTC_SSR_SS_Msk + +/******************** Bits definition for RTC_ICSR register ******************/ +#define RTC_ICSR_WUTWF_Pos (2U) +#define RTC_ICSR_WUTWF_Msk (0x1UL << RTC_ICSR_WUTWF_Pos) /*!< 0x00000004 */ +#define RTC_ICSR_WUTWF RTC_ICSR_WUTWF_Msk +#define RTC_ICSR_SHPF_Pos (3U) +#define RTC_ICSR_SHPF_Msk (0x1UL << RTC_ICSR_SHPF_Pos) /*!< 0x00000008 */ +#define RTC_ICSR_SHPF RTC_ICSR_SHPF_Msk +#define RTC_ICSR_INITS_Pos (4U) +#define RTC_ICSR_INITS_Msk (0x1UL << RTC_ICSR_INITS_Pos) /*!< 0x00000010 */ +#define RTC_ICSR_INITS RTC_ICSR_INITS_Msk +#define RTC_ICSR_RSF_Pos (5U) +#define RTC_ICSR_RSF_Msk (0x1UL << RTC_ICSR_RSF_Pos) /*!< 0x00000020 */ +#define RTC_ICSR_RSF RTC_ICSR_RSF_Msk +#define RTC_ICSR_INITF_Pos (6U) +#define RTC_ICSR_INITF_Msk (0x1UL << RTC_ICSR_INITF_Pos) /*!< 0x00000040 */ +#define RTC_ICSR_INITF RTC_ICSR_INITF_Msk +#define RTC_ICSR_INIT_Pos (7U) +#define RTC_ICSR_INIT_Msk (0x1UL << RTC_ICSR_INIT_Pos) /*!< 0x00000080 */ +#define RTC_ICSR_INIT RTC_ICSR_INIT_Msk +#define RTC_ICSR_BIN_Pos (8U) +#define RTC_ICSR_BIN_Msk (0x3UL << RTC_ICSR_BIN_Pos) /*!< 0x00000300 */ +#define RTC_ICSR_BIN RTC_ICSR_BIN_Msk +#define RTC_ICSR_BIN_0 (0x1UL << RTC_ICSR_BIN_Pos) /*!< 0x00000100 */ +#define RTC_ICSR_BIN_1 (0x2UL << RTC_ICSR_BIN_Pos) /*!< 0x00000200 */ +#define RTC_ICSR_BCDU_Pos (10U) +#define RTC_ICSR_BCDU_Msk (0x7UL << RTC_ICSR_BCDU_Pos) /*!< 0x00001C00 */ +#define RTC_ICSR_BCDU RTC_ICSR_BCDU_Msk +#define RTC_ICSR_BCDU_0 (0x1UL << RTC_ICSR_BCDU_Pos) /*!< 0x00000400 */ +#define RTC_ICSR_BCDU_1 (0x2UL << RTC_ICSR_BCDU_Pos) /*!< 0x00000800 */ +#define RTC_ICSR_BCDU_2 (0x4UL << RTC_ICSR_BCDU_Pos) /*!< 0x00001000 */ +#define RTC_ICSR_RECALPF_Pos (16U) +#define RTC_ICSR_RECALPF_Msk (0x1UL << RTC_ICSR_RECALPF_Pos) /*!< 0x00010000 */ +#define RTC_ICSR_RECALPF RTC_ICSR_RECALPF_Msk + +/******************** Bits definition for RTC_PRER register *****************/ +#define RTC_PRER_PREDIV_S_Pos (0U) +#define RTC_PRER_PREDIV_S_Msk (0x7FFFUL << RTC_PRER_PREDIV_S_Pos) /*!< 0x00007FFF */ +#define RTC_PRER_PREDIV_S RTC_PRER_PREDIV_S_Msk +#define RTC_PRER_PREDIV_A_Pos (16U) +#define RTC_PRER_PREDIV_A_Msk (0x7FUL << RTC_PRER_PREDIV_A_Pos) /*!< 0x007F0000 */ +#define RTC_PRER_PREDIV_A RTC_PRER_PREDIV_A_Msk + +/******************** Bits definition for RTC_WUTR register *****************/ +#define RTC_WUTR_WUT_Pos (0U) +#define RTC_WUTR_WUT_Msk (0xFFFFUL << RTC_WUTR_WUT_Pos) /*!< 0x0000FFFF */ +#define RTC_WUTR_WUT RTC_WUTR_WUT_Msk +#define RTC_WUTR_WUTOCLR_Pos (16U) +#define RTC_WUTR_WUTOCLR_Msk (0xFFFFUL << RTC_WUTR_WUTOCLR_Pos) /*!< 0x0000FFFF */ +#define RTC_WUTR_WUTOCLR RTC_WUTR_WUTOCLR_Msk + +/******************** Bits definition for RTC_CR register *******************/ +#define RTC_CR_WUCKSEL_Pos (0U) +#define RTC_CR_WUCKSEL_Msk (0x7UL << RTC_CR_WUCKSEL_Pos) /*!< 0x00000007 */ +#define RTC_CR_WUCKSEL RTC_CR_WUCKSEL_Msk +#define RTC_CR_WUCKSEL_0 (0x1UL << RTC_CR_WUCKSEL_Pos) /*!< 0x00000001 */ +#define RTC_CR_WUCKSEL_1 (0x2UL << RTC_CR_WUCKSEL_Pos) /*!< 0x00000002 */ +#define RTC_CR_WUCKSEL_2 (0x4UL << RTC_CR_WUCKSEL_Pos) /*!< 0x00000004 */ +#define RTC_CR_TSEDGE_Pos (3U) +#define RTC_CR_TSEDGE_Msk (0x1UL << RTC_CR_TSEDGE_Pos) /*!< 0x00000008 */ +#define RTC_CR_TSEDGE RTC_CR_TSEDGE_Msk +#define RTC_CR_REFCKON_Pos (4U) +#define RTC_CR_REFCKON_Msk (0x1UL << RTC_CR_REFCKON_Pos) /*!< 0x00000010 */ +#define RTC_CR_REFCKON RTC_CR_REFCKON_Msk +#define RTC_CR_BYPSHAD_Pos (5U) +#define RTC_CR_BYPSHAD_Msk (0x1UL << RTC_CR_BYPSHAD_Pos) /*!< 0x00000020 */ +#define RTC_CR_BYPSHAD RTC_CR_BYPSHAD_Msk +#define RTC_CR_FMT_Pos (6U) +#define RTC_CR_FMT_Msk (0x1UL << RTC_CR_FMT_Pos) /*!< 0x00000040 */ +#define RTC_CR_FMT RTC_CR_FMT_Msk +#define RTC_CR_SSRUIE_Pos (7U) +#define RTC_CR_SSRUIE_Msk (0x1UL << RTC_CR_SSRUIE_Pos) /*!< 0x00000080 */ +#define RTC_CR_SSRUIE RTC_CR_SSRUIE_Msk +#define RTC_CR_ALRAE_Pos (8U) +#define RTC_CR_ALRAE_Msk (0x1UL << RTC_CR_ALRAE_Pos) /*!< 0x00000100 */ +#define RTC_CR_ALRAE RTC_CR_ALRAE_Msk +#define RTC_CR_ALRBE_Pos (9U) +#define RTC_CR_ALRBE_Msk (0x1UL << RTC_CR_ALRBE_Pos) /*!< 0x00000200 */ +#define RTC_CR_ALRBE RTC_CR_ALRBE_Msk +#define RTC_CR_WUTE_Pos (10U) +#define RTC_CR_WUTE_Msk (0x1UL << RTC_CR_WUTE_Pos) /*!< 0x00000400 */ +#define RTC_CR_WUTE RTC_CR_WUTE_Msk +#define RTC_CR_TSE_Pos (11U) +#define RTC_CR_TSE_Msk (0x1UL << RTC_CR_TSE_Pos) /*!< 0x00000800 */ +#define RTC_CR_TSE RTC_CR_TSE_Msk +#define RTC_CR_ALRAIE_Pos (12U) +#define RTC_CR_ALRAIE_Msk (0x1UL << RTC_CR_ALRAIE_Pos) /*!< 0x00001000 */ +#define RTC_CR_ALRAIE RTC_CR_ALRAIE_Msk +#define RTC_CR_ALRBIE_Pos (13U) +#define RTC_CR_ALRBIE_Msk (0x1UL << RTC_CR_ALRBIE_Pos) /*!< 0x00002000 */ +#define RTC_CR_ALRBIE RTC_CR_ALRBIE_Msk +#define RTC_CR_WUTIE_Pos (14U) +#define RTC_CR_WUTIE_Msk (0x1UL << RTC_CR_WUTIE_Pos) /*!< 0x00004000 */ +#define RTC_CR_WUTIE RTC_CR_WUTIE_Msk +#define RTC_CR_TSIE_Pos (15U) +#define RTC_CR_TSIE_Msk (0x1UL << RTC_CR_TSIE_Pos) /*!< 0x00008000 */ +#define RTC_CR_TSIE RTC_CR_TSIE_Msk +#define RTC_CR_ADD1H_Pos (16U) +#define RTC_CR_ADD1H_Msk (0x1UL << RTC_CR_ADD1H_Pos) /*!< 0x00010000 */ +#define RTC_CR_ADD1H RTC_CR_ADD1H_Msk +#define RTC_CR_SUB1H_Pos (17U) +#define RTC_CR_SUB1H_Msk (0x1UL << RTC_CR_SUB1H_Pos) /*!< 0x00020000 */ +#define RTC_CR_SUB1H RTC_CR_SUB1H_Msk +#define RTC_CR_BKP_Pos (18U) +#define RTC_CR_BKP_Msk (0x1UL << RTC_CR_BKP_Pos) /*!< 0x00040000 */ +#define RTC_CR_BKP RTC_CR_BKP_Msk +#define RTC_CR_COSEL_Pos (19U) +#define RTC_CR_COSEL_Msk (0x1UL << RTC_CR_COSEL_Pos) /*!< 0x00080000 */ +#define RTC_CR_COSEL RTC_CR_COSEL_Msk +#define RTC_CR_POL_Pos (20U) +#define RTC_CR_POL_Msk (0x1UL << RTC_CR_POL_Pos) /*!< 0x00100000 */ +#define RTC_CR_POL RTC_CR_POL_Msk +#define RTC_CR_OSEL_Pos (21U) +#define RTC_CR_OSEL_Msk (0x3UL << RTC_CR_OSEL_Pos) /*!< 0x00600000 */ +#define RTC_CR_OSEL RTC_CR_OSEL_Msk +#define RTC_CR_OSEL_0 (0x1UL << RTC_CR_OSEL_Pos) /*!< 0x00200000 */ +#define RTC_CR_OSEL_1 (0x2UL << RTC_CR_OSEL_Pos) /*!< 0x00400000 */ +#define RTC_CR_COE_Pos (23U) +#define RTC_CR_COE_Msk (0x1UL << RTC_CR_COE_Pos) /*!< 0x00800000 */ +#define RTC_CR_COE RTC_CR_COE_Msk +#define RTC_CR_ITSE_Pos (24U) +#define RTC_CR_ITSE_Msk (0x1UL << RTC_CR_ITSE_Pos) /*!< 0x01000000 */ +#define RTC_CR_ITSE RTC_CR_ITSE_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 + + +/******************************************************************************/ +/* */ +/* Secure Advanced Encryption Standard (SAES) */ +/* */ +/******************************************************************************/ +/******************* Bits definition for SAES_CR register *********************/ +#define SAES_CR_EN_Pos (0U) +#define SAES_CR_EN_Msk (0x1UL << SAES_CR_EN_Pos) /*!< 0x00000001 */ +#define SAES_CR_EN SAES_CR_EN_Msk /*!< SAES Enable */ +#define SAES_CR_DATATYPE_Pos (1U) +#define SAES_CR_DATATYPE_Msk (0x3UL << SAES_CR_DATATYPE_Pos) /*!< 0x00000006 */ +#define SAES_CR_DATATYPE SAES_CR_DATATYPE_Msk /*!< Data type selection */ +#define SAES_CR_DATATYPE_0 (0x1UL << SAES_CR_DATATYPE_Pos) /*!< 0x00000002 */ +#define SAES_CR_DATATYPE_1 (0x2UL << SAES_CR_DATATYPE_Pos) /*!< 0x00000004 */ +#define SAES_CR_MODE_Pos (3U) +#define SAES_CR_MODE_Msk (0x3UL << SAES_CR_MODE_Pos) /*!< 0x00000018 */ +#define SAES_CR_MODE SAES_CR_MODE_Msk /*!< SAES Mode Of Operation */ +#define SAES_CR_MODE_0 (0x1UL << SAES_CR_MODE_Pos) /*!< 0x00000008 */ +#define SAES_CR_MODE_1 (0x2UL << SAES_CR_MODE_Pos) /*!< 0x00000010 */ +#define SAES_CR_CHMOD_Pos (5U) +#define SAES_CR_CHMOD_Msk (0x803UL << SAES_CR_CHMOD_Pos) /*!< 0x00010060 */ +#define SAES_CR_CHMOD SAES_CR_CHMOD_Msk /*!< SAES Chaining Mode */ +#define SAES_CR_CHMOD_0 (0x001UL << SAES_CR_CHMOD_Pos) /*!< 0x00000020 */ +#define SAES_CR_CHMOD_1 (0x002UL << SAES_CR_CHMOD_Pos) /*!< 0x00000040 */ +#define SAES_CR_CHMOD_2 (0x800UL << SAES_CR_CHMOD_Pos) /*!< 0x00010000 */ +#define SAES_CR_DMAINEN_Pos (11U) +#define SAES_CR_DMAINEN_Msk (0x1UL << SAES_CR_DMAINEN_Pos) /*!< 0x00000800 */ +#define SAES_CR_DMAINEN SAES_CR_DMAINEN_Msk /*!< Enable data input phase DMA management */ +#define SAES_CR_DMAOUTEN_Pos (12U) +#define SAES_CR_DMAOUTEN_Msk (0x1UL << SAES_CR_DMAOUTEN_Pos) /*!< 0x00001000 */ +#define SAES_CR_DMAOUTEN SAES_CR_DMAOUTEN_Msk /*!< Enable data output phase DMA management */ +#define SAES_CR_GCMPH_Pos (13U) +#define SAES_CR_GCMPH_Msk (0x3UL << SAES_CR_GCMPH_Pos) /*!< 0x00006000 */ +#define SAES_CR_GCMPH SAES_CR_GCMPH_Msk /*!< GCM Phase */ +#define SAES_CR_GCMPH_0 (0x1UL << SAES_CR_GCMPH_Pos) /*!< 0x00002000 */ +#define SAES_CR_GCMPH_1 (0x2UL << SAES_CR_GCMPH_Pos) /*!< 0x00004000 */ +#define SAES_CR_KEYSIZE_Pos (18U) +#define SAES_CR_KEYSIZE_Msk (0x1UL << SAES_CR_KEYSIZE_Pos) /*!< 0x00040000 */ +#define SAES_CR_KEYSIZE SAES_CR_KEYSIZE_Msk /*!< Key size selection */ +#define SAES_CR_NPBLB_Pos (20U) +#define SAES_CR_NPBLB_Msk (0xFUL << SAES_CR_NPBLB_Pos) /*!< 0x00F00000 */ +#define SAES_CR_NPBLB SAES_CR_NPBLB_Msk /*!< Number of padding bytes in payload last block */ +#define SAES_CR_NPBLB_0 (0x1UL << SAES_CR_NPBLB_Pos) /*!< 0x00100000 */ +#define SAES_CR_NPBLB_1 (0x2UL << SAES_CR_NPBLB_Pos) /*!< 0x00200000 */ +#define SAES_CR_NPBLB_2 (0x4UL << SAES_CR_NPBLB_Pos) /*!< 0x00400000 */ +#define SAES_CR_NPBLB_3 (0x8UL << SAES_CR_NPBLB_Pos) /*!< 0x00800000 */ +#define SAES_CR_KMOD_Pos (24U) +#define SAES_CR_KMOD_Msk (0x3UL << SAES_CR_KMOD_Pos) /*!< 0x00000006 */ +#define SAES_CR_KMOD SAES_CR_KMOD_Msk /*!< Key mode selection */ +#define SAES_CR_KMOD_0 (0x1UL << SAES_CR_KMOD_Pos) /*!< 0x01000000 */ +#define SAES_CR_KMOD_1 (0x2UL << SAES_CR_KMOD_Pos) /*!< 0x02000000 */ +#define SAES_CR_KSHAREID_Pos (26U) +#define SAES_CR_KSHAREID_Msk (0x3UL << SAES_CR_KSHAREID_Pos) /*!< 0x00000006 */ +#define SAES_CR_KSHAREID SAES_CR_KSHAREID_Msk /*!< Key Shared ID */ +#define SAES_CR_KEYSEL_Pos (28U) +#define SAES_CR_KEYSEL_Msk (0x7UL << SAES_CR_KEYSEL_Pos) /*!< 0x00000006 */ +#define SAES_CR_KEYSEL SAES_CR_KEYSEL_Msk /*!< Key Selection */ +#define SAES_CR_KEYSEL_0 (0x1UL << SAES_CR_KEYSEL_Pos) /*!< 0x02000000 */ +#define SAES_CR_KEYSEL_1 (0x2UL << SAES_CR_KEYSEL_Pos) /*!< 0x02000000 */ +#define SAES_CR_KEYSEL_2 (0x4UL << SAES_CR_KEYSEL_Pos) /*!< 0x02000000 */ +#define SAES_CR_IPRST_Pos (31U) +#define SAES_CR_IPRST_Msk (0x1UL << SAES_CR_IPRST_Pos) /*!< 0x80000001 */ +#define SAES_CR_IPRST SAES_CR_IPRST_Msk /*!< SAES IP software reset */ + +/******************* Bits definition for SAES_SR register *********************/ +#define SAES_SR_CCF_Pos (0U) +#define SAES_SR_CCF_Msk (0x1UL << SAES_SR_CCF_Pos) /*!< 0x00000001 */ +#define SAES_SR_CCF SAES_SR_CCF_Msk /*!< Computation Complete Flag */ +#define SAES_SR_RDERR_Pos (1U) +#define SAES_SR_RDERR_Msk (0x1UL << SAES_SR_RDERR_Pos) /*!< 0x00000002 */ +#define SAES_SR_RDERR SAES_SR_RDERR_Msk /*!< Read Error Flag */ +#define SAES_SR_WRERR_Pos (2U) +#define SAES_SR_WRERR_Msk (0x1UL << SAES_SR_WRERR_Pos) /*!< 0x00000004 */ +#define SAES_SR_WRERR SAES_SR_WRERR_Msk /*!< Write Error Flag */ +#define SAES_SR_BUSY_Pos (3U) +#define SAES_SR_BUSY_Msk (0x1UL << SAES_SR_BUSY_Pos) /*!< 0x00000008 */ +#define SAES_SR_BUSY SAES_SR_BUSY_Msk /*!< Busy Flag */ +#define SAES_SR_KEYVALID_Pos (7U) +#define SAES_SR_KEYVALID_Msk (0x1UL << SAES_SR_KEYVALID_Pos) /*!< 0x00000008 */ +#define SAES_SR_KEYVALID SAES_SR_KEYVALID_Msk /*!< KEYVALID Flag */ + +/******************* Bits definition for SAES_DINR register *******************/ +#define SAES_DINR_Pos (0U) +#define SAES_DINR_Msk (0xFFFFFFFFUL << SAES_DINR_Pos) /*!< 0xFFFFFFFF */ +#define SAES_DINR SAES_DINR_Msk /*!< SAES Data Input Register */ + +/******************* Bits definition for SAES_DOUTR register ******************/ +#define SAES_DOUTR_Pos (0U) +#define SAES_DOUTR_Msk (0xFFFFFFFFUL << SAES_DOUTR_Pos) /*!< 0xFFFFFFFF */ +#define SAES_DOUTR SAES_DOUTR_Msk /*!< SAES Data Output Register */ + +/******************* Bits definition for SAES_KEYR0 register ******************/ +#define SAES_KEYR0_Pos (0U) +#define SAES_KEYR0_Msk (0xFFFFFFFFUL << SAES_KEYR0_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR0 SAES_KEYR0_Msk /*!< SAES Key Register 0 */ + +/******************* Bits definition for SAES_KEYR1 register ******************/ +#define SAES_KEYR1_Pos (0U) +#define SAES_KEYR1_Msk (0xFFFFFFFFUL << SAES_KEYR1_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR1 SAES_KEYR1_Msk /*!< SAES Key Register 1 */ + +/******************* Bits definition for SAES_KEYR2 register ******************/ +#define SAES_KEYR2_Pos (0U) +#define SAES_KEYR2_Msk (0xFFFFFFFFUL << SAES_KEYR2_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR2 SAES_KEYR2_Msk /*!< SAES Key Register 2 */ + +/******************* Bits definition for SAES_KEYR3 register ******************/ +#define SAES_KEYR3_Pos (0U) +#define SAES_KEYR3_Msk (0xFFFFFFFFUL << SAES_KEYR3_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR3 SAES_KEYR3_Msk /*!< SAES Key Register 3 */ + +/******************* Bits definition for SAES_KEYR4 register ******************/ +#define SAES_KEYR4_Pos (0U) +#define SAES_KEYR4_Msk (0xFFFFFFFFUL << SAES_KEYR4_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR4 SAES_KEYR4_Msk /*!< SAES Key Register 4 */ + +/******************* Bits definition for SAES_KEYR5 register ******************/ +#define SAES_KEYR5_Pos (0U) +#define SAES_KEYR5_Msk (0xFFFFFFFFUL << SAES_KEYR5_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR5 SAES_KEYR5_Msk /*!< SAES Key Register 5 */ + +/******************* Bits definition for SAES_KEYR6 register ******************/ +#define SAES_KEYR6_Pos (0U) +#define SAES_KEYR6_Msk (0xFFFFFFFFUL << SAES_KEYR6_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR6 SAES_KEYR6_Msk /*!< SAES Key Register 6 */ + +/******************* Bits definition for SAES_KEYR7 register ******************/ +#define SAES_KEYR7_Pos (0U) +#define SAES_KEYR7_Msk (0xFFFFFFFFUL << SAES_KEYR7_Pos) /*!< 0xFFFFFFFF */ +#define SAES_KEYR7 SAES_KEYR7_Msk /*!< SAES Key Register 7 */ + +/******************* Bits definition for SAES_IVR0 register ******************/ +#define SAES_IVR0_Pos (0U) +#define SAES_IVR0_Msk (0xFFFFFFFFUL << SAES_IVR0_Pos) /*!< 0xFFFFFFFF */ +#define SAES_IVR0 SAES_IVR0_Msk /*!< SAES Initialization Vector Register 0 */ + +/******************* Bits definition for SAES_IVR1 register ******************/ +#define SAES_IVR1_Pos (0U) +#define SAES_IVR1_Msk (0xFFFFFFFFUL << SAES_IVR1_Pos) /*!< 0xFFFFFFFF */ +#define SAES_IVR1 SAES_IVR1_Msk /*!< SAES Initialization Vector Register 1 */ + +/******************* Bits definition for SAES_IVR2 register ******************/ +#define SAES_IVR2_Pos (0U) +#define SAES_IVR2_Msk (0xFFFFFFFFUL << SAES_IVR2_Pos) /*!< 0xFFFFFFFF */ +#define SAES_IVR2 SAES_IVR2_Msk /*!< SAES Initialization Vector Register 2 */ + +/******************* Bits definition for SAES_IVR3 register ******************/ +#define SAES_IVR3_Pos (0U) +#define SAES_IVR3_Msk (0xFFFFFFFFUL << SAES_IVR3_Pos) /*!< 0xFFFFFFFF */ +#define SAES_IVR3 SAES_IVR3_Msk /*!< SAES Initialization Vector Register 3 */ + +/******************* Bit definition for SAES_SUSP0R register ******************/ +#define SAES_SUSP0R_Pos (0U) +#define SAES_SUSP0R_Msk (0xFFFFFFFFUL << SAES_SUSP0R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP0R SAES_SUSP0R_Msk /*!< SAES Suspend registers 0 */ + +/******************* Bit definition for SAES_SUSP1R register ******************/ +#define SAES_SUSP1R_Pos (0U) +#define SAES_SUSP1R_Msk (0xFFFFFFFFUL << SAES_SUSP1R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP1R SAES_SUSP1R_Msk /*!< SAES Suspend registers 1 */ + +/******************* Bit definition for SAES_SUSP2R register ******************/ +#define SAES_SUSP2R_Pos (0U) +#define SAES_SUSP2R_Msk (0xFFFFFFFFUL << SAES_SUSP2R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP2R SAES_SUSP2R_Msk /*!< SAES Suspend registers 2 */ + +/******************* Bit definition for SAES_SUSP3R register ******************/ +#define SAES_SUSP3R_Pos (0U) +#define SAES_SUSP3R_Msk (0xFFFFFFFFUL << SAES_SUSP3R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP3R SAES_SUSP3R_Msk /*!< SAES Suspend registers 3 */ + +/******************* Bit definition for SAES_SUSP4R register ******************/ +#define SAES_SUSP4R_Pos (0U) +#define SAES_SUSP4R_Msk (0xFFFFFFFFUL << SAES_SUSP4R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP4R SAES_SUSP4R_Msk /*!< SAES Suspend registers 4 */ + +/******************* Bit definition for SAES_SUSP5R register ******************/ +#define SAES_SUSP5R_Pos (0U) +#define SAES_SUSP5R_Msk (0xFFFFFFFFUL << SAES_SUSP5R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP5R SAES_SUSP5R_Msk /*!< AES Suspend registers 5 */ + +/******************* Bit definition for SAES_SUSP6R register ******************/ +#define SAES_SUSP6R_Pos (0U) +#define SAES_SUSP6R_Msk (0xFFFFFFFFUL << SAES_SUSP6R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP6R SAES_SUSP6R_Msk /*!< SAES Suspend registers 6 */ + +/******************* Bit definition for SAES_SUSP7R register ******************/ +#define SAES_SUSP7R_Pos (0U) +#define SAES_SUSP7R_Msk (0xFFFFFFFFUL << SAES_SUSP7R_Pos) /*!< 0xFFFFFFFF */ +#define SAES_SUSP7R SAES_SUSP7R_Msk /*!< SAES Suspend registers 7 */ + +/******************* Bits definition for SAES_IER register ******************/ +#define SAES_IER_CCFIE_Pos (0U) +#define SAES_IER_CCFIE_Msk (0x1UL << SAES_IER_CCFIE_Pos) /*!< 0x00000001 */ +#define SAES_IER_CCFIE SAES_IER_CCFIE_Msk /*!< Computation complete flag interrupt enable */ +#define SAES_IER_RWEIE_Pos (1U) +#define SAES_IER_RWEIE_Msk (0x1UL << SAES_IER_RWEIE_Pos) /*!< 0x00000002 */ +#define SAES_IER_RWEIE SAES_IER_RWEIE_Msk /*!< Read or write error Interrupt Enable */ +#define SAES_IER_KEIE_Pos (2U) +#define SAES_IER_KEIE_Msk (0x1UL << SAES_IER_KEIE_Pos) /*!< 0x00000004 */ +#define SAES_IER_KEIE SAES_IER_KEIE_Msk /*!< Key error interrupt enable */ +#define SAES_IER_RNGEIE_Pos (3U) +#define SAES_IER_RNGEIE_Msk (0x1UL << SAES_IER_RNGEIE_Pos) /*!< 0x00000008 */ +#define SAES_IER_RNGEIE SAES_IER_RNGEIE_Msk /*!< Rng error interrupt enable */ + +/******************* Bits definition for SAES_ISR register ******************/ +#define SAES_ISR_CCF_Pos (0U) +#define SAES_ISR_CCF_Msk (0x1UL << SAES_ISR_CCF_Pos) /*!< 0x00000001 */ +#define SAES_ISR_CCF SAES_ISR_CCF_Msk /*!< Computation complete flag */ +#define SAES_ISR_RWEIF_Pos (1U) +#define SAES_ISR_RWEIF_Msk (0x1UL << SAES_ISR_RWEIF_Pos) /*!< 0x00000002 */ +#define SAES_ISR_RWEIF SAES_ISR_RWEIF_Msk /*!< Read or write error Interrupt flag */ +#define SAES_ISR_KEIF_Pos (2U) +#define SAES_ISR_KEIF_Msk (0x1UL << SAES_ISR_KEIF_Pos) /*!< 0x00000004 */ +#define SAES_ISR_KEIF SAES_ISR_KEIF_Msk /*!< Key error interrupt flag */ +#define SAES_ISR_RNGEIF_Pos (3U) +#define SAES_ISR_RNGEIF_Msk (0x1UL << SAES_ISR_RNGEIF_Pos) /*!< 0x00000008 */ +#define SAES_ISR_RNGEIF SAES_ISR_RNGEIF_Msk /*!< Rng error interrupt flag */ + +/******************* Bits definition for SAES_ICR register ******************/ +#define SAES_ICR_CCF_Pos (0U) +#define SAES_ICR_CCF_Msk (0x1UL << SAES_ICR_CCF_Pos) /*!< 0x00000001 */ +#define SAES_ICR_CCF SAES_ICR_CCF_Msk /*!< Computation complete flag clear */ +#define SAES_ICR_RWEIF_Pos (1U) +#define SAES_ICR_RWEIF_Msk (0x1UL << SAES_ICR_RWEIF_Pos) /*!< 0x00000002 */ +#define SAES_ICR_RWEIF SAES_ICR_RWEIF_Msk /*!< Read or write error Interrupt flag clear */ +#define SAES_ICR_KEIF_Pos (2U) +#define SAES_ICR_KEIF_Msk (0x1UL << SAES_ICR_KEIF_Pos) /*!< 0x00000004 */ +#define SAES_ICR_KEIF SAES_ICR_KEIF_Msk /*!< Key error interrupt flag clear */ +#define SAES_ICR_RNGEIF_Pos (3U) +#define SAES_ICR_RNGEIF_Msk (0x1UL << SAES_ICR_RNGEIF_Pos) /*!< 0x00000008 */ +#define SAES_ICR_RNGEIF SAES_ICR_RNGEIF_Msk /*!< Rng error interrupt flag clear */ + +/******************************************************************************/ +/* */ +/* 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 /*! +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_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) */ + +/** + * @} + */ + +/** @addtogroup STM32H7RSxx_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); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_STM32H7RSXX_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.md b/Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.md new file mode 100644 index 0000000..29f81d8 --- /dev/null +++ b/Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.txt b/Drivers/CMSIS/Device/ST/STM32H7RSxx/LICENSE.txt new file mode 100644 index 0000000..872e82b --- /dev/null +++ b/Drivers/CMSIS/Device/ST/STM32H7RSxx/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/Drivers/CMSIS/Documentation/General/html/LICENSE.txt b/Drivers/CMSIS/Documentation/General/html/LICENSE.txt new file mode 100644 index 0000000..c0ee812 --- /dev/null +++ b/Drivers/CMSIS/Documentation/General/html/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/Drivers/CMSIS/Include/cachel1_armv7.h b/Drivers/CMSIS/Include/cachel1_armv7.h new file mode 100644 index 0000000..efb29d8 --- /dev/null +++ b/Drivers/CMSIS/Include/cachel1_armv7.h @@ -0,0 +1,441 @@ +/****************************************************************************** + * @file cachel1_armv7.h + * @brief CMSIS Level 1 Cache API for Armv7-M and later + * @version V1.0.3 + * @date 17. March 2023 + ******************************************************************************/ +/* + * Copyright (c) 2020-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_CACHEL1_ARMV7_H +#define ARM_CACHEL1_ARMV7_H + +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#ifndef __SCB_DCACHE_LINE_SIZE +#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +#ifndef __SCB_ICACHE_LINE_SIZE +#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief I-Cache Invalidate by address + \details Invalidates I-Cache for the given address. + I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + I-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] isize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if ( isize > 0 ) { + int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_ICACHE_LINE_SIZE; + op_size -= __SCB_ICACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + struct { + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + } locals + #if ((defined(__GNUC__) || defined(__clang__)) && !defined(__OPTIMIZE__)) + __ALIGNED(__SCB_DCACHE_LINE_SIZE) + #endif + ; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + #if !defined(__OPTIMIZE__) + /* + * For the endless loop issue with no optimization builds. + * More details, see https://github.com/ARM-software/CMSIS_5/issues/620 + * + * The issue only happens when local variables are in stack. If + * local variables are saved in general purpose register, then the function + * is OK. + * + * When local variables are in stack, after disabling the cache, flush the + * local variables cache line for data consistency. + */ + /* Clean and invalidate the local variable cache. */ + #if defined(__ICCARM__) + /* As we can't align the stack to the cache line size, invalidate each of the variables */ + SCB->DCCIMVAC = (uint32_t)&locals.sets; + SCB->DCCIMVAC = (uint32_t)&locals.ways; + SCB->DCCIMVAC = (uint32_t)&locals.ccsidr; + #else + SCB->DCCIMVAC = (uint32_t)&locals; + #endif + __DSB(); + __ISB(); + #endif + + locals.ccsidr = SCB->CCSIDR; + /* clean & invalidate D-Cache */ + locals.sets = (uint32_t)(CCSIDR_SETS(locals.ccsidr)); + do { + locals.ways = (uint32_t)(CCSIDR_WAYS(locals.ccsidr)); + do { + SCB->DCCISW = (((locals.sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((locals.ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (locals.ways-- != 0U); + } while(locals.sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ + +#endif /* ARM_CACHEL1_ARMV7_H */ diff --git a/Drivers/CMSIS/Include/cmsis_armcc.h b/Drivers/CMSIS/Include/cmsis_armcc.h new file mode 100644 index 0000000..a955d47 --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_armcc.h @@ -0,0 +1,888 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.3.2 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + /* __ARM_ARCH_8_1M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; + __ISB(); +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/Drivers/CMSIS/Include/cmsis_armclang.h b/Drivers/CMSIS/Include/cmsis_armclang.h new file mode 100644 index 0000000..6911417 --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_armclang.h @@ -0,0 +1,1503 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.4.3 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/Drivers/CMSIS/Include/cmsis_armclang_ltm.h b/Drivers/CMSIS/Include/cmsis_armclang_ltm.h new file mode 100644 index 0000000..1e255d5 --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_armclang_ltm.h @@ -0,0 +1,1928 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.5.3 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/Drivers/CMSIS/Include/cmsis_compiler.h b/Drivers/CMSIS/Include/cmsis_compiler.h new file mode 100644 index 0000000..adbf296 --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_compiler.h @@ -0,0 +1,283 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/Drivers/CMSIS/Include/cmsis_gcc.h b/Drivers/CMSIS/Include/cmsis_gcc.h new file mode 100644 index 0000000..67bda4e --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_gcc.h @@ -0,0 +1,2211 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.4.1 + * @date 27. May 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL __StackSeal +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + } else { + result = __SXTB16(__ROR(op1, rotate)) ; + } + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate)); + } else { + result = __SXTAB16(op1, __ROR(op2, rotate)); + } + return result; +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +#define __PKHBT(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/Drivers/CMSIS/Include/cmsis_iccarm.h b/Drivers/CMSIS/Include/cmsis_iccarm.h new file mode 100644 index 0000000..65b824b --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_iccarm.h @@ -0,0 +1,1002 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.3.0 + * @date 14. April 2021 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2021 IAR Systems +// Copyright (c) 2017-2021 Arm Limited. All rights reserved. +// +// SPDX-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. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#undef __WEAK /* undo the definition from DLib_Defaults.h */ +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + +#ifndef __PROGRAM_START +#define __PROGRAM_START __iar_program_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP CSTACK$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT CSTACK$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __vector_table +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE @".intvec" +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL STACKSEAL$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __arm_wsr("CONTROL", control); + __iar_builtin_ISB(); +} + + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __arm_wsr("CONTROL_NS", control); + __iar_builtin_ISB(); +} + + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM volatile("RRX %0, %1" : "=r"(result) : "r" (value)); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + __iar_builtin_ISB(); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM volatile ("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM volatile ("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM volatile ("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM volatile ("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM volatile ("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM volatile ("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/Drivers/CMSIS/Include/cmsis_version.h b/Drivers/CMSIS/Include/cmsis_version.h new file mode 100644 index 0000000..8b4765f --- /dev/null +++ b/Drivers/CMSIS/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.5 + * @date 02. February 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/Drivers/CMSIS/Include/core_armv81mml.h b/Drivers/CMSIS/Include/core_armv81mml.h new file mode 100644 index 0000000..94128a1 --- /dev/null +++ b/Drivers/CMSIS/Include/core_armv81mml.h @@ -0,0 +1,4228 @@ +/**************************************************************************//** + * @file core_armv81mml.h + * @brief CMSIS Armv8.1-M Mainline Core Peripheral Access Layer Header File + * @version V1.4.2 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_ARMV81MML_H_GENERIC +#define __CORE_ARMV81MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMV81MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS ARMV81MML definitions */ +#define __ARMv81MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv81MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv81MML_CMSIS_VERSION ((__ARMv81MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv81MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +#if defined ( __CC_ARM ) + #error Legacy Arm Compiler does not support Armv8.1-M target architecture. +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV81MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV81MML_H_DEPENDANT +#define __CORE_ARMV81MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv81MML_REV + #define __ARMv81MML_REV 0x0000U + #warning "__ARMv81MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #if __FPU_PRESENT != 0U + #ifndef __FPU_DP + #define __FPU_DP 0U + #warning "__FPU_DP not defined in device header file; using default!" + #endif + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __PMU_PRESENT + #define __PMU_PRESENT 0U + #warning "__PMU_PRESENT not defined in device header file; using default!" + #endif + + #if __PMU_PRESENT != 0U + #ifndef __PMU_NUM_EVENTCNT + #define __PMU_NUM_EVENTCNT 2U + #warning "__PMU_NUM_EVENTCNT not defined in device header file; using default!" + #elif (__PMU_NUM_EVENTCNT > 31 || __PMU_NUM_EVENTCNT < 2) + #error "__PMU_NUM_EVENTCNT is out of range in device header file!" */ + #endif + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv81MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + __IOM uint32_t RFSR; /*!< Offset: 0x204 (R/W) RAS Fault Status Register */ + uint32_t RESERVED4[14U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_IESB_Pos 5U /*!< SCB AIRCR: Implicit ESB Enable Position */ +#define SCB_AIRCR_IESB_Msk (1UL << SCB_AIRCR_IESB_Pos) /*!< SCB AIRCR: Implicit ESB Enable Mask */ + +#define SCB_AIRCR_DIT_Pos 4U /*!< SCB AIRCR: Data Independent Timing Position */ +#define SCB_AIRCR_DIT_Msk (1UL << SCB_AIRCR_DIT_Pos) /*!< SCB AIRCR: Data Independent Timing Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_TRD_Pos 20U /*!< SCB CCR: TRD Position */ +#define SCB_CCR_TRD_Msk (1UL << SCB_CCR_TRD_Pos) /*!< SCB CCR: TRD Mask */ + +#define SCB_CCR_LOB_Pos 19U /*!< SCB CCR: LOB Position */ +#define SCB_CCR_LOB_Msk (1UL << SCB_CCR_LOB_Pos) /*!< SCB CCR: LOB Mask */ + +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_PMU_Pos 5U /*!< SCB DFSR: PMU Position */ +#define SCB_DFSR_PMU_Msk (1UL << SCB_DFSR_PMU_Pos) /*!< SCB DFSR: PMU Mask */ + +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CP7_Pos 7U /*!< SCB NSACR: CP7 Position */ +#define SCB_NSACR_CP7_Msk (1UL << SCB_NSACR_CP7_Pos) /*!< SCB NSACR: CP7 Mask */ + +#define SCB_NSACR_CP6_Pos 6U /*!< SCB NSACR: CP6 Position */ +#define SCB_NSACR_CP6_Msk (1UL << SCB_NSACR_CP6_Pos) /*!< SCB NSACR: CP6 Mask */ + +#define SCB_NSACR_CP5_Pos 5U /*!< SCB NSACR: CP5 Position */ +#define SCB_NSACR_CP5_Msk (1UL << SCB_NSACR_CP5_Pos) /*!< SCB NSACR: CP5 Mask */ + +#define SCB_NSACR_CP4_Pos 4U /*!< SCB NSACR: CP4 Position */ +#define SCB_NSACR_CP4_Msk (1UL << SCB_NSACR_CP4_Pos) /*!< SCB NSACR: CP4 Mask */ + +#define SCB_NSACR_CP3_Pos 3U /*!< SCB NSACR: CP3 Position */ +#define SCB_NSACR_CP3_Msk (1UL << SCB_NSACR_CP3_Pos) /*!< SCB NSACR: CP3 Mask */ + +#define SCB_NSACR_CP2_Pos 2U /*!< SCB NSACR: CP2 Position */ +#define SCB_NSACR_CP2_Msk (1UL << SCB_NSACR_CP2_Pos) /*!< SCB NSACR: CP2 Mask */ + +#define SCB_NSACR_CP1_Pos 1U /*!< SCB NSACR: CP1 Position */ +#define SCB_NSACR_CP1_Msk (1UL << SCB_NSACR_CP1_Pos) /*!< SCB NSACR: CP1 Mask */ + +#define SCB_NSACR_CP0_Pos 0U /*!< SCB NSACR: CP0 Position */ +#define SCB_NSACR_CP0_Msk (1UL /*<< SCB_NSACR_CP0_Pos*/) /*!< SCB NSACR: CP0 Mask */ + +/* SCB Debug Feature Register 0 Definitions */ +#define SCB_ID_DFR_UDE_Pos 28U /*!< SCB ID_DFR: UDE Position */ +#define SCB_ID_DFR_UDE_Msk (0xFUL << SCB_ID_DFR_UDE_Pos) /*!< SCB ID_DFR: UDE Mask */ + +#define SCB_ID_DFR_MProfDbg_Pos 20U /*!< SCB ID_DFR: MProfDbg Position */ +#define SCB_ID_DFR_MProfDbg_Msk (0xFUL << SCB_ID_DFR_MProfDbg_Pos) /*!< SCB ID_DFR: MProfDbg Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB RAS Fault Status Register Definitions */ +#define SCB_RFSR_V_Pos 31U /*!< SCB RFSR: V Position */ +#define SCB_RFSR_V_Msk (1UL << SCB_RFSR_V_Pos) /*!< SCB RFSR: V Mask */ + +#define SCB_RFSR_IS_Pos 16U /*!< SCB RFSR: IS Position */ +#define SCB_RFSR_IS_Msk (0x7FFFUL << SCB_RFSR_IS_Pos) /*!< SCB RFSR: IS Mask */ + +#define SCB_RFSR_UET_Pos 0U /*!< SCB RFSR: UET Position */ +#define SCB_RFSR_UET_Msk (3UL /*<< SCB_RFSR_UET_Pos*/) /*!< SCB RFSR: UET Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[3U]; + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) ITM Device Type Register */ + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFmt_Pos 0U /*!< TPI FFCR: EnFmt Position */ +#define TPI_FFCR_EnFmt_Msk (0x3UL << /*TPI_FFCR_EnFmt_Pos*/) /*!< TPI FFCR: EnFmt Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_PMU Performance Monitoring Unit (PMU) + \brief Type definitions for the Performance Monitoring Unit (PMU) + @{ + */ + +/** + \brief Structure type to access the Performance Monitoring Unit (PMU). + */ +typedef struct +{ + __IOM uint32_t EVCNTR[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x0 (R/W) PMU Event Counter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED0[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCNTR; /*!< Offset: 0x7C (R/W) PMU Cycle Counter Register */ + uint32_t RESERVED1[224]; + __IOM uint32_t EVTYPER[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x400 (R/W) PMU Event Type and Filter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED2[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCFILTR; /*!< Offset: 0x47C (R/W) PMU Cycle Counter Filter Register */ + uint32_t RESERVED3[480]; + __IOM uint32_t CNTENSET; /*!< Offset: 0xC00 (R/W) PMU Count Enable Set Register */ + uint32_t RESERVED4[7]; + __IOM uint32_t CNTENCLR; /*!< Offset: 0xC20 (R/W) PMU Count Enable Clear Register */ + uint32_t RESERVED5[7]; + __IOM uint32_t INTENSET; /*!< Offset: 0xC40 (R/W) PMU Interrupt Enable Set Register */ + uint32_t RESERVED6[7]; + __IOM uint32_t INTENCLR; /*!< Offset: 0xC60 (R/W) PMU Interrupt Enable Clear Register */ + uint32_t RESERVED7[7]; + __IOM uint32_t OVSCLR; /*!< Offset: 0xC80 (R/W) PMU Overflow Flag Status Clear Register */ + uint32_t RESERVED8[7]; + __IOM uint32_t SWINC; /*!< Offset: 0xCA0 (R/W) PMU Software Increment Register */ + uint32_t RESERVED9[7]; + __IOM uint32_t OVSSET; /*!< Offset: 0xCC0 (R/W) PMU Overflow Flag Status Set Register */ + uint32_t RESERVED10[79]; + __IOM uint32_t TYPE; /*!< Offset: 0xE00 (R/W) PMU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0xE04 (R/W) PMU Control Register */ + uint32_t RESERVED11[108]; + __IOM uint32_t AUTHSTATUS; /*!< Offset: 0xFB8 (R/W) PMU Authentication Status Register */ + __IOM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/W) PMU Device Architecture Register */ + uint32_t RESERVED12[3]; + __IOM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/W) PMU Device Type Register */ + __IOM uint32_t PIDR4; /*!< Offset: 0xFD0 (R/W) PMU Peripheral Identification Register 4 */ + uint32_t RESERVED13[3]; + __IOM uint32_t PIDR0; /*!< Offset: 0xFE0 (R/W) PMU Peripheral Identification Register 0 */ + __IOM uint32_t PIDR1; /*!< Offset: 0xFE4 (R/W) PMU Peripheral Identification Register 1 */ + __IOM uint32_t PIDR2; /*!< Offset: 0xFE8 (R/W) PMU Peripheral Identification Register 2 */ + __IOM uint32_t PIDR3; /*!< Offset: 0xFEC (R/W) PMU Peripheral Identification Register 3 */ + __IOM uint32_t CIDR0; /*!< Offset: 0xFF0 (R/W) PMU Component Identification Register 0 */ + __IOM uint32_t CIDR1; /*!< Offset: 0xFF4 (R/W) PMU Component Identification Register 1 */ + __IOM uint32_t CIDR2; /*!< Offset: 0xFF8 (R/W) PMU Component Identification Register 2 */ + __IOM uint32_t CIDR3; /*!< Offset: 0xFFC (R/W) PMU Component Identification Register 3 */ +} PMU_Type; + +/** \brief PMU Event Counter Registers (0-30) Definitions */ + +#define PMU_EVCNTR_CNT_Pos 0U /*!< PMU EVCNTR: Counter Position */ +#define PMU_EVCNTR_CNT_Msk (0xFFFFUL /*<< PMU_EVCNTRx_CNT_Pos*/) /*!< PMU EVCNTR: Counter Mask */ + +/** \brief PMU Event Type and Filter Registers (0-30) Definitions */ + +#define PMU_EVTYPER_EVENTTOCNT_Pos 0U /*!< PMU EVTYPER: Event to Count Position */ +#define PMU_EVTYPER_EVENTTOCNT_Msk (0xFFFFUL /*<< EVTYPERx_EVENTTOCNT_Pos*/) /*!< PMU EVTYPER: Event to Count Mask */ + +/** \brief PMU Count Enable Set Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENSET: Event Counter 0 Enable Set Position */ +#define PMU_CNTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENSET_CNT0_ENABLE_Pos*/) /*!< PMU CNTENSET: Event Counter 0 Enable Set Mask */ + +#define PMU_CNTENSET_CNT1_ENABLE_Pos 1U /*!< PMU CNTENSET: Event Counter 1 Enable Set Position */ +#define PMU_CNTENSET_CNT1_ENABLE_Msk (1UL << PMU_CNTENSET_CNT1_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 1 Enable Set Mask */ + +#define PMU_CNTENSET_CNT2_ENABLE_Pos 2U /*!< PMU CNTENSET: Event Counter 2 Enable Set Position */ +#define PMU_CNTENSET_CNT2_ENABLE_Msk (1UL << PMU_CNTENSET_CNT2_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 2 Enable Set Mask */ + +#define PMU_CNTENSET_CNT3_ENABLE_Pos 3U /*!< PMU CNTENSET: Event Counter 3 Enable Set Position */ +#define PMU_CNTENSET_CNT3_ENABLE_Msk (1UL << PMU_CNTENSET_CNT3_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 3 Enable Set Mask */ + +#define PMU_CNTENSET_CNT4_ENABLE_Pos 4U /*!< PMU CNTENSET: Event Counter 4 Enable Set Position */ +#define PMU_CNTENSET_CNT4_ENABLE_Msk (1UL << PMU_CNTENSET_CNT4_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 4 Enable Set Mask */ + +#define PMU_CNTENSET_CNT5_ENABLE_Pos 5U /*!< PMU CNTENSET: Event Counter 5 Enable Set Position */ +#define PMU_CNTENSET_CNT5_ENABLE_Msk (1UL << PMU_CNTENSET_CNT5_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 5 Enable Set Mask */ + +#define PMU_CNTENSET_CNT6_ENABLE_Pos 6U /*!< PMU CNTENSET: Event Counter 6 Enable Set Position */ +#define PMU_CNTENSET_CNT6_ENABLE_Msk (1UL << PMU_CNTENSET_CNT6_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 6 Enable Set Mask */ + +#define PMU_CNTENSET_CNT7_ENABLE_Pos 7U /*!< PMU CNTENSET: Event Counter 7 Enable Set Position */ +#define PMU_CNTENSET_CNT7_ENABLE_Msk (1UL << PMU_CNTENSET_CNT7_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 7 Enable Set Mask */ + +#define PMU_CNTENSET_CNT8_ENABLE_Pos 8U /*!< PMU CNTENSET: Event Counter 8 Enable Set Position */ +#define PMU_CNTENSET_CNT8_ENABLE_Msk (1UL << PMU_CNTENSET_CNT8_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 8 Enable Set Mask */ + +#define PMU_CNTENSET_CNT9_ENABLE_Pos 9U /*!< PMU CNTENSET: Event Counter 9 Enable Set Position */ +#define PMU_CNTENSET_CNT9_ENABLE_Msk (1UL << PMU_CNTENSET_CNT9_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 9 Enable Set Mask */ + +#define PMU_CNTENSET_CNT10_ENABLE_Pos 10U /*!< PMU CNTENSET: Event Counter 10 Enable Set Position */ +#define PMU_CNTENSET_CNT10_ENABLE_Msk (1UL << PMU_CNTENSET_CNT10_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 10 Enable Set Mask */ + +#define PMU_CNTENSET_CNT11_ENABLE_Pos 11U /*!< PMU CNTENSET: Event Counter 11 Enable Set Position */ +#define PMU_CNTENSET_CNT11_ENABLE_Msk (1UL << PMU_CNTENSET_CNT11_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 11 Enable Set Mask */ + +#define PMU_CNTENSET_CNT12_ENABLE_Pos 12U /*!< PMU CNTENSET: Event Counter 12 Enable Set Position */ +#define PMU_CNTENSET_CNT12_ENABLE_Msk (1UL << PMU_CNTENSET_CNT12_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 12 Enable Set Mask */ + +#define PMU_CNTENSET_CNT13_ENABLE_Pos 13U /*!< PMU CNTENSET: Event Counter 13 Enable Set Position */ +#define PMU_CNTENSET_CNT13_ENABLE_Msk (1UL << PMU_CNTENSET_CNT13_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 13 Enable Set Mask */ + +#define PMU_CNTENSET_CNT14_ENABLE_Pos 14U /*!< PMU CNTENSET: Event Counter 14 Enable Set Position */ +#define PMU_CNTENSET_CNT14_ENABLE_Msk (1UL << PMU_CNTENSET_CNT14_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 14 Enable Set Mask */ + +#define PMU_CNTENSET_CNT15_ENABLE_Pos 15U /*!< PMU CNTENSET: Event Counter 15 Enable Set Position */ +#define PMU_CNTENSET_CNT15_ENABLE_Msk (1UL << PMU_CNTENSET_CNT15_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 15 Enable Set Mask */ + +#define PMU_CNTENSET_CNT16_ENABLE_Pos 16U /*!< PMU CNTENSET: Event Counter 16 Enable Set Position */ +#define PMU_CNTENSET_CNT16_ENABLE_Msk (1UL << PMU_CNTENSET_CNT16_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 16 Enable Set Mask */ + +#define PMU_CNTENSET_CNT17_ENABLE_Pos 17U /*!< PMU CNTENSET: Event Counter 17 Enable Set Position */ +#define PMU_CNTENSET_CNT17_ENABLE_Msk (1UL << PMU_CNTENSET_CNT17_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 17 Enable Set Mask */ + +#define PMU_CNTENSET_CNT18_ENABLE_Pos 18U /*!< PMU CNTENSET: Event Counter 18 Enable Set Position */ +#define PMU_CNTENSET_CNT18_ENABLE_Msk (1UL << PMU_CNTENSET_CNT18_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 18 Enable Set Mask */ + +#define PMU_CNTENSET_CNT19_ENABLE_Pos 19U /*!< PMU CNTENSET: Event Counter 19 Enable Set Position */ +#define PMU_CNTENSET_CNT19_ENABLE_Msk (1UL << PMU_CNTENSET_CNT19_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 19 Enable Set Mask */ + +#define PMU_CNTENSET_CNT20_ENABLE_Pos 20U /*!< PMU CNTENSET: Event Counter 20 Enable Set Position */ +#define PMU_CNTENSET_CNT20_ENABLE_Msk (1UL << PMU_CNTENSET_CNT20_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 20 Enable Set Mask */ + +#define PMU_CNTENSET_CNT21_ENABLE_Pos 21U /*!< PMU CNTENSET: Event Counter 21 Enable Set Position */ +#define PMU_CNTENSET_CNT21_ENABLE_Msk (1UL << PMU_CNTENSET_CNT21_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 21 Enable Set Mask */ + +#define PMU_CNTENSET_CNT22_ENABLE_Pos 22U /*!< PMU CNTENSET: Event Counter 22 Enable Set Position */ +#define PMU_CNTENSET_CNT22_ENABLE_Msk (1UL << PMU_CNTENSET_CNT22_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 22 Enable Set Mask */ + +#define PMU_CNTENSET_CNT23_ENABLE_Pos 23U /*!< PMU CNTENSET: Event Counter 23 Enable Set Position */ +#define PMU_CNTENSET_CNT23_ENABLE_Msk (1UL << PMU_CNTENSET_CNT23_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 23 Enable Set Mask */ + +#define PMU_CNTENSET_CNT24_ENABLE_Pos 24U /*!< PMU CNTENSET: Event Counter 24 Enable Set Position */ +#define PMU_CNTENSET_CNT24_ENABLE_Msk (1UL << PMU_CNTENSET_CNT24_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 24 Enable Set Mask */ + +#define PMU_CNTENSET_CNT25_ENABLE_Pos 25U /*!< PMU CNTENSET: Event Counter 25 Enable Set Position */ +#define PMU_CNTENSET_CNT25_ENABLE_Msk (1UL << PMU_CNTENSET_CNT25_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 25 Enable Set Mask */ + +#define PMU_CNTENSET_CNT26_ENABLE_Pos 26U /*!< PMU CNTENSET: Event Counter 26 Enable Set Position */ +#define PMU_CNTENSET_CNT26_ENABLE_Msk (1UL << PMU_CNTENSET_CNT26_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 26 Enable Set Mask */ + +#define PMU_CNTENSET_CNT27_ENABLE_Pos 27U /*!< PMU CNTENSET: Event Counter 27 Enable Set Position */ +#define PMU_CNTENSET_CNT27_ENABLE_Msk (1UL << PMU_CNTENSET_CNT27_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 27 Enable Set Mask */ + +#define PMU_CNTENSET_CNT28_ENABLE_Pos 28U /*!< PMU CNTENSET: Event Counter 28 Enable Set Position */ +#define PMU_CNTENSET_CNT28_ENABLE_Msk (1UL << PMU_CNTENSET_CNT28_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 28 Enable Set Mask */ + +#define PMU_CNTENSET_CNT29_ENABLE_Pos 29U /*!< PMU CNTENSET: Event Counter 29 Enable Set Position */ +#define PMU_CNTENSET_CNT29_ENABLE_Msk (1UL << PMU_CNTENSET_CNT29_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 29 Enable Set Mask */ + +#define PMU_CNTENSET_CNT30_ENABLE_Pos 30U /*!< PMU CNTENSET: Event Counter 30 Enable Set Position */ +#define PMU_CNTENSET_CNT30_ENABLE_Msk (1UL << PMU_CNTENSET_CNT30_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 30 Enable Set Mask */ + +#define PMU_CNTENSET_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENSET: Cycle Counter Enable Set Position */ +#define PMU_CNTENSET_CCNTR_ENABLE_Msk (1UL << PMU_CNTENSET_CCNTR_ENABLE_Pos) /*!< PMU CNTENSET: Cycle Counter Enable Set Mask */ + +/** \brief PMU Count Enable Clear Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Position */ +#define PMU_CNTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU CNTENCLR: Event Counter 1 Enable Clear Position */ +#define PMU_CNTENCLR_CNT1_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT1_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 1 Enable Clear */ + +#define PMU_CNTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Position */ +#define PMU_CNTENCLR_CNT2_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT2_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Position */ +#define PMU_CNTENCLR_CNT3_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT3_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Position */ +#define PMU_CNTENCLR_CNT4_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT4_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Position */ +#define PMU_CNTENCLR_CNT5_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT5_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Position */ +#define PMU_CNTENCLR_CNT6_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT6_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Position */ +#define PMU_CNTENCLR_CNT7_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT7_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Position */ +#define PMU_CNTENCLR_CNT8_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT8_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Position */ +#define PMU_CNTENCLR_CNT9_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT9_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Position */ +#define PMU_CNTENCLR_CNT10_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT10_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Position */ +#define PMU_CNTENCLR_CNT11_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT11_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Position */ +#define PMU_CNTENCLR_CNT12_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT12_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Position */ +#define PMU_CNTENCLR_CNT13_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT13_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Position */ +#define PMU_CNTENCLR_CNT14_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT14_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Position */ +#define PMU_CNTENCLR_CNT15_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT15_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Position */ +#define PMU_CNTENCLR_CNT16_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT16_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Position */ +#define PMU_CNTENCLR_CNT17_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT17_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Position */ +#define PMU_CNTENCLR_CNT18_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT18_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Position */ +#define PMU_CNTENCLR_CNT19_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT19_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Position */ +#define PMU_CNTENCLR_CNT20_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT20_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Position */ +#define PMU_CNTENCLR_CNT21_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT21_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Position */ +#define PMU_CNTENCLR_CNT22_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT22_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Position */ +#define PMU_CNTENCLR_CNT23_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT23_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Position */ +#define PMU_CNTENCLR_CNT24_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT24_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Position */ +#define PMU_CNTENCLR_CNT25_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT25_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Position */ +#define PMU_CNTENCLR_CNT26_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT26_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Position */ +#define PMU_CNTENCLR_CNT27_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT27_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Position */ +#define PMU_CNTENCLR_CNT28_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT28_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Position */ +#define PMU_CNTENCLR_CNT29_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT29_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Position */ +#define PMU_CNTENCLR_CNT30_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT30_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Mask */ + +#define PMU_CNTENCLR_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENCLR: Cycle Counter Enable Clear Position */ +#define PMU_CNTENCLR_CCNTR_ENABLE_Msk (1UL << PMU_CNTENCLR_CCNTR_ENABLE_Pos) /*!< PMU CNTENCLR: Cycle Counter Enable Clear Mask */ + +/** \brief PMU Interrupt Enable Set Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENSET_CNT0_ENABLE_Pos*/) /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT1_ENABLE_Pos 1U /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT1_ENABLE_Msk (1UL << PMU_INTENSET_CNT1_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT2_ENABLE_Pos 2U /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT2_ENABLE_Msk (1UL << PMU_INTENSET_CNT2_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT3_ENABLE_Pos 3U /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT3_ENABLE_Msk (1UL << PMU_INTENSET_CNT3_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT4_ENABLE_Pos 4U /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT4_ENABLE_Msk (1UL << PMU_INTENSET_CNT4_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT5_ENABLE_Pos 5U /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT5_ENABLE_Msk (1UL << PMU_INTENSET_CNT5_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT6_ENABLE_Pos 6U /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT6_ENABLE_Msk (1UL << PMU_INTENSET_CNT6_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT7_ENABLE_Pos 7U /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT7_ENABLE_Msk (1UL << PMU_INTENSET_CNT7_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT8_ENABLE_Pos 8U /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT8_ENABLE_Msk (1UL << PMU_INTENSET_CNT8_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT9_ENABLE_Pos 9U /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT9_ENABLE_Msk (1UL << PMU_INTENSET_CNT9_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT10_ENABLE_Pos 10U /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT10_ENABLE_Msk (1UL << PMU_INTENSET_CNT10_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT11_ENABLE_Pos 11U /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT11_ENABLE_Msk (1UL << PMU_INTENSET_CNT11_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT12_ENABLE_Pos 12U /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT12_ENABLE_Msk (1UL << PMU_INTENSET_CNT12_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT13_ENABLE_Pos 13U /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT13_ENABLE_Msk (1UL << PMU_INTENSET_CNT13_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT14_ENABLE_Pos 14U /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT14_ENABLE_Msk (1UL << PMU_INTENSET_CNT14_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT15_ENABLE_Pos 15U /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT15_ENABLE_Msk (1UL << PMU_INTENSET_CNT15_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT16_ENABLE_Pos 16U /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT16_ENABLE_Msk (1UL << PMU_INTENSET_CNT16_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT17_ENABLE_Pos 17U /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT17_ENABLE_Msk (1UL << PMU_INTENSET_CNT17_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT18_ENABLE_Pos 18U /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT18_ENABLE_Msk (1UL << PMU_INTENSET_CNT18_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT19_ENABLE_Pos 19U /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT19_ENABLE_Msk (1UL << PMU_INTENSET_CNT19_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT20_ENABLE_Pos 20U /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT20_ENABLE_Msk (1UL << PMU_INTENSET_CNT20_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT21_ENABLE_Pos 21U /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT21_ENABLE_Msk (1UL << PMU_INTENSET_CNT21_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT22_ENABLE_Pos 22U /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT22_ENABLE_Msk (1UL << PMU_INTENSET_CNT22_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT23_ENABLE_Pos 23U /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT23_ENABLE_Msk (1UL << PMU_INTENSET_CNT23_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT24_ENABLE_Pos 24U /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT24_ENABLE_Msk (1UL << PMU_INTENSET_CNT24_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT25_ENABLE_Pos 25U /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT25_ENABLE_Msk (1UL << PMU_INTENSET_CNT25_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT26_ENABLE_Pos 26U /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT26_ENABLE_Msk (1UL << PMU_INTENSET_CNT26_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT27_ENABLE_Pos 27U /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT27_ENABLE_Msk (1UL << PMU_INTENSET_CNT27_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT28_ENABLE_Pos 28U /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT28_ENABLE_Msk (1UL << PMU_INTENSET_CNT28_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT29_ENABLE_Pos 29U /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT29_ENABLE_Msk (1UL << PMU_INTENSET_CNT29_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT30_ENABLE_Pos 30U /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT30_ENABLE_Msk (1UL << PMU_INTENSET_CNT30_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Position */ +#define PMU_INTENSET_CCYCNT_ENABLE_Msk (1UL << PMU_INTENSET_CYCCNT_ENABLE_Pos) /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Mask */ + +/** \brief PMU Interrupt Enable Clear Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT1_ENABLE_Msk (1UL << PMU_INTENCLR_CNT1_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear */ + +#define PMU_INTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT2_ENABLE_Msk (1UL << PMU_INTENCLR_CNT2_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT3_ENABLE_Msk (1UL << PMU_INTENCLR_CNT3_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT4_ENABLE_Msk (1UL << PMU_INTENCLR_CNT4_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT5_ENABLE_Msk (1UL << PMU_INTENCLR_CNT5_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT6_ENABLE_Msk (1UL << PMU_INTENCLR_CNT6_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT7_ENABLE_Msk (1UL << PMU_INTENCLR_CNT7_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT8_ENABLE_Msk (1UL << PMU_INTENCLR_CNT8_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT9_ENABLE_Msk (1UL << PMU_INTENCLR_CNT9_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT10_ENABLE_Msk (1UL << PMU_INTENCLR_CNT10_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT11_ENABLE_Msk (1UL << PMU_INTENCLR_CNT11_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT12_ENABLE_Msk (1UL << PMU_INTENCLR_CNT12_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT13_ENABLE_Msk (1UL << PMU_INTENCLR_CNT13_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT14_ENABLE_Msk (1UL << PMU_INTENCLR_CNT14_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT15_ENABLE_Msk (1UL << PMU_INTENCLR_CNT15_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT16_ENABLE_Msk (1UL << PMU_INTENCLR_CNT16_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT17_ENABLE_Msk (1UL << PMU_INTENCLR_CNT17_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT18_ENABLE_Msk (1UL << PMU_INTENCLR_CNT18_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT19_ENABLE_Msk (1UL << PMU_INTENCLR_CNT19_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT20_ENABLE_Msk (1UL << PMU_INTENCLR_CNT20_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT21_ENABLE_Msk (1UL << PMU_INTENCLR_CNT21_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT22_ENABLE_Msk (1UL << PMU_INTENCLR_CNT22_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT23_ENABLE_Msk (1UL << PMU_INTENCLR_CNT23_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT24_ENABLE_Msk (1UL << PMU_INTENCLR_CNT24_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT25_ENABLE_Msk (1UL << PMU_INTENCLR_CNT25_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT26_ENABLE_Msk (1UL << PMU_INTENCLR_CNT26_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT27_ENABLE_Msk (1UL << PMU_INTENCLR_CNT27_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT28_ENABLE_Msk (1UL << PMU_INTENCLR_CNT28_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT29_ENABLE_Msk (1UL << PMU_INTENCLR_CNT29_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT30_ENABLE_Msk (1UL << PMU_INTENCLR_CNT30_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CYCCNT_ENABLE_Msk (1UL << PMU_INTENCLR_CYCCNT_ENABLE_Pos) /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Mask */ + +/** \brief PMU Overflow Flag Status Set Register Definitions */ + +#define PMU_OVSSET_CNT0_STATUS_Pos 0U /*!< PMU OVSSET: Event Counter 0 Overflow Set Position */ +#define PMU_OVSSET_CNT0_STATUS_Msk (1UL /*<< PMU_OVSSET_CNT0_STATUS_Pos*/) /*!< PMU OVSSET: Event Counter 0 Overflow Set Mask */ + +#define PMU_OVSSET_CNT1_STATUS_Pos 1U /*!< PMU OVSSET: Event Counter 1 Overflow Set Position */ +#define PMU_OVSSET_CNT1_STATUS_Msk (1UL << PMU_OVSSET_CNT1_STATUS_Pos) /*!< PMU OVSSET: Event Counter 1 Overflow Set Mask */ + +#define PMU_OVSSET_CNT2_STATUS_Pos 2U /*!< PMU OVSSET: Event Counter 2 Overflow Set Position */ +#define PMU_OVSSET_CNT2_STATUS_Msk (1UL << PMU_OVSSET_CNT2_STATUS_Pos) /*!< PMU OVSSET: Event Counter 2 Overflow Set Mask */ + +#define PMU_OVSSET_CNT3_STATUS_Pos 3U /*!< PMU OVSSET: Event Counter 3 Overflow Set Position */ +#define PMU_OVSSET_CNT3_STATUS_Msk (1UL << PMU_OVSSET_CNT3_STATUS_Pos) /*!< PMU OVSSET: Event Counter 3 Overflow Set Mask */ + +#define PMU_OVSSET_CNT4_STATUS_Pos 4U /*!< PMU OVSSET: Event Counter 4 Overflow Set Position */ +#define PMU_OVSSET_CNT4_STATUS_Msk (1UL << PMU_OVSSET_CNT4_STATUS_Pos) /*!< PMU OVSSET: Event Counter 4 Overflow Set Mask */ + +#define PMU_OVSSET_CNT5_STATUS_Pos 5U /*!< PMU OVSSET: Event Counter 5 Overflow Set Position */ +#define PMU_OVSSET_CNT5_STATUS_Msk (1UL << PMU_OVSSET_CNT5_STATUS_Pos) /*!< PMU OVSSET: Event Counter 5 Overflow Set Mask */ + +#define PMU_OVSSET_CNT6_STATUS_Pos 6U /*!< PMU OVSSET: Event Counter 6 Overflow Set Position */ +#define PMU_OVSSET_CNT6_STATUS_Msk (1UL << PMU_OVSSET_CNT6_STATUS_Pos) /*!< PMU OVSSET: Event Counter 6 Overflow Set Mask */ + +#define PMU_OVSSET_CNT7_STATUS_Pos 7U /*!< PMU OVSSET: Event Counter 7 Overflow Set Position */ +#define PMU_OVSSET_CNT7_STATUS_Msk (1UL << PMU_OVSSET_CNT7_STATUS_Pos) /*!< PMU OVSSET: Event Counter 7 Overflow Set Mask */ + +#define PMU_OVSSET_CNT8_STATUS_Pos 8U /*!< PMU OVSSET: Event Counter 8 Overflow Set Position */ +#define PMU_OVSSET_CNT8_STATUS_Msk (1UL << PMU_OVSSET_CNT8_STATUS_Pos) /*!< PMU OVSSET: Event Counter 8 Overflow Set Mask */ + +#define PMU_OVSSET_CNT9_STATUS_Pos 9U /*!< PMU OVSSET: Event Counter 9 Overflow Set Position */ +#define PMU_OVSSET_CNT9_STATUS_Msk (1UL << PMU_OVSSET_CNT9_STATUS_Pos) /*!< PMU OVSSET: Event Counter 9 Overflow Set Mask */ + +#define PMU_OVSSET_CNT10_STATUS_Pos 10U /*!< PMU OVSSET: Event Counter 10 Overflow Set Position */ +#define PMU_OVSSET_CNT10_STATUS_Msk (1UL << PMU_OVSSET_CNT10_STATUS_Pos) /*!< PMU OVSSET: Event Counter 10 Overflow Set Mask */ + +#define PMU_OVSSET_CNT11_STATUS_Pos 11U /*!< PMU OVSSET: Event Counter 11 Overflow Set Position */ +#define PMU_OVSSET_CNT11_STATUS_Msk (1UL << PMU_OVSSET_CNT11_STATUS_Pos) /*!< PMU OVSSET: Event Counter 11 Overflow Set Mask */ + +#define PMU_OVSSET_CNT12_STATUS_Pos 12U /*!< PMU OVSSET: Event Counter 12 Overflow Set Position */ +#define PMU_OVSSET_CNT12_STATUS_Msk (1UL << PMU_OVSSET_CNT12_STATUS_Pos) /*!< PMU OVSSET: Event Counter 12 Overflow Set Mask */ + +#define PMU_OVSSET_CNT13_STATUS_Pos 13U /*!< PMU OVSSET: Event Counter 13 Overflow Set Position */ +#define PMU_OVSSET_CNT13_STATUS_Msk (1UL << PMU_OVSSET_CNT13_STATUS_Pos) /*!< PMU OVSSET: Event Counter 13 Overflow Set Mask */ + +#define PMU_OVSSET_CNT14_STATUS_Pos 14U /*!< PMU OVSSET: Event Counter 14 Overflow Set Position */ +#define PMU_OVSSET_CNT14_STATUS_Msk (1UL << PMU_OVSSET_CNT14_STATUS_Pos) /*!< PMU OVSSET: Event Counter 14 Overflow Set Mask */ + +#define PMU_OVSSET_CNT15_STATUS_Pos 15U /*!< PMU OVSSET: Event Counter 15 Overflow Set Position */ +#define PMU_OVSSET_CNT15_STATUS_Msk (1UL << PMU_OVSSET_CNT15_STATUS_Pos) /*!< PMU OVSSET: Event Counter 15 Overflow Set Mask */ + +#define PMU_OVSSET_CNT16_STATUS_Pos 16U /*!< PMU OVSSET: Event Counter 16 Overflow Set Position */ +#define PMU_OVSSET_CNT16_STATUS_Msk (1UL << PMU_OVSSET_CNT16_STATUS_Pos) /*!< PMU OVSSET: Event Counter 16 Overflow Set Mask */ + +#define PMU_OVSSET_CNT17_STATUS_Pos 17U /*!< PMU OVSSET: Event Counter 17 Overflow Set Position */ +#define PMU_OVSSET_CNT17_STATUS_Msk (1UL << PMU_OVSSET_CNT17_STATUS_Pos) /*!< PMU OVSSET: Event Counter 17 Overflow Set Mask */ + +#define PMU_OVSSET_CNT18_STATUS_Pos 18U /*!< PMU OVSSET: Event Counter 18 Overflow Set Position */ +#define PMU_OVSSET_CNT18_STATUS_Msk (1UL << PMU_OVSSET_CNT18_STATUS_Pos) /*!< PMU OVSSET: Event Counter 18 Overflow Set Mask */ + +#define PMU_OVSSET_CNT19_STATUS_Pos 19U /*!< PMU OVSSET: Event Counter 19 Overflow Set Position */ +#define PMU_OVSSET_CNT19_STATUS_Msk (1UL << PMU_OVSSET_CNT19_STATUS_Pos) /*!< PMU OVSSET: Event Counter 19 Overflow Set Mask */ + +#define PMU_OVSSET_CNT20_STATUS_Pos 20U /*!< PMU OVSSET: Event Counter 20 Overflow Set Position */ +#define PMU_OVSSET_CNT20_STATUS_Msk (1UL << PMU_OVSSET_CNT20_STATUS_Pos) /*!< PMU OVSSET: Event Counter 20 Overflow Set Mask */ + +#define PMU_OVSSET_CNT21_STATUS_Pos 21U /*!< PMU OVSSET: Event Counter 21 Overflow Set Position */ +#define PMU_OVSSET_CNT21_STATUS_Msk (1UL << PMU_OVSSET_CNT21_STATUS_Pos) /*!< PMU OVSSET: Event Counter 21 Overflow Set Mask */ + +#define PMU_OVSSET_CNT22_STATUS_Pos 22U /*!< PMU OVSSET: Event Counter 22 Overflow Set Position */ +#define PMU_OVSSET_CNT22_STATUS_Msk (1UL << PMU_OVSSET_CNT22_STATUS_Pos) /*!< PMU OVSSET: Event Counter 22 Overflow Set Mask */ + +#define PMU_OVSSET_CNT23_STATUS_Pos 23U /*!< PMU OVSSET: Event Counter 23 Overflow Set Position */ +#define PMU_OVSSET_CNT23_STATUS_Msk (1UL << PMU_OVSSET_CNT23_STATUS_Pos) /*!< PMU OVSSET: Event Counter 23 Overflow Set Mask */ + +#define PMU_OVSSET_CNT24_STATUS_Pos 24U /*!< PMU OVSSET: Event Counter 24 Overflow Set Position */ +#define PMU_OVSSET_CNT24_STATUS_Msk (1UL << PMU_OVSSET_CNT24_STATUS_Pos) /*!< PMU OVSSET: Event Counter 24 Overflow Set Mask */ + +#define PMU_OVSSET_CNT25_STATUS_Pos 25U /*!< PMU OVSSET: Event Counter 25 Overflow Set Position */ +#define PMU_OVSSET_CNT25_STATUS_Msk (1UL << PMU_OVSSET_CNT25_STATUS_Pos) /*!< PMU OVSSET: Event Counter 25 Overflow Set Mask */ + +#define PMU_OVSSET_CNT26_STATUS_Pos 26U /*!< PMU OVSSET: Event Counter 26 Overflow Set Position */ +#define PMU_OVSSET_CNT26_STATUS_Msk (1UL << PMU_OVSSET_CNT26_STATUS_Pos) /*!< PMU OVSSET: Event Counter 26 Overflow Set Mask */ + +#define PMU_OVSSET_CNT27_STATUS_Pos 27U /*!< PMU OVSSET: Event Counter 27 Overflow Set Position */ +#define PMU_OVSSET_CNT27_STATUS_Msk (1UL << PMU_OVSSET_CNT27_STATUS_Pos) /*!< PMU OVSSET: Event Counter 27 Overflow Set Mask */ + +#define PMU_OVSSET_CNT28_STATUS_Pos 28U /*!< PMU OVSSET: Event Counter 28 Overflow Set Position */ +#define PMU_OVSSET_CNT28_STATUS_Msk (1UL << PMU_OVSSET_CNT28_STATUS_Pos) /*!< PMU OVSSET: Event Counter 28 Overflow Set Mask */ + +#define PMU_OVSSET_CNT29_STATUS_Pos 29U /*!< PMU OVSSET: Event Counter 29 Overflow Set Position */ +#define PMU_OVSSET_CNT29_STATUS_Msk (1UL << PMU_OVSSET_CNT29_STATUS_Pos) /*!< PMU OVSSET: Event Counter 29 Overflow Set Mask */ + +#define PMU_OVSSET_CNT30_STATUS_Pos 30U /*!< PMU OVSSET: Event Counter 30 Overflow Set Position */ +#define PMU_OVSSET_CNT30_STATUS_Msk (1UL << PMU_OVSSET_CNT30_STATUS_Pos) /*!< PMU OVSSET: Event Counter 30 Overflow Set Mask */ + +#define PMU_OVSSET_CYCCNT_STATUS_Pos 31U /*!< PMU OVSSET: Cycle Counter Overflow Set Position */ +#define PMU_OVSSET_CYCCNT_STATUS_Msk (1UL << PMU_OVSSET_CYCCNT_STATUS_Pos) /*!< PMU OVSSET: Cycle Counter Overflow Set Mask */ + +/** \brief PMU Overflow Flag Status Clear Register Definitions */ + +#define PMU_OVSCLR_CNT0_STATUS_Pos 0U /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Position */ +#define PMU_OVSCLR_CNT0_STATUS_Msk (1UL /*<< PMU_OVSCLR_CNT0_STATUS_Pos*/) /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT1_STATUS_Pos 1U /*!< PMU OVSCLR: Event Counter 1 Overflow Clear Position */ +#define PMU_OVSCLR_CNT1_STATUS_Msk (1UL << PMU_OVSCLR_CNT1_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 1 Overflow Clear */ + +#define PMU_OVSCLR_CNT2_STATUS_Pos 2U /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Position */ +#define PMU_OVSCLR_CNT2_STATUS_Msk (1UL << PMU_OVSCLR_CNT2_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT3_STATUS_Pos 3U /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Position */ +#define PMU_OVSCLR_CNT3_STATUS_Msk (1UL << PMU_OVSCLR_CNT3_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT4_STATUS_Pos 4U /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Position */ +#define PMU_OVSCLR_CNT4_STATUS_Msk (1UL << PMU_OVSCLR_CNT4_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT5_STATUS_Pos 5U /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Position */ +#define PMU_OVSCLR_CNT5_STATUS_Msk (1UL << PMU_OVSCLR_CNT5_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT6_STATUS_Pos 6U /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Position */ +#define PMU_OVSCLR_CNT6_STATUS_Msk (1UL << PMU_OVSCLR_CNT6_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT7_STATUS_Pos 7U /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Position */ +#define PMU_OVSCLR_CNT7_STATUS_Msk (1UL << PMU_OVSCLR_CNT7_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT8_STATUS_Pos 8U /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Position */ +#define PMU_OVSCLR_CNT8_STATUS_Msk (1UL << PMU_OVSCLR_CNT8_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT9_STATUS_Pos 9U /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Position */ +#define PMU_OVSCLR_CNT9_STATUS_Msk (1UL << PMU_OVSCLR_CNT9_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT10_STATUS_Pos 10U /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Position */ +#define PMU_OVSCLR_CNT10_STATUS_Msk (1UL << PMU_OVSCLR_CNT10_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT11_STATUS_Pos 11U /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Position */ +#define PMU_OVSCLR_CNT11_STATUS_Msk (1UL << PMU_OVSCLR_CNT11_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT12_STATUS_Pos 12U /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Position */ +#define PMU_OVSCLR_CNT12_STATUS_Msk (1UL << PMU_OVSCLR_CNT12_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT13_STATUS_Pos 13U /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Position */ +#define PMU_OVSCLR_CNT13_STATUS_Msk (1UL << PMU_OVSCLR_CNT13_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT14_STATUS_Pos 14U /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Position */ +#define PMU_OVSCLR_CNT14_STATUS_Msk (1UL << PMU_OVSCLR_CNT14_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT15_STATUS_Pos 15U /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Position */ +#define PMU_OVSCLR_CNT15_STATUS_Msk (1UL << PMU_OVSCLR_CNT15_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT16_STATUS_Pos 16U /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Position */ +#define PMU_OVSCLR_CNT16_STATUS_Msk (1UL << PMU_OVSCLR_CNT16_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT17_STATUS_Pos 17U /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Position */ +#define PMU_OVSCLR_CNT17_STATUS_Msk (1UL << PMU_OVSCLR_CNT17_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT18_STATUS_Pos 18U /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Position */ +#define PMU_OVSCLR_CNT18_STATUS_Msk (1UL << PMU_OVSCLR_CNT18_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT19_STATUS_Pos 19U /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Position */ +#define PMU_OVSCLR_CNT19_STATUS_Msk (1UL << PMU_OVSCLR_CNT19_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT20_STATUS_Pos 20U /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Position */ +#define PMU_OVSCLR_CNT20_STATUS_Msk (1UL << PMU_OVSCLR_CNT20_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT21_STATUS_Pos 21U /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Position */ +#define PMU_OVSCLR_CNT21_STATUS_Msk (1UL << PMU_OVSCLR_CNT21_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT22_STATUS_Pos 22U /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Position */ +#define PMU_OVSCLR_CNT22_STATUS_Msk (1UL << PMU_OVSCLR_CNT22_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT23_STATUS_Pos 23U /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Position */ +#define PMU_OVSCLR_CNT23_STATUS_Msk (1UL << PMU_OVSCLR_CNT23_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT24_STATUS_Pos 24U /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Position */ +#define PMU_OVSCLR_CNT24_STATUS_Msk (1UL << PMU_OVSCLR_CNT24_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT25_STATUS_Pos 25U /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Position */ +#define PMU_OVSCLR_CNT25_STATUS_Msk (1UL << PMU_OVSCLR_CNT25_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT26_STATUS_Pos 26U /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Position */ +#define PMU_OVSCLR_CNT26_STATUS_Msk (1UL << PMU_OVSCLR_CNT26_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT27_STATUS_Pos 27U /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Position */ +#define PMU_OVSCLR_CNT27_STATUS_Msk (1UL << PMU_OVSCLR_CNT27_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT28_STATUS_Pos 28U /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Position */ +#define PMU_OVSCLR_CNT28_STATUS_Msk (1UL << PMU_OVSCLR_CNT28_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT29_STATUS_Pos 29U /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Position */ +#define PMU_OVSCLR_CNT29_STATUS_Msk (1UL << PMU_OVSCLR_CNT29_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT30_STATUS_Pos 30U /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Position */ +#define PMU_OVSCLR_CNT30_STATUS_Msk (1UL << PMU_OVSCLR_CNT30_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Mask */ + +#define PMU_OVSCLR_CYCCNT_STATUS_Pos 31U /*!< PMU OVSCLR: Cycle Counter Overflow Clear Position */ +#define PMU_OVSCLR_CYCCNT_STATUS_Msk (1UL << PMU_OVSCLR_CYCCNT_STATUS_Pos) /*!< PMU OVSCLR: Cycle Counter Overflow Clear Mask */ + +/** \brief PMU Software Increment Counter */ + +#define PMU_SWINC_CNT0_Pos 0U /*!< PMU SWINC: Event Counter 0 Software Increment Position */ +#define PMU_SWINC_CNT0_Msk (1UL /*<< PMU_SWINC_CNT0_Pos */) /*!< PMU SWINC: Event Counter 0 Software Increment Mask */ + +#define PMU_SWINC_CNT1_Pos 1U /*!< PMU SWINC: Event Counter 1 Software Increment Position */ +#define PMU_SWINC_CNT1_Msk (1UL << PMU_SWINC_CNT1_Pos) /*!< PMU SWINC: Event Counter 1 Software Increment Mask */ + +#define PMU_SWINC_CNT2_Pos 2U /*!< PMU SWINC: Event Counter 2 Software Increment Position */ +#define PMU_SWINC_CNT2_Msk (1UL << PMU_SWINC_CNT2_Pos) /*!< PMU SWINC: Event Counter 2 Software Increment Mask */ + +#define PMU_SWINC_CNT3_Pos 3U /*!< PMU SWINC: Event Counter 3 Software Increment Position */ +#define PMU_SWINC_CNT3_Msk (1UL << PMU_SWINC_CNT3_Pos) /*!< PMU SWINC: Event Counter 3 Software Increment Mask */ + +#define PMU_SWINC_CNT4_Pos 4U /*!< PMU SWINC: Event Counter 4 Software Increment Position */ +#define PMU_SWINC_CNT4_Msk (1UL << PMU_SWINC_CNT4_Pos) /*!< PMU SWINC: Event Counter 4 Software Increment Mask */ + +#define PMU_SWINC_CNT5_Pos 5U /*!< PMU SWINC: Event Counter 5 Software Increment Position */ +#define PMU_SWINC_CNT5_Msk (1UL << PMU_SWINC_CNT5_Pos) /*!< PMU SWINC: Event Counter 5 Software Increment Mask */ + +#define PMU_SWINC_CNT6_Pos 6U /*!< PMU SWINC: Event Counter 6 Software Increment Position */ +#define PMU_SWINC_CNT6_Msk (1UL << PMU_SWINC_CNT6_Pos) /*!< PMU SWINC: Event Counter 6 Software Increment Mask */ + +#define PMU_SWINC_CNT7_Pos 7U /*!< PMU SWINC: Event Counter 7 Software Increment Position */ +#define PMU_SWINC_CNT7_Msk (1UL << PMU_SWINC_CNT7_Pos) /*!< PMU SWINC: Event Counter 7 Software Increment Mask */ + +#define PMU_SWINC_CNT8_Pos 8U /*!< PMU SWINC: Event Counter 8 Software Increment Position */ +#define PMU_SWINC_CNT8_Msk (1UL << PMU_SWINC_CNT8_Pos) /*!< PMU SWINC: Event Counter 8 Software Increment Mask */ + +#define PMU_SWINC_CNT9_Pos 9U /*!< PMU SWINC: Event Counter 9 Software Increment Position */ +#define PMU_SWINC_CNT9_Msk (1UL << PMU_SWINC_CNT9_Pos) /*!< PMU SWINC: Event Counter 9 Software Increment Mask */ + +#define PMU_SWINC_CNT10_Pos 10U /*!< PMU SWINC: Event Counter 10 Software Increment Position */ +#define PMU_SWINC_CNT10_Msk (1UL << PMU_SWINC_CNT10_Pos) /*!< PMU SWINC: Event Counter 10 Software Increment Mask */ + +#define PMU_SWINC_CNT11_Pos 11U /*!< PMU SWINC: Event Counter 11 Software Increment Position */ +#define PMU_SWINC_CNT11_Msk (1UL << PMU_SWINC_CNT11_Pos) /*!< PMU SWINC: Event Counter 11 Software Increment Mask */ + +#define PMU_SWINC_CNT12_Pos 12U /*!< PMU SWINC: Event Counter 12 Software Increment Position */ +#define PMU_SWINC_CNT12_Msk (1UL << PMU_SWINC_CNT12_Pos) /*!< PMU SWINC: Event Counter 12 Software Increment Mask */ + +#define PMU_SWINC_CNT13_Pos 13U /*!< PMU SWINC: Event Counter 13 Software Increment Position */ +#define PMU_SWINC_CNT13_Msk (1UL << PMU_SWINC_CNT13_Pos) /*!< PMU SWINC: Event Counter 13 Software Increment Mask */ + +#define PMU_SWINC_CNT14_Pos 14U /*!< PMU SWINC: Event Counter 14 Software Increment Position */ +#define PMU_SWINC_CNT14_Msk (1UL << PMU_SWINC_CNT14_Pos) /*!< PMU SWINC: Event Counter 14 Software Increment Mask */ + +#define PMU_SWINC_CNT15_Pos 15U /*!< PMU SWINC: Event Counter 15 Software Increment Position */ +#define PMU_SWINC_CNT15_Msk (1UL << PMU_SWINC_CNT15_Pos) /*!< PMU SWINC: Event Counter 15 Software Increment Mask */ + +#define PMU_SWINC_CNT16_Pos 16U /*!< PMU SWINC: Event Counter 16 Software Increment Position */ +#define PMU_SWINC_CNT16_Msk (1UL << PMU_SWINC_CNT16_Pos) /*!< PMU SWINC: Event Counter 16 Software Increment Mask */ + +#define PMU_SWINC_CNT17_Pos 17U /*!< PMU SWINC: Event Counter 17 Software Increment Position */ +#define PMU_SWINC_CNT17_Msk (1UL << PMU_SWINC_CNT17_Pos) /*!< PMU SWINC: Event Counter 17 Software Increment Mask */ + +#define PMU_SWINC_CNT18_Pos 18U /*!< PMU SWINC: Event Counter 18 Software Increment Position */ +#define PMU_SWINC_CNT18_Msk (1UL << PMU_SWINC_CNT18_Pos) /*!< PMU SWINC: Event Counter 18 Software Increment Mask */ + +#define PMU_SWINC_CNT19_Pos 19U /*!< PMU SWINC: Event Counter 19 Software Increment Position */ +#define PMU_SWINC_CNT19_Msk (1UL << PMU_SWINC_CNT19_Pos) /*!< PMU SWINC: Event Counter 19 Software Increment Mask */ + +#define PMU_SWINC_CNT20_Pos 20U /*!< PMU SWINC: Event Counter 20 Software Increment Position */ +#define PMU_SWINC_CNT20_Msk (1UL << PMU_SWINC_CNT20_Pos) /*!< PMU SWINC: Event Counter 20 Software Increment Mask */ + +#define PMU_SWINC_CNT21_Pos 21U /*!< PMU SWINC: Event Counter 21 Software Increment Position */ +#define PMU_SWINC_CNT21_Msk (1UL << PMU_SWINC_CNT21_Pos) /*!< PMU SWINC: Event Counter 21 Software Increment Mask */ + +#define PMU_SWINC_CNT22_Pos 22U /*!< PMU SWINC: Event Counter 22 Software Increment Position */ +#define PMU_SWINC_CNT22_Msk (1UL << PMU_SWINC_CNT22_Pos) /*!< PMU SWINC: Event Counter 22 Software Increment Mask */ + +#define PMU_SWINC_CNT23_Pos 23U /*!< PMU SWINC: Event Counter 23 Software Increment Position */ +#define PMU_SWINC_CNT23_Msk (1UL << PMU_SWINC_CNT23_Pos) /*!< PMU SWINC: Event Counter 23 Software Increment Mask */ + +#define PMU_SWINC_CNT24_Pos 24U /*!< PMU SWINC: Event Counter 24 Software Increment Position */ +#define PMU_SWINC_CNT24_Msk (1UL << PMU_SWINC_CNT24_Pos) /*!< PMU SWINC: Event Counter 24 Software Increment Mask */ + +#define PMU_SWINC_CNT25_Pos 25U /*!< PMU SWINC: Event Counter 25 Software Increment Position */ +#define PMU_SWINC_CNT25_Msk (1UL << PMU_SWINC_CNT25_Pos) /*!< PMU SWINC: Event Counter 25 Software Increment Mask */ + +#define PMU_SWINC_CNT26_Pos 26U /*!< PMU SWINC: Event Counter 26 Software Increment Position */ +#define PMU_SWINC_CNT26_Msk (1UL << PMU_SWINC_CNT26_Pos) /*!< PMU SWINC: Event Counter 26 Software Increment Mask */ + +#define PMU_SWINC_CNT27_Pos 27U /*!< PMU SWINC: Event Counter 27 Software Increment Position */ +#define PMU_SWINC_CNT27_Msk (1UL << PMU_SWINC_CNT27_Pos) /*!< PMU SWINC: Event Counter 27 Software Increment Mask */ + +#define PMU_SWINC_CNT28_Pos 28U /*!< PMU SWINC: Event Counter 28 Software Increment Position */ +#define PMU_SWINC_CNT28_Msk (1UL << PMU_SWINC_CNT28_Pos) /*!< PMU SWINC: Event Counter 28 Software Increment Mask */ + +#define PMU_SWINC_CNT29_Pos 29U /*!< PMU SWINC: Event Counter 29 Software Increment Position */ +#define PMU_SWINC_CNT29_Msk (1UL << PMU_SWINC_CNT29_Pos) /*!< PMU SWINC: Event Counter 29 Software Increment Mask */ + +#define PMU_SWINC_CNT30_Pos 30U /*!< PMU SWINC: Event Counter 30 Software Increment Position */ +#define PMU_SWINC_CNT30_Msk (1UL << PMU_SWINC_CNT30_Pos) /*!< PMU SWINC: Event Counter 30 Software Increment Mask */ + +/** \brief PMU Control Register Definitions */ + +#define PMU_CTRL_ENABLE_Pos 0U /*!< PMU CTRL: ENABLE Position */ +#define PMU_CTRL_ENABLE_Msk (1UL /*<< PMU_CTRL_ENABLE_Pos*/) /*!< PMU CTRL: ENABLE Mask */ + +#define PMU_CTRL_EVENTCNT_RESET_Pos 1U /*!< PMU CTRL: Event Counter Reset Position */ +#define PMU_CTRL_EVENTCNT_RESET_Msk (1UL << PMU_CTRL_EVENTCNT_RESET_Pos) /*!< PMU CTRL: Event Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_RESET_Pos 2U /*!< PMU CTRL: Cycle Counter Reset Position */ +#define PMU_CTRL_CYCCNT_RESET_Msk (1UL << PMU_CTRL_CYCCNT_RESET_Pos) /*!< PMU CTRL: Cycle Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_DISABLE_Pos 5U /*!< PMU CTRL: Disable Cycle Counter Position */ +#define PMU_CTRL_CYCCNT_DISABLE_Msk (1UL << PMU_CTRL_CYCCNT_DISABLE_Pos) /*!< PMU CTRL: Disable Cycle Counter Mask */ + +#define PMU_CTRL_FRZ_ON_OV_Pos 9U /*!< PMU CTRL: Freeze-on-overflow Position */ +#define PMU_CTRL_FRZ_ON_OV_Msk (1UL << PMU_CTRL_FRZ_ON_OVERFLOW_Pos) /*!< PMU CTRL: Freeze-on-overflow Mask */ + +#define PMU_CTRL_TRACE_ON_OV_Pos 11U /*!< PMU CTRL: Trace-on-overflow Position */ +#define PMU_CTRL_TRACE_ON_OV_Msk (1UL << PMU_CTRL_TRACE_ON_OVERFLOW_Pos) /*!< PMU CTRL: Trace-on-overflow Mask */ + +/** \brief PMU Type Register Definitions */ + +#define PMU_TYPE_NUM_CNTS_Pos 0U /*!< PMU TYPE: Number of Counters Position */ +#define PMU_TYPE_NUM_CNTS_Msk (0xFFUL /*<< PMU_TYPE_NUM_CNTS_Pos*/) /*!< PMU TYPE: Number of Counters Mask */ + +#define PMU_TYPE_SIZE_CNTS_Pos 8U /*!< PMU TYPE: Size of Counters Position */ +#define PMU_TYPE_SIZE_CNTS_Msk (0x3FUL << PMU_TYPE_SIZE_CNTS_Pos) /*!< PMU TYPE: Size of Counters Mask */ + +#define PMU_TYPE_CYCCNT_PRESENT_Pos 14U /*!< PMU TYPE: Cycle Counter Present Position */ +#define PMU_TYPE_CYCCNT_PRESENT_Msk (1UL << PMU_TYPE_CYCCNT_PRESENT_Pos) /*!< PMU TYPE: Cycle Counter Present Mask */ + +#define PMU_TYPE_FRZ_OV_SUPPORT_Pos 21U /*!< PMU TYPE: Freeze-on-overflow Support Position */ +#define PMU_TYPE_FRZ_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Freeze-on-overflow Support Mask */ + +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Pos 23U /*!< PMU TYPE: Trace-on-overflow Support Position */ +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Trace-on-overflow Support Mask */ + +/** \brief PMU Authentication Status Register Definitions */ + +#define PMU_AUTHSTATUS_NSID_Pos 0U /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSID_Msk (0x3UL /*<< PMU_AUTHSTATUS_NSID_Pos*/) /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSNID_Pos 2U /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSNID_Msk (0x3UL << PMU_AUTHSTATUS_NSNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SID_Pos 4U /*!< PMU AUTHSTATUS: Secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_SID_Msk (0x3UL << PMU_AUTHSTATUS_SID_Pos) /*!< PMU AUTHSTATUS: Secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SNID_Pos 6U /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SNID_Msk (0x3UL << PMU_AUTHSTATUS_SNID_Pos) /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUID_Pos 16U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUID_Msk (0x3UL << PMU_AUTHSTATUS_NSUID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUNID_Pos 18U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUNID_Msk (0x3UL << PMU_AUTHSTATUS_NSUNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUID_Pos 20U /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_SUID_Msk (0x3UL << PMU_AUTHSTATUS_SUID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUNID_Pos 22U /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SUNID_Msk (0x3UL << PMU_AUTHSTATUS_SUNID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Mask */ + +/*@} end of group CMSIS_PMU */ +#endif + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +#define FPU_FPDSCR_FZ16_Pos 19U /*!< FPDSCR: FZ16 bit Position */ +#define FPU_FPDSCR_FZ16_Msk (1UL << FPU_FPDSCR_FZ16_Pos) /*!< FPDSCR: FZ16 bit Mask */ + +#define FPU_FPDSCR_LTPSIZE_Pos 16U /*!< FPDSCR: LTPSIZE bit Position */ +#define FPU_FPDSCR_LTPSIZE_Msk (7UL << FPU_FPDSCR_LTPSIZE_Pos) /*!< FPDSCR: LTPSIZE bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FPRound_Pos 28U /*!< MVFR0: FPRound bits Position */ +#define FPU_MVFR0_FPRound_Msk (0xFUL << FPU_MVFR0_FPRound_Pos) /*!< MVFR0: FPRound bits Mask */ + +#define FPU_MVFR0_FPSqrt_Pos 20U /*!< MVFR0: FPSqrt bits Position */ +#define FPU_MVFR0_FPSqrt_Msk (0xFUL << FPU_MVFR0_FPSqrt_Pos) /*!< MVFR0: FPSqrt bits Mask */ + +#define FPU_MVFR0_FPDivide_Pos 16U /*!< MVFR0: FPDivide bits Position */ +#define FPU_MVFR0_FPDivide_Msk (0xFUL << FPU_MVFR0_FPDivide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FPDP_Pos 8U /*!< MVFR0: FPDP bits Position */ +#define FPU_MVFR0_FPDP_Msk (0xFUL << FPU_MVFR0_FPDP_Pos) /*!< MVFR0: FPDP bits Mask */ + +#define FPU_MVFR0_FPSP_Pos 4U /*!< MVFR0: FPSP bits Position */ +#define FPU_MVFR0_FPSP_Msk (0xFUL << FPU_MVFR0_FPSP_Pos) /*!< MVFR0: FPSP bits Mask */ + +#define FPU_MVFR0_SIMDReg_Pos 0U /*!< MVFR0: SIMDReg bits Position */ +#define FPU_MVFR0_SIMDReg_Msk (0xFUL /*<< FPU_MVFR0_SIMDReg_Pos*/) /*!< MVFR0: SIMDReg bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FMAC_Pos 28U /*!< MVFR1: FMAC bits Position */ +#define FPU_MVFR1_FMAC_Msk (0xFUL << FPU_MVFR1_FMAC_Pos) /*!< MVFR1: FMAC bits Mask */ + +#define FPU_MVFR1_FPHP_Pos 24U /*!< MVFR1: FPHP bits Position */ +#define FPU_MVFR1_FPHP_Msk (0xFUL << FPU_MVFR1_FPHP_Pos) /*!< MVFR1: FPHP bits Mask */ + +#define FPU_MVFR1_FP16_Pos 20U /*!< MVFR1: FP16 bits Position */ +#define FPU_MVFR1_FP16_Msk (0xFUL << FPU_MVFR1_FP16_Pos) /*!< MVFR1: FP16 bits Mask */ + +#define FPU_MVFR1_MVE_Pos 8U /*!< MVFR1: MVE bits Position */ +#define FPU_MVFR1_MVE_Msk (0xFUL << FPU_MVFR1_MVE_Pos) /*!< MVFR1: MVE bits Mask */ + +#define FPU_MVFR1_FPDNaN_Pos 4U /*!< MVFR1: FPDNaN bits Position */ +#define FPU_MVFR1_FPDNaN_Msk (0xFUL << FPU_MVFR1_FPDNaN_Pos) /*!< MVFR1: FPDNaN bits Mask */ + +#define FPU_MVFR1_FPFtZ_Pos 0U /*!< MVFR1: FPFtZ bits Position */ +#define FPU_MVFR1_FPFtZ_Msk (0xFUL /*<< FPU_MVFR1_FPFtZ_Pos*/) /*!< MVFR1: FPFtZ bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_FPD_Pos 23U /*!< \deprecated CoreDebug DHCSR: S_FPD Position */ +#define CoreDebug_DHCSR_S_FPD_Msk (1UL << CoreDebug_DHCSR_S_FPD_Pos) /*!< \deprecated CoreDebug DHCSR: S_FPD Mask */ + +#define CoreDebug_DHCSR_S_SUIDE_Pos 22U /*!< \deprecated CoreDebug DHCSR: S_SUIDE Position */ +#define CoreDebug_DHCSR_S_SUIDE_Msk (1UL << CoreDebug_DHCSR_S_SUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SUIDE Mask */ + +#define CoreDebug_DHCSR_S_NSUIDE_Pos 21U /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Position */ +#define CoreDebug_DHCSR_S_NSUIDE_Msk (1UL << CoreDebug_DHCSR_S_NSUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Mask */ + +#define CoreDebug_DHCSR_S_SDE_Pos 20U /*!< \deprecated CoreDebug DHCSR: S_SDE Position */ +#define CoreDebug_DHCSR_S_SDE_Msk (1UL << CoreDebug_DHCSR_S_SDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SDE Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_PMOV_Pos 6U /*!< \deprecated CoreDebug DHCSR: C_PMOV Position */ +#define CoreDebug_DHCSR_C_PMOV_Msk (1UL << CoreDebug_DHCSR_C_PMOV_Pos) /*!< \deprecated CoreDebug DHCSR: C_PMOV Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Set Clear Exception and Monitor Control Register Definitions */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_REQ_Pos 3U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_SET_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_PEND_Pos 1U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_SET_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_UIDEN_Pos 10U /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_UIDAPEN_Pos 9U /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDAPEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDAPEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Mask */ + +#define CoreDebug_DAUTHCTRL_FSDMA_Pos 8U /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Position */ +#define CoreDebug_DAUTHCTRL_FSDMA_Msk (1UL << CoreDebug_DAUTHCTRL_FSDMA_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_FPD_Pos 23U /*!< DCB DHCSR: Floating-point registers Debuggable Position */ +#define DCB_DHCSR_S_FPD_Msk (0x1UL << DCB_DHCSR_S_FPD_Pos) /*!< DCB DHCSR: Floating-point registers Debuggable Mask */ + +#define DCB_DHCSR_S_SUIDE_Pos 22U /*!< DCB DHCSR: Secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_SUIDE_Msk (0x1UL << DCB_DHCSR_S_SUIDE_Pos) /*!< DCB DHCSR: Secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_NSUIDE_Pos 21U /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_NSUIDE_Msk (0x1UL << DCB_DHCSR_S_NSUIDE_Pos) /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_PMOV_Pos 6U /*!< DCB DHCSR: Halt on PMU overflow control Position */ +#define DCB_DHCSR_C_PMOV_Msk (0x1UL << DCB_DHCSR_C_PMOV_Pos) /*!< DCB DHCSR: Halt on PMU overflow control Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DSCEMCR, Debug Set Clear Exception and Monitor Control Register Definitions */ +#define DCB_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< DCB DSCEMCR: Clear monitor request Position */ +#define DCB_DSCEMCR_CLR_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_REQ_Pos) /*!< DCB DSCEMCR: Clear monitor request Mask */ + +#define DCB_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< DCB DSCEMCR: Clear monitor pend Position */ +#define DCB_DSCEMCR_CLR_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_PEND_Pos) /*!< DCB DSCEMCR: Clear monitor pend Mask */ + +#define DCB_DSCEMCR_SET_MON_REQ_Pos 3U /*!< DCB DSCEMCR: Set monitor request Position */ +#define DCB_DSCEMCR_SET_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_SET_MON_REQ_Pos) /*!< DCB DSCEMCR: Set monitor request Mask */ + +#define DCB_DSCEMCR_SET_MON_PEND_Pos 1U /*!< DCB DSCEMCR: Set monitor pend Position */ +#define DCB_DSCEMCR_SET_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_SET_MON_PEND_Pos) /*!< DCB DSCEMCR: Set monitor pend Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_UIDEN_Pos 10U /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Position */ +#define DCB_DAUTHCTRL_UIDEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Mask */ + +#define DCB_DAUTHCTRL_UIDAPEN_Pos 9U /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Position */ +#define DCB_DAUTHCTRL_UIDAPEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDAPEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Mask */ + +#define DCB_DAUTHCTRL_FSDMA_Pos 8U /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Position */ +#define DCB_DAUTHCTRL_FSDMA_Msk (0x1UL << DCB_DAUTHCTRL_FSDMA_Pos) /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Mask */ + +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SUNID_Pos 22U /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUNID_Msk (0x3UL << DIB_DAUTHSTATUS_SUNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SUID_Pos 20U /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUID_Msk (0x3UL << DIB_DAUTHSTATUS_SUID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_NSUNID_Pos 18U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Position */ +#define DIB_DAUTHSTATUS_NSUNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Mask */ + +#define DIB_DAUTHSTATUS_NSUID_Pos 16U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_NSUID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + #define PMU_BASE (0xE0003000UL) /*!< PMU Base Address */ + #define PMU ((PMU_Type *) PMU_BASE ) /*!< PMU configuration struct */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## PMU functions and events #################################### */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + +#include "pmu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + +/* ########################## MVE functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_MveFunctions MVE Functions + \brief Function that provides MVE type. + @{ + */ + +/** + \brief get MVE type + \details returns the MVE type + \returns + - \b 0: No Vector Extension (MVE) + - \b 1: Integer Vector Extension (MVE-I) + - \b 2: Floating-point Vector Extension (MVE-F) + */ +__STATIC_INLINE uint32_t SCB_GetMVEType(void) +{ + const uint32_t mvfr1 = FPU->MVFR1; + if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x2U << FPU_MVFR1_MVE_Pos)) + { + return 2U; + } + else if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x1U << FPU_MVFR1_MVE_Pos)) + { + return 1U; + } + else + { + return 0U; + } +} + + +/*@} end of CMSIS_Core_MveFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV81MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_armv8mbl.h b/Drivers/CMSIS/Include/core_armv8mbl.h new file mode 100644 index 0000000..932d3d1 --- /dev/null +++ b/Drivers/CMSIS/Include/core_armv8mbl.h @@ -0,0 +1,2222 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 27. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< \deprecated CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_armv8mml.h b/Drivers/CMSIS/Include/core_armv8mml.h new file mode 100644 index 0000000..c119fbf --- /dev/null +++ b/Drivers/CMSIS/Include/core_armv8mml.h @@ -0,0 +1,3209 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.2.3 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (80U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm0.h b/Drivers/CMSIS/Include/core_cm0.h new file mode 100644 index 0000000..6441ff3 --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm0.h @@ -0,0 +1,952 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 21. August 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + *(vectors + (int32_t)IRQn) = vector; /* use pointer arithmetic to access vector */ + /* ARM Application Note 321 states that the M0 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + return *(vectors + (int32_t)IRQn); /* use pointer arithmetic to access vector */ +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm0plus.h b/Drivers/CMSIS/Include/core_cm0plus.h new file mode 100644 index 0000000..4e7179a --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm0plus.h @@ -0,0 +1,1087 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.9 + * @date 21. August 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +#else + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + *(vectors + (int32_t)IRQn) = vector; /* use pointer arithmetic to access vector */ +#endif + /* ARM Application Note 321 states that the M0+ does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +#else + uint32_t *vectors = (uint32_t *)(NVIC_USER_IRQ_OFFSET << 2); /* point to 1st user interrupt */ + return *(vectors + (int32_t)IRQn); /* use pointer arithmetic to access vector */ +#endif +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm1.h b/Drivers/CMSIS/Include/core_cm1.h new file mode 100644 index 0000000..76b4569 --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm1.h @@ -0,0 +1,979 @@ +/**************************************************************************//** + * @file core_cm1.h + * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File + * @version V1.0.1 + * @date 12. November 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM1_H_GENERIC +#define __CORE_CM1_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M1 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM1 definitions */ +#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ + __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (1U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM1_H_DEPENDANT +#define __CORE_CM1_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM1_REV + #define __CM1_REV 0x0100U + #warning "__CM1_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ + +#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M1 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M1 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm23.h b/Drivers/CMSIS/Include/core_cm23.h new file mode 100644 index 0000000..55fff99 --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm23.h @@ -0,0 +1,2297 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.1.0 + * @date 11. February 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM23_H_GENERIC +#define __CORE_CM23_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M23 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< \deprecated CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm3.h b/Drivers/CMSIS/Include/core_cm3.h new file mode 100644 index 0000000..74fb87e --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm3.h @@ -0,0 +1,1943 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ +#endif + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm33.h b/Drivers/CMSIS/Include/core_cm33.h new file mode 100644 index 0000000..18a2e6f --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm33.h @@ -0,0 +1,3277 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.2.3 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm35p.h b/Drivers/CMSIS/Include/core_cm35p.h new file mode 100644 index 0000000..3843d95 --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm35p.h @@ -0,0 +1,3277 @@ +/**************************************************************************//** + * @file core_cm35p.h + * @brief CMSIS Cortex-M35P Core Peripheral Access Layer Header File + * @version V1.1.3 + * @date 13. October 2021 + ******************************************************************************/ +/* + * Copyright (c) 2018-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM35P_H_GENERIC +#define __CORE_CM35P_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M35P + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM35P definitions */ +#define __CM35P_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM35P_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM35P_CMSIS_VERSION ((__CM35P_CMSIS_VERSION_MAIN << 16U) | \ + __CM35P_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (35U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM35P_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM35P_H_DEPENDANT +#define __CORE_CM35P_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM35P_REV + #define __CM35P_REV 0x0000U + #warning "__CM35P_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M35P */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM35P_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm4.h b/Drivers/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000..e21cd14 --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm4.h @@ -0,0 +1,2129 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.2 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm55.h b/Drivers/CMSIS/Include/core_cm55.h new file mode 100644 index 0000000..faa30ce --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm55.h @@ -0,0 +1,4817 @@ +/**************************************************************************//** + * @file core_cm55.h + * @brief CMSIS Cortex-M55 Core Peripheral Access Layer Header File + * @version V1.2.4 + * @date 21. April 2022 + ******************************************************************************/ +/* + * Copyright (c) 2018-2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM55_H_GENERIC +#define __CORE_CM55_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M55 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM55 definitions */ +#define __CM55_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM55_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM55_CMSIS_VERSION ((__CM55_CMSIS_VERSION_MAIN << 16U) | \ + __CM55_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (55U) /*!< Cortex-M Core */ + +#if defined ( __CC_ARM ) + #error Legacy Arm Compiler does not support Armv8.1-M target architecture. +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM55_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM55_H_DEPENDANT +#define __CORE_CM55_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM55_REV + #define __CM55_REV 0x0000U + #warning "__CM55_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #if __FPU_PRESENT != 0U + #ifndef __FPU_DP + #define __FPU_DP 0U + #warning "__FPU_DP not defined in device header file; using default!" + #endif + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __PMU_PRESENT + #define __PMU_PRESENT 0U + #warning "__PMU_PRESENT not defined in device header file; using default!" + #endif + + #if __PMU_PRESENT != 0U + #ifndef __PMU_NUM_EVENTCNT + #define __PMU_NUM_EVENTCNT 8U + #warning "__PMU_NUM_EVENTCNT not defined in device header file; using default!" + #elif (__PMU_NUM_EVENTCNT > 8 || __PMU_NUM_EVENTCNT < 2) + #error "__PMU_NUM_EVENTCNT is out of range in device header file!" */ + #endif + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M55 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core EWIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core PMU Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + __IOM uint32_t RFSR; /*!< Offset: 0x204 (R/W) RAS Fault Status Register */ + uint32_t RESERVED4[14U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_IESB_Pos 5U /*!< SCB AIRCR: Implicit ESB Enable Position */ +#define SCB_AIRCR_IESB_Msk (1UL << SCB_AIRCR_IESB_Pos) /*!< SCB AIRCR: Implicit ESB Enable Mask */ + +#define SCB_AIRCR_DIT_Pos 4U /*!< SCB AIRCR: Data Independent Timing Position */ +#define SCB_AIRCR_DIT_Msk (1UL << SCB_AIRCR_DIT_Pos) /*!< SCB AIRCR: Data Independent Timing Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_TRD_Pos 20U /*!< SCB CCR: TRD Position */ +#define SCB_CCR_TRD_Msk (1UL << SCB_CCR_TRD_Pos) /*!< SCB CCR: TRD Mask */ + +#define SCB_CCR_LOB_Pos 19U /*!< SCB CCR: LOB Position */ +#define SCB_CCR_LOB_Msk (1UL << SCB_CCR_LOB_Pos) /*!< SCB CCR: LOB Mask */ + +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_PMU_Pos 5U /*!< SCB DFSR: PMU Position */ +#define SCB_DFSR_PMU_Msk (1UL << SCB_DFSR_PMU_Pos) /*!< SCB DFSR: PMU Mask */ + +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CP7_Pos 7U /*!< SCB NSACR: CP7 Position */ +#define SCB_NSACR_CP7_Msk (1UL << SCB_NSACR_CP7_Pos) /*!< SCB NSACR: CP7 Mask */ + +#define SCB_NSACR_CP6_Pos 6U /*!< SCB NSACR: CP6 Position */ +#define SCB_NSACR_CP6_Msk (1UL << SCB_NSACR_CP6_Pos) /*!< SCB NSACR: CP6 Mask */ + +#define SCB_NSACR_CP5_Pos 5U /*!< SCB NSACR: CP5 Position */ +#define SCB_NSACR_CP5_Msk (1UL << SCB_NSACR_CP5_Pos) /*!< SCB NSACR: CP5 Mask */ + +#define SCB_NSACR_CP4_Pos 4U /*!< SCB NSACR: CP4 Position */ +#define SCB_NSACR_CP4_Msk (1UL << SCB_NSACR_CP4_Pos) /*!< SCB NSACR: CP4 Mask */ + +#define SCB_NSACR_CP3_Pos 3U /*!< SCB NSACR: CP3 Position */ +#define SCB_NSACR_CP3_Msk (1UL << SCB_NSACR_CP3_Pos) /*!< SCB NSACR: CP3 Mask */ + +#define SCB_NSACR_CP2_Pos 2U /*!< SCB NSACR: CP2 Position */ +#define SCB_NSACR_CP2_Msk (1UL << SCB_NSACR_CP2_Pos) /*!< SCB NSACR: CP2 Mask */ + +#define SCB_NSACR_CP1_Pos 1U /*!< SCB NSACR: CP1 Position */ +#define SCB_NSACR_CP1_Msk (1UL << SCB_NSACR_CP1_Pos) /*!< SCB NSACR: CP1 Mask */ + +#define SCB_NSACR_CP0_Pos 0U /*!< SCB NSACR: CP0 Position */ +#define SCB_NSACR_CP0_Msk (1UL /*<< SCB_NSACR_CP0_Pos*/) /*!< SCB NSACR: CP0 Mask */ + +/* SCB Debug Feature Register 0 Definitions */ +#define SCB_ID_DFR_UDE_Pos 28U /*!< SCB ID_DFR: UDE Position */ +#define SCB_ID_DFR_UDE_Msk (0xFUL << SCB_ID_DFR_UDE_Pos) /*!< SCB ID_DFR: UDE Mask */ + +#define SCB_ID_DFR_MProfDbg_Pos 20U /*!< SCB ID_DFR: MProfDbg Position */ +#define SCB_ID_DFR_MProfDbg_Msk (0xFUL << SCB_ID_DFR_MProfDbg_Pos) /*!< SCB ID_DFR: MProfDbg Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB RAS Fault Status Register Definitions */ +#define SCB_RFSR_V_Pos 31U /*!< SCB RFSR: V Position */ +#define SCB_RFSR_V_Msk (1UL << SCB_RFSR_V_Pos) /*!< SCB RFSR: V Mask */ + +#define SCB_RFSR_IS_Pos 16U /*!< SCB RFSR: IS Position */ +#define SCB_RFSR_IS_Msk (0x7FFFUL << SCB_RFSR_IS_Pos) /*!< SCB RFSR: IS Mask */ + +#define SCB_RFSR_UET_Pos 0U /*!< SCB RFSR: UET Position */ +#define SCB_RFSR_UET_Msk (3UL /*<< SCB_RFSR_UET_Pos*/) /*!< SCB RFSR: UET Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ICB Implementation Control Block register (ICB) + \brief Type definitions for the Implementation Control Block Register + @{ + */ + +/** + \brief Structure type to access the Implementation Control Block (ICB). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} ICB_Type; + +/* Auxiliary Control Register Definitions */ +#define ICB_ACTLR_DISCRITAXIRUW_Pos 27U /*!< ACTLR: DISCRITAXIRUW Position */ +#define ICB_ACTLR_DISCRITAXIRUW_Msk (1UL << ICB_ACTLR_DISCRITAXIRUW_Pos) /*!< ACTLR: DISCRITAXIRUW Mask */ + +#define ICB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define ICB_ACTLR_DISDI_Msk (3UL << ICB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define ICB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define ICB_ACTLR_DISCRITAXIRUR_Msk (1UL << ICB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define ICB_ACTLR_EVENTBUSEN_Pos 14U /*!< ACTLR: EVENTBUSEN Position */ +#define ICB_ACTLR_EVENTBUSEN_Msk (1UL << ICB_ACTLR_EVENTBUSEN_Pos) /*!< ACTLR: EVENTBUSEN Mask */ + +#define ICB_ACTLR_EVENTBUSEN_S_Pos 13U /*!< ACTLR: EVENTBUSEN_S Position */ +#define ICB_ACTLR_EVENTBUSEN_S_Msk (1UL << ICB_ACTLR_EVENTBUSEN_S_Pos) /*!< ACTLR: EVENTBUSEN_S Mask */ + +#define ICB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define ICB_ACTLR_DISITMATBFLUSH_Msk (1UL << ICB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define ICB_ACTLR_DISNWAMODE_Pos 11U /*!< ACTLR: DISNWAMODE Position */ +#define ICB_ACTLR_DISNWAMODE_Msk (1UL << ICB_ACTLR_DISNWAMODE_Pos) /*!< ACTLR: DISNWAMODE Mask */ + +#define ICB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define ICB_ACTLR_FPEXCODIS_Msk (1UL << ICB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define ICB_ACTLR_DISOLAP_Pos 7U /*!< ACTLR: DISOLAP Position */ +#define ICB_ACTLR_DISOLAP_Msk (1UL << ICB_ACTLR_DISOLAP_Pos) /*!< ACTLR: DISOLAP Mask */ + +#define ICB_ACTLR_DISOLAPS_Pos 6U /*!< ACTLR: DISOLAPS Position */ +#define ICB_ACTLR_DISOLAPS_Msk (1UL << ICB_ACTLR_DISOLAPS_Pos) /*!< ACTLR: DISOLAPS Mask */ + +#define ICB_ACTLR_DISLOBR_Pos 5U /*!< ACTLR: DISLOBR Position */ +#define ICB_ACTLR_DISLOBR_Msk (1UL << ICB_ACTLR_DISLOBR_Pos) /*!< ACTLR: DISLOBR Mask */ + +#define ICB_ACTLR_DISLO_Pos 4U /*!< ACTLR: DISLO Position */ +#define ICB_ACTLR_DISLO_Msk (1UL << ICB_ACTLR_DISLO_Pos) /*!< ACTLR: DISLO Mask */ + +#define ICB_ACTLR_DISLOLEP_Pos 3U /*!< ACTLR: DISLOLEP Position */ +#define ICB_ACTLR_DISLOLEP_Msk (1UL << ICB_ACTLR_DISLOLEP_Pos) /*!< ACTLR: DISLOLEP Mask */ + +#define ICB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define ICB_ACTLR_DISFOLD_Msk (1UL << ICB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +/* Interrupt Controller Type Register Definitions */ +#define ICB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define ICB_ICTR_INTLINESNUM_Msk (0xFUL /*<< ICB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_ICB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[3U]; + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) ITM Device Type Register */ + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup MemSysCtl_Type Memory System Control Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Memory System Control Registers (MEMSYSCTL) + @{ + */ + +/** + \brief Structure type to access the Memory System Control Registers (MEMSYSCTL). + */ +typedef struct +{ + __IOM uint32_t MSCR; /*!< Offset: 0x000 (R/W) Memory System Control Register */ + __IOM uint32_t PFCR; /*!< Offset: 0x004 (R/W) Prefetcher Control Register */ + uint32_t RESERVED1[2U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x010 (R/W) ITCM Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x014 (R/W) DTCM Control Register */ + __IOM uint32_t PAHBCR; /*!< Offset: 0x018 (R/W) P-AHB Control Register */ + uint32_t RESERVED2[313U]; + __IOM uint32_t ITGU_CTRL; /*!< Offset: 0x500 (R/W) ITGU Control Register */ + __IOM uint32_t ITGU_CFG; /*!< Offset: 0x504 (R/W) ITGU Configuration Register */ + uint32_t RESERVED3[2U]; + __IOM uint32_t ITGU_LUT[16U]; /*!< Offset: 0x510 (R/W) ITGU Look Up Table Register */ + uint32_t RESERVED4[44U]; + __IOM uint32_t DTGU_CTRL; /*!< Offset: 0x600 (R/W) DTGU Control Registers */ + __IOM uint32_t DTGU_CFG; /*!< Offset: 0x604 (R/W) DTGU Configuration Register */ + uint32_t RESERVED5[2U]; + __IOM uint32_t DTGU_LUT[16U]; /*!< Offset: 0x610 (R/W) DTGU Look Up Table Register */ +} MemSysCtl_Type; + +/* MEMSYSCTL Memory System Control Register (MSCR) Register Definitions */ +#define MEMSYSCTL_MSCR_CPWRDN_Pos 17U /*!< MEMSYSCTL MSCR: CPWRDN Position */ +#define MEMSYSCTL_MSCR_CPWRDN_Msk (0x1UL << MEMSYSCTL_MSCR_CPWRDN_Pos) /*!< MEMSYSCTL MSCR: CPWRDN Mask */ + +#define MEMSYSCTL_MSCR_DCCLEAN_Pos 16U /*!< MEMSYSCTL MSCR: DCCLEAN Position */ +#define MEMSYSCTL_MSCR_DCCLEAN_Msk (0x1UL << MEMSYSCTL_MSCR_DCCLEAN_Pos) /*!< MEMSYSCTL MSCR: DCCLEAN Mask */ + +#define MEMSYSCTL_MSCR_ICACTIVE_Pos 13U /*!< MEMSYSCTL MSCR: ICACTIVE Position */ +#define MEMSYSCTL_MSCR_ICACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_ICACTIVE_Pos) /*!< MEMSYSCTL MSCR: ICACTIVE Mask */ + +#define MEMSYSCTL_MSCR_DCACTIVE_Pos 12U /*!< MEMSYSCTL MSCR: DCACTIVE Position */ +#define MEMSYSCTL_MSCR_DCACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_DCACTIVE_Pos) /*!< MEMSYSCTL MSCR: DCACTIVE Mask */ + +#define MEMSYSCTL_MSCR_TECCCHKDIS_Pos 4U /*!< MEMSYSCTL MSCR: TECCCHKDIS Position */ +#define MEMSYSCTL_MSCR_TECCCHKDIS_Msk (0x1UL << MEMSYSCTL_MSCR_TECCCHKDIS_Pos) /*!< MEMSYSCTL MSCR: TECCCHKDIS Mask */ + +#define MEMSYSCTL_MSCR_EVECCFAULT_Pos 3U /*!< MEMSYSCTL MSCR: EVECCFAULT Position */ +#define MEMSYSCTL_MSCR_EVECCFAULT_Msk (0x1UL << MEMSYSCTL_MSCR_EVECCFAULT_Pos) /*!< MEMSYSCTL MSCR: EVECCFAULT Mask */ + +#define MEMSYSCTL_MSCR_FORCEWT_Pos 2U /*!< MEMSYSCTL MSCR: FORCEWT Position */ +#define MEMSYSCTL_MSCR_FORCEWT_Msk (0x1UL << MEMSYSCTL_MSCR_FORCEWT_Pos) /*!< MEMSYSCTL MSCR: FORCEWT Mask */ + +#define MEMSYSCTL_MSCR_ECCEN_Pos 1U /*!< MEMSYSCTL MSCR: ECCEN Position */ +#define MEMSYSCTL_MSCR_ECCEN_Msk (0x1UL << MEMSYSCTL_MSCR_ECCEN_Pos) /*!< MEMSYSCTL MSCR: ECCEN Mask */ + +/* MEMSYSCTL Prefetcher Control Register (PFCR) Register Definitions */ +#define MEMSYSCTL_PFCR_MAX_OS_Pos 7U /*!< MEMSYSCTL PFCR: MAX_OS Position */ +#define MEMSYSCTL_PFCR_MAX_OS_Msk (0x7UL << MEMSYSCTL_PFCR_MAX_OS_Pos) /*!< MEMSYSCTL PFCR: MAX_OS Mask */ + +#define MEMSYSCTL_PFCR_MAX_LA_Pos 4U /*!< MEMSYSCTL PFCR: MAX_LA Position */ +#define MEMSYSCTL_PFCR_MAX_LA_Msk (0x7UL << MEMSYSCTL_PFCR_MAX_LA_Pos) /*!< MEMSYSCTL PFCR: MAX_LA Mask */ + +#define MEMSYSCTL_PFCR_MIN_LA_Pos 1U /*!< MEMSYSCTL PFCR: MIN_LA Position */ +#define MEMSYSCTL_PFCR_MIN_LA_Msk (0x7UL << MEMSYSCTL_PFCR_MIN_LA_Pos) /*!< MEMSYSCTL PFCR: MIN_LA Mask */ + +#define MEMSYSCTL_PFCR_ENABLE_Pos 0U /*!< MEMSYSCTL PFCR: ENABLE Position */ +#define MEMSYSCTL_PFCR_ENABLE_Msk (0x1UL /*<< MEMSYSCTL_PFCR_ENABLE_Pos*/) /*!< MEMSYSCTL PFCR: ENABLE Mask */ + +/* MEMSYSCTL ITCM Control Register (ITCMCR) Register Definitions */ +#define MEMSYSCTL_ITCMCR_SZ_Pos 3U /*!< MEMSYSCTL ITCMCR: SZ Position */ +#define MEMSYSCTL_ITCMCR_SZ_Msk (0xFUL << MEMSYSCTL_ITCMCR_SZ_Pos) /*!< MEMSYSCTL ITCMCR: SZ Mask */ + +#define MEMSYSCTL_ITCMCR_EN_Pos 0U /*!< MEMSYSCTL ITCMCR: EN Position */ +#define MEMSYSCTL_ITCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_ITCMCR_EN_Pos*/) /*!< MEMSYSCTL ITCMCR: EN Mask */ + +/* MEMSYSCTL DTCM Control Register (DTCMCR) Register Definitions */ +#define MEMSYSCTL_DTCMCR_SZ_Pos 3U /*!< MEMSYSCTL DTCMCR: SZ Position */ +#define MEMSYSCTL_DTCMCR_SZ_Msk (0xFUL << MEMSYSCTL_DTCMCR_SZ_Pos) /*!< MEMSYSCTL DTCMCR: SZ Mask */ + +#define MEMSYSCTL_DTCMCR_EN_Pos 0U /*!< MEMSYSCTL DTCMCR: EN Position */ +#define MEMSYSCTL_DTCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_DTCMCR_EN_Pos*/) /*!< MEMSYSCTL DTCMCR: EN Mask */ + +/* MEMSYSCTL P-AHB Control Register (PAHBCR) Register Definitions */ +#define MEMSYSCTL_PAHBCR_SZ_Pos 1U /*!< MEMSYSCTL PAHBCR: SZ Position */ +#define MEMSYSCTL_PAHBCR_SZ_Msk (0x7UL << MEMSYSCTL_PAHBCR_SZ_Pos) /*!< MEMSYSCTL PAHBCR: SZ Mask */ + +#define MEMSYSCTL_PAHBCR_EN_Pos 0U /*!< MEMSYSCTL PAHBCR: EN Position */ +#define MEMSYSCTL_PAHBCR_EN_Msk (0x1UL /*<< MEMSYSCTL_PAHBCR_EN_Pos*/) /*!< MEMSYSCTL PAHBCR: EN Mask */ + +/* MEMSYSCTL ITGU Control Register (ITGU_CTRL) Register Definitions */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL ITGU_CTRL: DEREN Position */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_ITGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL ITGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL ITGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_ITGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL ITGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL ITGU Configuration Register (ITGU_CFG) Register Definitions */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL ITGU_CFG: PRESENT Position */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_ITGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL ITGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL ITGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_ITGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL ITGU_CFG: BLKSZ Mask */ + +/* MEMSYSCTL DTGU Control Registers (DTGU_CTRL) Register Definitions */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL DTGU_CTRL: DEREN Position */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_DTGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL DTGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL DTGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_DTGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL DTGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL DTGU Configuration Register (DTGU_CFG) Register Definitions */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL DTGU_CFG: PRESENT Position */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_DTGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL DTGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL DTGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_DTGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL DTGU_CFG: BLKSZ Mask */ + + +/*@}*/ /* end of group MemSysCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PwrModCtl_Type Power Mode Control Registers + \brief Type definitions for the Power Mode Control Registers (PWRMODCTL) + @{ + */ + +/** + \brief Structure type to access the Power Mode Control Registers (PWRMODCTL). + */ +typedef struct +{ + __IOM uint32_t CPDLPSTATE; /*!< Offset: 0x000 (R/W) Core Power Domain Low Power State Register */ + __IOM uint32_t DPDLPSTATE; /*!< Offset: 0x004 (R/W) Debug Power Domain Low Power State Register */ +} PwrModCtl_Type; + +/* PWRMODCTL Core Power Domain Low Power State (CPDLPSTATE) Register Definitions */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos 8U /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos 4U /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos 0U /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Msk (0x3UL /*<< PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos*/) /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Mask */ + +/* PWRMODCTL Debug Power Domain Low Power State (DPDLPSTATE) Register Definitions */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos 0U /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Position */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Msk (0x3UL /*<< PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos*/) /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Mask */ + +/*@}*/ /* end of group PwrModCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup EWIC_Type External Wakeup Interrupt Controller Registers + \brief Type definitions for the External Wakeup Interrupt Controller Registers (EWIC) + @{ + */ + +/** + \brief Structure type to access the External Wakeup Interrupt Controller Registers (EWIC). + */ +typedef struct +{ + __OM uint32_t EVENTSPR; /*!< Offset: 0x000 ( /W) Event Set Pending Register */ + uint32_t RESERVED0[31U]; + __IM uint32_t EVENTMASKA; /*!< Offset: 0x080 (R/W) Event Mask A Register */ + __IM uint32_t EVENTMASK[15]; /*!< Offset: 0x084 (R/W) Event Mask Register */ +} EWIC_Type; + +/* EWIC External Wakeup Interrupt Controller (EVENTSPR) Register Definitions */ +#define EWIC_EVENTSPR_EDBGREQ_Pos 2U /*!< EWIC EVENTSPR: EDBGREQ Position */ +#define EWIC_EVENTSPR_EDBGREQ_Msk (0x1UL << EWIC_EVENTSPR_EDBGREQ_Pos) /*!< EWIC EVENTSPR: EDBGREQ Mask */ + +#define EWIC_EVENTSPR_NMI_Pos 1U /*!< EWIC EVENTSPR: NMI Position */ +#define EWIC_EVENTSPR_NMI_Msk (0x1UL << EWIC_EVENTSPR_NMI_Pos) /*!< EWIC EVENTSPR: NMI Mask */ + +#define EWIC_EVENTSPR_EVENT_Pos 0U /*!< EWIC EVENTSPR: EVENT Position */ +#define EWIC_EVENTSPR_EVENT_Msk (0x1UL /*<< EWIC_EVENTSPR_EVENT_Pos*/) /*!< EWIC EVENTSPR: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASKA) Register Definitions */ +#define EWIC_EVENTMASKA_EDBGREQ_Pos 2U /*!< EWIC EVENTMASKA: EDBGREQ Position */ +#define EWIC_EVENTMASKA_EDBGREQ_Msk (0x1UL << EWIC_EVENTMASKA_EDBGREQ_Pos) /*!< EWIC EVENTMASKA: EDBGREQ Mask */ + +#define EWIC_EVENTMASKA_NMI_Pos 1U /*!< EWIC EVENTMASKA: NMI Position */ +#define EWIC_EVENTMASKA_NMI_Msk (0x1UL << EWIC_EVENTMASKA_NMI_Pos) /*!< EWIC EVENTMASKA: NMI Mask */ + +#define EWIC_EVENTMASKA_EVENT_Pos 0U /*!< EWIC EVENTMASKA: EVENT Position */ +#define EWIC_EVENTMASKA_EVENT_Msk (0x1UL /*<< EWIC_EVENTMASKA_EVENT_Pos*/) /*!< EWIC EVENTMASKA: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASK) Register Definitions */ +#define EWIC_EVENTMASK_IRQ_Pos 0U /*!< EWIC EVENTMASKA: IRQ Position */ +#define EWIC_EVENTMASK_IRQ_Msk (0xFFFFFFFFUL /*<< EWIC_EVENTMASKA_IRQ_Pos*/) /*!< EWIC EVENTMASKA: IRQ Mask */ + +/*@}*/ /* end of group EWIC_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup ErrBnk_Type Error Banking Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Error Banking Registers (ERRBNK) + @{ + */ + +/** + \brief Structure type to access the Error Banking Registers (ERRBNK). + */ +typedef struct +{ + __IOM uint32_t IEBR0; /*!< Offset: 0x000 (R/W) Instruction Cache Error Bank Register 0 */ + __IOM uint32_t IEBR1; /*!< Offset: 0x004 (R/W) Instruction Cache Error Bank Register 1 */ + uint32_t RESERVED0[2U]; + __IOM uint32_t DEBR0; /*!< Offset: 0x010 (R/W) Data Cache Error Bank Register 0 */ + __IOM uint32_t DEBR1; /*!< Offset: 0x014 (R/W) Data Cache Error Bank Register 1 */ + uint32_t RESERVED1[2U]; + __IOM uint32_t TEBR0; /*!< Offset: 0x020 (R/W) TCM Error Bank Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t TEBR1; /*!< Offset: 0x028 (R/W) TCM Error Bank Register 1 */ +} ErrBnk_Type; + +/* ERRBNK Instruction Cache Error Bank Register 0 (IEBR0) Register Definitions */ +#define ERRBNK_IEBR0_SWDEF_Pos 30U /*!< ERRBNK IEBR0: SWDEF Position */ +#define ERRBNK_IEBR0_SWDEF_Msk (0x3UL << ERRBNK_IEBR0_SWDEF_Pos) /*!< ERRBNK IEBR0: SWDEF Mask */ + +#define ERRBNK_IEBR0_BANK_Pos 16U /*!< ERRBNK IEBR0: BANK Position */ +#define ERRBNK_IEBR0_BANK_Msk (0x1UL << ERRBNK_IEBR0_BANK_Pos) /*!< ERRBNK IEBR0: BANK Mask */ + +#define ERRBNK_IEBR0_LOCATION_Pos 2U /*!< ERRBNK IEBR0: LOCATION Position */ +#define ERRBNK_IEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR0_LOCATION_Pos) /*!< ERRBNK IEBR0: LOCATION Mask */ + +#define ERRBNK_IEBR0_LOCKED_Pos 1U /*!< ERRBNK IEBR0: LOCKED Position */ +#define ERRBNK_IEBR0_LOCKED_Msk (0x1UL << ERRBNK_IEBR0_LOCKED_Pos) /*!< ERRBNK IEBR0: LOCKED Mask */ + +#define ERRBNK_IEBR0_VALID_Pos 0U /*!< ERRBNK IEBR0: VALID Position */ +#define ERRBNK_IEBR0_VALID_Msk (0x1UL << /*ERRBNK_IEBR0_VALID_Pos*/) /*!< ERRBNK IEBR0: VALID Mask */ + +/* ERRBNK Instruction Cache Error Bank Register 1 (IEBR1) Register Definitions */ +#define ERRBNK_IEBR1_SWDEF_Pos 30U /*!< ERRBNK IEBR1: SWDEF Position */ +#define ERRBNK_IEBR1_SWDEF_Msk (0x3UL << ERRBNK_IEBR1_SWDEF_Pos) /*!< ERRBNK IEBR1: SWDEF Mask */ + +#define ERRBNK_IEBR1_BANK_Pos 16U /*!< ERRBNK IEBR1: BANK Position */ +#define ERRBNK_IEBR1_BANK_Msk (0x1UL << ERRBNK_IEBR1_BANK_Pos) /*!< ERRBNK IEBR1: BANK Mask */ + +#define ERRBNK_IEBR1_LOCATION_Pos 2U /*!< ERRBNK IEBR1: LOCATION Position */ +#define ERRBNK_IEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR1_LOCATION_Pos) /*!< ERRBNK IEBR1: LOCATION Mask */ + +#define ERRBNK_IEBR1_LOCKED_Pos 1U /*!< ERRBNK IEBR1: LOCKED Position */ +#define ERRBNK_IEBR1_LOCKED_Msk (0x1UL << ERRBNK_IEBR1_LOCKED_Pos) /*!< ERRBNK IEBR1: LOCKED Mask */ + +#define ERRBNK_IEBR1_VALID_Pos 0U /*!< ERRBNK IEBR1: VALID Position */ +#define ERRBNK_IEBR1_VALID_Msk (0x1UL << /*ERRBNK_IEBR1_VALID_Pos*/) /*!< ERRBNK IEBR1: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 0 (DEBR0) Register Definitions */ +#define ERRBNK_DEBR0_SWDEF_Pos 30U /*!< ERRBNK DEBR0: SWDEF Position */ +#define ERRBNK_DEBR0_SWDEF_Msk (0x3UL << ERRBNK_DEBR0_SWDEF_Pos) /*!< ERRBNK DEBR0: SWDEF Mask */ + +#define ERRBNK_DEBR0_TYPE_Pos 17U /*!< ERRBNK DEBR0: TYPE Position */ +#define ERRBNK_DEBR0_TYPE_Msk (0x1UL << ERRBNK_DEBR0_TYPE_Pos) /*!< ERRBNK DEBR0: TYPE Mask */ + +#define ERRBNK_DEBR0_BANK_Pos 16U /*!< ERRBNK DEBR0: BANK Position */ +#define ERRBNK_DEBR0_BANK_Msk (0x1UL << ERRBNK_DEBR0_BANK_Pos) /*!< ERRBNK DEBR0: BANK Mask */ + +#define ERRBNK_DEBR0_LOCATION_Pos 2U /*!< ERRBNK DEBR0: LOCATION Position */ +#define ERRBNK_DEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR0_LOCATION_Pos) /*!< ERRBNK DEBR0: LOCATION Mask */ + +#define ERRBNK_DEBR0_LOCKED_Pos 1U /*!< ERRBNK DEBR0: LOCKED Position */ +#define ERRBNK_DEBR0_LOCKED_Msk (0x1UL << ERRBNK_DEBR0_LOCKED_Pos) /*!< ERRBNK DEBR0: LOCKED Mask */ + +#define ERRBNK_DEBR0_VALID_Pos 0U /*!< ERRBNK DEBR0: VALID Position */ +#define ERRBNK_DEBR0_VALID_Msk (0x1UL << /*ERRBNK_DEBR0_VALID_Pos*/) /*!< ERRBNK DEBR0: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 1 (DEBR1) Register Definitions */ +#define ERRBNK_DEBR1_SWDEF_Pos 30U /*!< ERRBNK DEBR1: SWDEF Position */ +#define ERRBNK_DEBR1_SWDEF_Msk (0x3UL << ERRBNK_DEBR1_SWDEF_Pos) /*!< ERRBNK DEBR1: SWDEF Mask */ + +#define ERRBNK_DEBR1_TYPE_Pos 17U /*!< ERRBNK DEBR1: TYPE Position */ +#define ERRBNK_DEBR1_TYPE_Msk (0x1UL << ERRBNK_DEBR1_TYPE_Pos) /*!< ERRBNK DEBR1: TYPE Mask */ + +#define ERRBNK_DEBR1_BANK_Pos 16U /*!< ERRBNK DEBR1: BANK Position */ +#define ERRBNK_DEBR1_BANK_Msk (0x1UL << ERRBNK_DEBR1_BANK_Pos) /*!< ERRBNK DEBR1: BANK Mask */ + +#define ERRBNK_DEBR1_LOCATION_Pos 2U /*!< ERRBNK DEBR1: LOCATION Position */ +#define ERRBNK_DEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR1_LOCATION_Pos) /*!< ERRBNK DEBR1: LOCATION Mask */ + +#define ERRBNK_DEBR1_LOCKED_Pos 1U /*!< ERRBNK DEBR1: LOCKED Position */ +#define ERRBNK_DEBR1_LOCKED_Msk (0x1UL << ERRBNK_DEBR1_LOCKED_Pos) /*!< ERRBNK DEBR1: LOCKED Mask */ + +#define ERRBNK_DEBR1_VALID_Pos 0U /*!< ERRBNK DEBR1: VALID Position */ +#define ERRBNK_DEBR1_VALID_Msk (0x1UL << /*ERRBNK_DEBR1_VALID_Pos*/) /*!< ERRBNK DEBR1: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 0 (TEBR0) Register Definitions */ +#define ERRBNK_TEBR0_SWDEF_Pos 30U /*!< ERRBNK TEBR0: SWDEF Position */ +#define ERRBNK_TEBR0_SWDEF_Msk (0x3UL << ERRBNK_TEBR0_SWDEF_Pos) /*!< ERRBNK TEBR0: SWDEF Mask */ + +#define ERRBNK_TEBR0_POISON_Pos 28U /*!< ERRBNK TEBR0: POISON Position */ +#define ERRBNK_TEBR0_POISON_Msk (0x1UL << ERRBNK_TEBR0_POISON_Pos) /*!< ERRBNK TEBR0: POISON Mask */ + +#define ERRBNK_TEBR0_TYPE_Pos 27U /*!< ERRBNK TEBR0: TYPE Position */ +#define ERRBNK_TEBR0_TYPE_Msk (0x1UL << ERRBNK_TEBR0_TYPE_Pos) /*!< ERRBNK TEBR0: TYPE Mask */ + +#define ERRBNK_TEBR0_BANK_Pos 24U /*!< ERRBNK TEBR0: BANK Position */ +#define ERRBNK_TEBR0_BANK_Msk (0x3UL << ERRBNK_TEBR0_BANK_Pos) /*!< ERRBNK TEBR0: BANK Mask */ + +#define ERRBNK_TEBR0_LOCATION_Pos 2U /*!< ERRBNK TEBR0: LOCATION Position */ +#define ERRBNK_TEBR0_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR0_LOCATION_Pos) /*!< ERRBNK TEBR0: LOCATION Mask */ + +#define ERRBNK_TEBR0_LOCKED_Pos 1U /*!< ERRBNK TEBR0: LOCKED Position */ +#define ERRBNK_TEBR0_LOCKED_Msk (0x1UL << ERRBNK_TEBR0_LOCKED_Pos) /*!< ERRBNK TEBR0: LOCKED Mask */ + +#define ERRBNK_TEBR0_VALID_Pos 0U /*!< ERRBNK TEBR0: VALID Position */ +#define ERRBNK_TEBR0_VALID_Msk (0x1UL << /*ERRBNK_TEBR0_VALID_Pos*/) /*!< ERRBNK TEBR0: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 1 (TEBR1) Register Definitions */ +#define ERRBNK_TEBR1_SWDEF_Pos 30U /*!< ERRBNK TEBR1: SWDEF Position */ +#define ERRBNK_TEBR1_SWDEF_Msk (0x3UL << ERRBNK_TEBR1_SWDEF_Pos) /*!< ERRBNK TEBR1: SWDEF Mask */ + +#define ERRBNK_TEBR1_POISON_Pos 28U /*!< ERRBNK TEBR1: POISON Position */ +#define ERRBNK_TEBR1_POISON_Msk (0x1UL << ERRBNK_TEBR1_POISON_Pos) /*!< ERRBNK TEBR1: POISON Mask */ + +#define ERRBNK_TEBR1_TYPE_Pos 27U /*!< ERRBNK TEBR1: TYPE Position */ +#define ERRBNK_TEBR1_TYPE_Msk (0x1UL << ERRBNK_TEBR1_TYPE_Pos) /*!< ERRBNK TEBR1: TYPE Mask */ + +#define ERRBNK_TEBR1_BANK_Pos 24U /*!< ERRBNK TEBR1: BANK Position */ +#define ERRBNK_TEBR1_BANK_Msk (0x3UL << ERRBNK_TEBR1_BANK_Pos) /*!< ERRBNK TEBR1: BANK Mask */ + +#define ERRBNK_TEBR1_LOCATION_Pos 2U /*!< ERRBNK TEBR1: LOCATION Position */ +#define ERRBNK_TEBR1_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR1_LOCATION_Pos) /*!< ERRBNK TEBR1: LOCATION Mask */ + +#define ERRBNK_TEBR1_LOCKED_Pos 1U /*!< ERRBNK TEBR1: LOCKED Position */ +#define ERRBNK_TEBR1_LOCKED_Msk (0x1UL << ERRBNK_TEBR1_LOCKED_Pos) /*!< ERRBNK TEBR1: LOCKED Mask */ + +#define ERRBNK_TEBR1_VALID_Pos 0U /*!< ERRBNK TEBR1: VALID Position */ +#define ERRBNK_TEBR1_VALID_Msk (0x1UL << /*ERRBNK_TEBR1_VALID_Pos*/) /*!< ERRBNK TEBR1: VALID Mask */ + +/*@}*/ /* end of group ErrBnk_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PrcCfgInf_Type Processor Configuration Information Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Processor Configuration Information Registerss (PRCCFGINF) + @{ + */ + +/** + \brief Structure type to access the Processor Configuration Information Registerss (PRCCFGINF). + */ +typedef struct +{ + __OM uint32_t CFGINFOSEL; /*!< Offset: 0x000 ( /W) Processor Configuration Information Selection Register */ + __IM uint32_t CFGINFORD; /*!< Offset: 0x004 (R/ ) Processor Configuration Information Read Data Register */ +} PrcCfgInf_Type; + +/* PRCCFGINF Processor Configuration Information Selection Register (CFGINFOSEL) Definitions */ + +/* PRCCFGINF Processor Configuration Information Read Data Register (CFGINFORD) Definitions */ + +/*@}*/ /* end of group PrcCfgInf_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup STL_Type Software Test Library Observation Registers + \brief Type definitions for the Software Test Library Observation Registerss (STL) + @{ + */ + +/** + \brief Structure type to access the Software Test Library Observation Registerss (STL). + */ +typedef struct +{ + __IM uint32_t STLNVICPENDOR; /*!< Offset: 0x000 (R/ ) NVIC Pending Priority Tree Register */ + __IM uint32_t STLNVICACTVOR; /*!< Offset: 0x004 (R/ ) NVIC Active Priority Tree Register */ + uint32_t RESERVED0[2U]; + __OM uint32_t STLIDMPUSR; /*!< Offset: 0x010 ( /W) MPU Sanple Register */ + __IM uint32_t STLIMPUOR; /*!< Offset: 0x014 (R/ ) MPU Region Hit Register */ + __IM uint32_t STLD0MPUOR; /*!< Offset: 0x018 (R/ ) MPU Memory Attributes Register 0 */ + __IM uint32_t STLD1MPUOR; /*!< Offset: 0x01C (R/ ) MPU Memory Attributes Register 1 */ + +} STL_Type; + +/* STL Software Test Library Observation Register (STLNVICPENDOR) Definitions */ +#define STL_STLNVICPENDOR_VALID_Pos 18U /*!< STL STLNVICPENDOR: VALID Position */ +#define STL_STLNVICPENDOR_VALID_Msk (0x1UL << STL_STLNVICPENDOR_VALID_Pos) /*!< STL STLNVICPENDOR: VALID Mask */ + +#define STL_STLNVICPENDOR_TARGET_Pos 17U /*!< STL STLNVICPENDOR: TARGET Position */ +#define STL_STLNVICPENDOR_TARGET_Msk (0x1UL << STL_STLNVICPENDOR_TARGET_Pos) /*!< STL STLNVICPENDOR: TARGET Mask */ + +#define STL_STLNVICPENDOR_PRIORITY_Pos 9U /*!< STL STLNVICPENDOR: PRIORITY Position */ +#define STL_STLNVICPENDOR_PRIORITY_Msk (0xFFUL << STL_STLNVICPENDOR_PRIORITY_Pos) /*!< STL STLNVICPENDOR: PRIORITY Mask */ + +#define STL_STLNVICPENDOR_INTNUM_Pos 0U /*!< STL STLNVICPENDOR: INTNUM Position */ +#define STL_STLNVICPENDOR_INTNUM_Msk (0x1FFUL /*<< STL_STLNVICPENDOR_INTNUM_Pos*/) /*!< STL STLNVICPENDOR: INTNUM Mask */ + +/* STL Software Test Library Observation Register (STLNVICACTVOR) Definitions */ +#define STL_STLNVICACTVOR_VALID_Pos 18U /*!< STL STLNVICACTVOR: VALID Position */ +#define STL_STLNVICACTVOR_VALID_Msk (0x1UL << STL_STLNVICACTVOR_VALID_Pos) /*!< STL STLNVICACTVOR: VALID Mask */ + +#define STL_STLNVICACTVOR_TARGET_Pos 17U /*!< STL STLNVICACTVOR: TARGET Position */ +#define STL_STLNVICACTVOR_TARGET_Msk (0x1UL << STL_STLNVICACTVOR_TARGET_Pos) /*!< STL STLNVICACTVOR: TARGET Mask */ + +#define STL_STLNVICACTVOR_PRIORITY_Pos 9U /*!< STL STLNVICACTVOR: PRIORITY Position */ +#define STL_STLNVICACTVOR_PRIORITY_Msk (0xFFUL << STL_STLNVICACTVOR_PRIORITY_Pos) /*!< STL STLNVICACTVOR: PRIORITY Mask */ + +#define STL_STLNVICACTVOR_INTNUM_Pos 0U /*!< STL STLNVICACTVOR: INTNUM Position */ +#define STL_STLNVICACTVOR_INTNUM_Msk (0x1FFUL /*<< STL_STLNVICACTVOR_INTNUM_Pos*/) /*!< STL STLNVICACTVOR: INTNUM Mask */ + +/* STL Software Test Library Observation Register (STLIDMPUSR) Definitions */ +#define STL_STLIDMPUSR_ADDR_Pos 5U /*!< STL STLIDMPUSR: ADDR Position */ +#define STL_STLIDMPUSR_ADDR_Msk (0x7FFFFFFUL << STL_STLIDMPUSR_ADDR_Pos) /*!< STL STLIDMPUSR: ADDR Mask */ + +#define STL_STLIDMPUSR_INSTR_Pos 2U /*!< STL STLIDMPUSR: INSTR Position */ +#define STL_STLIDMPUSR_INSTR_Msk (0x1UL << STL_STLIDMPUSR_INSTR_Pos) /*!< STL STLIDMPUSR: INSTR Mask */ + +#define STL_STLIDMPUSR_DATA_Pos 1U /*!< STL STLIDMPUSR: DATA Position */ +#define STL_STLIDMPUSR_DATA_Msk (0x1UL << STL_STLIDMPUSR_DATA_Pos) /*!< STL STLIDMPUSR: DATA Mask */ + +/* STL Software Test Library Observation Register (STLIMPUOR) Definitions */ +#define STL_STLIMPUOR_HITREGION_Pos 9U /*!< STL STLIMPUOR: HITREGION Position */ +#define STL_STLIMPUOR_HITREGION_Msk (0xFFUL << STL_STLIMPUOR_HITREGION_Pos) /*!< STL STLIMPUOR: HITREGION Mask */ + +#define STL_STLIMPUOR_ATTR_Pos 0U /*!< STL STLIMPUOR: ATTR Position */ +#define STL_STLIMPUOR_ATTR_Msk (0x1FFUL /*<< STL_STLIMPUOR_ATTR_Pos*/) /*!< STL STLIMPUOR: ATTR Mask */ + +/* STL Software Test Library Observation Register (STLD0MPUOR) Definitions */ +#define STL_STLD0MPUOR_HITREGION_Pos 9U /*!< STL STLD0MPUOR: HITREGION Position */ +#define STL_STLD0MPUOR_HITREGION_Msk (0xFFUL << STL_STLD0MPUOR_HITREGION_Pos) /*!< STL STLD0MPUOR: HITREGION Mask */ + +#define STL_STLD0MPUOR_ATTR_Pos 0U /*!< STL STLD0MPUOR: ATTR Position */ +#define STL_STLD0MPUOR_ATTR_Msk (0x1FFUL /*<< STL_STLD0MPUOR_ATTR_Pos*/) /*!< STL STLD0MPUOR: ATTR Mask */ + +/* STL Software Test Library Observation Register (STLD1MPUOR) Definitions */ +#define STL_STLD1MPUOR_HITREGION_Pos 9U /*!< STL STLD1MPUOR: HITREGION Position */ +#define STL_STLD1MPUOR_HITREGION_Msk (0xFFUL << STL_STLD1MPUOR_HITREGION_Pos) /*!< STL STLD1MPUOR: HITREGION Mask */ + +#define STL_STLD1MPUOR_ATTR_Pos 0U /*!< STL STLD1MPUOR: ATTR Position */ +#define STL_STLD1MPUOR_ATTR_Msk (0x1FFUL /*<< STL_STLD1MPUOR_ATTR_Pos*/) /*!< STL STLD1MPUOR: ATTR Mask */ + +/*@}*/ /* end of group STL_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFmt_Pos 0U /*!< TPI FFCR: EnFmt Position */ +#define TPI_FFCR_EnFmt_Msk (0x3UL << /*TPI_FFCR_EnFmt_Pos*/) /*!< TPI FFCR: EnFmt Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_PMU Performance Monitoring Unit (PMU) + \brief Type definitions for the Performance Monitoring Unit (PMU) + @{ + */ + +/** + \brief Structure type to access the Performance Monitoring Unit (PMU). + */ +typedef struct +{ + __IOM uint32_t EVCNTR[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x0 (R/W) PMU Event Counter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED0[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCNTR; /*!< Offset: 0x7C (R/W) PMU Cycle Counter Register */ + uint32_t RESERVED1[224]; + __IOM uint32_t EVTYPER[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x400 (R/W) PMU Event Type and Filter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED2[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCFILTR; /*!< Offset: 0x47C (R/W) PMU Cycle Counter Filter Register */ + uint32_t RESERVED3[480]; + __IOM uint32_t CNTENSET; /*!< Offset: 0xC00 (R/W) PMU Count Enable Set Register */ + uint32_t RESERVED4[7]; + __IOM uint32_t CNTENCLR; /*!< Offset: 0xC20 (R/W) PMU Count Enable Clear Register */ + uint32_t RESERVED5[7]; + __IOM uint32_t INTENSET; /*!< Offset: 0xC40 (R/W) PMU Interrupt Enable Set Register */ + uint32_t RESERVED6[7]; + __IOM uint32_t INTENCLR; /*!< Offset: 0xC60 (R/W) PMU Interrupt Enable Clear Register */ + uint32_t RESERVED7[7]; + __IOM uint32_t OVSCLR; /*!< Offset: 0xC80 (R/W) PMU Overflow Flag Status Clear Register */ + uint32_t RESERVED8[7]; + __IOM uint32_t SWINC; /*!< Offset: 0xCA0 (R/W) PMU Software Increment Register */ + uint32_t RESERVED9[7]; + __IOM uint32_t OVSSET; /*!< Offset: 0xCC0 (R/W) PMU Overflow Flag Status Set Register */ + uint32_t RESERVED10[79]; + __IOM uint32_t TYPE; /*!< Offset: 0xE00 (R/W) PMU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0xE04 (R/W) PMU Control Register */ + uint32_t RESERVED11[108]; + __IOM uint32_t AUTHSTATUS; /*!< Offset: 0xFB8 (R/W) PMU Authentication Status Register */ + __IOM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/W) PMU Device Architecture Register */ + uint32_t RESERVED12[3]; + __IOM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/W) PMU Device Type Register */ + __IOM uint32_t PIDR4; /*!< Offset: 0xFD0 (R/W) PMU Peripheral Identification Register 4 */ + uint32_t RESERVED13[3]; + __IOM uint32_t PIDR0; /*!< Offset: 0xFE0 (R/W) PMU Peripheral Identification Register 0 */ + __IOM uint32_t PIDR1; /*!< Offset: 0xFE4 (R/W) PMU Peripheral Identification Register 1 */ + __IOM uint32_t PIDR2; /*!< Offset: 0xFE8 (R/W) PMU Peripheral Identification Register 2 */ + __IOM uint32_t PIDR3; /*!< Offset: 0xFEC (R/W) PMU Peripheral Identification Register 3 */ + __IOM uint32_t CIDR0; /*!< Offset: 0xFF0 (R/W) PMU Component Identification Register 0 */ + __IOM uint32_t CIDR1; /*!< Offset: 0xFF4 (R/W) PMU Component Identification Register 1 */ + __IOM uint32_t CIDR2; /*!< Offset: 0xFF8 (R/W) PMU Component Identification Register 2 */ + __IOM uint32_t CIDR3; /*!< Offset: 0xFFC (R/W) PMU Component Identification Register 3 */ +} PMU_Type; + +/** \brief PMU Event Counter Registers (0-30) Definitions */ + +#define PMU_EVCNTR_CNT_Pos 0U /*!< PMU EVCNTR: Counter Position */ +#define PMU_EVCNTR_CNT_Msk (0xFFFFUL /*<< PMU_EVCNTRx_CNT_Pos*/) /*!< PMU EVCNTR: Counter Mask */ + +/** \brief PMU Event Type and Filter Registers (0-30) Definitions */ + +#define PMU_EVTYPER_EVENTTOCNT_Pos 0U /*!< PMU EVTYPER: Event to Count Position */ +#define PMU_EVTYPER_EVENTTOCNT_Msk (0xFFFFUL /*<< EVTYPERx_EVENTTOCNT_Pos*/) /*!< PMU EVTYPER: Event to Count Mask */ + +/** \brief PMU Count Enable Set Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENSET: Event Counter 0 Enable Set Position */ +#define PMU_CNTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENSET_CNT0_ENABLE_Pos*/) /*!< PMU CNTENSET: Event Counter 0 Enable Set Mask */ + +#define PMU_CNTENSET_CNT1_ENABLE_Pos 1U /*!< PMU CNTENSET: Event Counter 1 Enable Set Position */ +#define PMU_CNTENSET_CNT1_ENABLE_Msk (1UL << PMU_CNTENSET_CNT1_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 1 Enable Set Mask */ + +#define PMU_CNTENSET_CNT2_ENABLE_Pos 2U /*!< PMU CNTENSET: Event Counter 2 Enable Set Position */ +#define PMU_CNTENSET_CNT2_ENABLE_Msk (1UL << PMU_CNTENSET_CNT2_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 2 Enable Set Mask */ + +#define PMU_CNTENSET_CNT3_ENABLE_Pos 3U /*!< PMU CNTENSET: Event Counter 3 Enable Set Position */ +#define PMU_CNTENSET_CNT3_ENABLE_Msk (1UL << PMU_CNTENSET_CNT3_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 3 Enable Set Mask */ + +#define PMU_CNTENSET_CNT4_ENABLE_Pos 4U /*!< PMU CNTENSET: Event Counter 4 Enable Set Position */ +#define PMU_CNTENSET_CNT4_ENABLE_Msk (1UL << PMU_CNTENSET_CNT4_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 4 Enable Set Mask */ + +#define PMU_CNTENSET_CNT5_ENABLE_Pos 5U /*!< PMU CNTENSET: Event Counter 5 Enable Set Position */ +#define PMU_CNTENSET_CNT5_ENABLE_Msk (1UL << PMU_CNTENSET_CNT5_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 5 Enable Set Mask */ + +#define PMU_CNTENSET_CNT6_ENABLE_Pos 6U /*!< PMU CNTENSET: Event Counter 6 Enable Set Position */ +#define PMU_CNTENSET_CNT6_ENABLE_Msk (1UL << PMU_CNTENSET_CNT6_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 6 Enable Set Mask */ + +#define PMU_CNTENSET_CNT7_ENABLE_Pos 7U /*!< PMU CNTENSET: Event Counter 7 Enable Set Position */ +#define PMU_CNTENSET_CNT7_ENABLE_Msk (1UL << PMU_CNTENSET_CNT7_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 7 Enable Set Mask */ + +#define PMU_CNTENSET_CNT8_ENABLE_Pos 8U /*!< PMU CNTENSET: Event Counter 8 Enable Set Position */ +#define PMU_CNTENSET_CNT8_ENABLE_Msk (1UL << PMU_CNTENSET_CNT8_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 8 Enable Set Mask */ + +#define PMU_CNTENSET_CNT9_ENABLE_Pos 9U /*!< PMU CNTENSET: Event Counter 9 Enable Set Position */ +#define PMU_CNTENSET_CNT9_ENABLE_Msk (1UL << PMU_CNTENSET_CNT9_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 9 Enable Set Mask */ + +#define PMU_CNTENSET_CNT10_ENABLE_Pos 10U /*!< PMU CNTENSET: Event Counter 10 Enable Set Position */ +#define PMU_CNTENSET_CNT10_ENABLE_Msk (1UL << PMU_CNTENSET_CNT10_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 10 Enable Set Mask */ + +#define PMU_CNTENSET_CNT11_ENABLE_Pos 11U /*!< PMU CNTENSET: Event Counter 11 Enable Set Position */ +#define PMU_CNTENSET_CNT11_ENABLE_Msk (1UL << PMU_CNTENSET_CNT11_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 11 Enable Set Mask */ + +#define PMU_CNTENSET_CNT12_ENABLE_Pos 12U /*!< PMU CNTENSET: Event Counter 12 Enable Set Position */ +#define PMU_CNTENSET_CNT12_ENABLE_Msk (1UL << PMU_CNTENSET_CNT12_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 12 Enable Set Mask */ + +#define PMU_CNTENSET_CNT13_ENABLE_Pos 13U /*!< PMU CNTENSET: Event Counter 13 Enable Set Position */ +#define PMU_CNTENSET_CNT13_ENABLE_Msk (1UL << PMU_CNTENSET_CNT13_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 13 Enable Set Mask */ + +#define PMU_CNTENSET_CNT14_ENABLE_Pos 14U /*!< PMU CNTENSET: Event Counter 14 Enable Set Position */ +#define PMU_CNTENSET_CNT14_ENABLE_Msk (1UL << PMU_CNTENSET_CNT14_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 14 Enable Set Mask */ + +#define PMU_CNTENSET_CNT15_ENABLE_Pos 15U /*!< PMU CNTENSET: Event Counter 15 Enable Set Position */ +#define PMU_CNTENSET_CNT15_ENABLE_Msk (1UL << PMU_CNTENSET_CNT15_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 15 Enable Set Mask */ + +#define PMU_CNTENSET_CNT16_ENABLE_Pos 16U /*!< PMU CNTENSET: Event Counter 16 Enable Set Position */ +#define PMU_CNTENSET_CNT16_ENABLE_Msk (1UL << PMU_CNTENSET_CNT16_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 16 Enable Set Mask */ + +#define PMU_CNTENSET_CNT17_ENABLE_Pos 17U /*!< PMU CNTENSET: Event Counter 17 Enable Set Position */ +#define PMU_CNTENSET_CNT17_ENABLE_Msk (1UL << PMU_CNTENSET_CNT17_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 17 Enable Set Mask */ + +#define PMU_CNTENSET_CNT18_ENABLE_Pos 18U /*!< PMU CNTENSET: Event Counter 18 Enable Set Position */ +#define PMU_CNTENSET_CNT18_ENABLE_Msk (1UL << PMU_CNTENSET_CNT18_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 18 Enable Set Mask */ + +#define PMU_CNTENSET_CNT19_ENABLE_Pos 19U /*!< PMU CNTENSET: Event Counter 19 Enable Set Position */ +#define PMU_CNTENSET_CNT19_ENABLE_Msk (1UL << PMU_CNTENSET_CNT19_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 19 Enable Set Mask */ + +#define PMU_CNTENSET_CNT20_ENABLE_Pos 20U /*!< PMU CNTENSET: Event Counter 20 Enable Set Position */ +#define PMU_CNTENSET_CNT20_ENABLE_Msk (1UL << PMU_CNTENSET_CNT20_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 20 Enable Set Mask */ + +#define PMU_CNTENSET_CNT21_ENABLE_Pos 21U /*!< PMU CNTENSET: Event Counter 21 Enable Set Position */ +#define PMU_CNTENSET_CNT21_ENABLE_Msk (1UL << PMU_CNTENSET_CNT21_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 21 Enable Set Mask */ + +#define PMU_CNTENSET_CNT22_ENABLE_Pos 22U /*!< PMU CNTENSET: Event Counter 22 Enable Set Position */ +#define PMU_CNTENSET_CNT22_ENABLE_Msk (1UL << PMU_CNTENSET_CNT22_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 22 Enable Set Mask */ + +#define PMU_CNTENSET_CNT23_ENABLE_Pos 23U /*!< PMU CNTENSET: Event Counter 23 Enable Set Position */ +#define PMU_CNTENSET_CNT23_ENABLE_Msk (1UL << PMU_CNTENSET_CNT23_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 23 Enable Set Mask */ + +#define PMU_CNTENSET_CNT24_ENABLE_Pos 24U /*!< PMU CNTENSET: Event Counter 24 Enable Set Position */ +#define PMU_CNTENSET_CNT24_ENABLE_Msk (1UL << PMU_CNTENSET_CNT24_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 24 Enable Set Mask */ + +#define PMU_CNTENSET_CNT25_ENABLE_Pos 25U /*!< PMU CNTENSET: Event Counter 25 Enable Set Position */ +#define PMU_CNTENSET_CNT25_ENABLE_Msk (1UL << PMU_CNTENSET_CNT25_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 25 Enable Set Mask */ + +#define PMU_CNTENSET_CNT26_ENABLE_Pos 26U /*!< PMU CNTENSET: Event Counter 26 Enable Set Position */ +#define PMU_CNTENSET_CNT26_ENABLE_Msk (1UL << PMU_CNTENSET_CNT26_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 26 Enable Set Mask */ + +#define PMU_CNTENSET_CNT27_ENABLE_Pos 27U /*!< PMU CNTENSET: Event Counter 27 Enable Set Position */ +#define PMU_CNTENSET_CNT27_ENABLE_Msk (1UL << PMU_CNTENSET_CNT27_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 27 Enable Set Mask */ + +#define PMU_CNTENSET_CNT28_ENABLE_Pos 28U /*!< PMU CNTENSET: Event Counter 28 Enable Set Position */ +#define PMU_CNTENSET_CNT28_ENABLE_Msk (1UL << PMU_CNTENSET_CNT28_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 28 Enable Set Mask */ + +#define PMU_CNTENSET_CNT29_ENABLE_Pos 29U /*!< PMU CNTENSET: Event Counter 29 Enable Set Position */ +#define PMU_CNTENSET_CNT29_ENABLE_Msk (1UL << PMU_CNTENSET_CNT29_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 29 Enable Set Mask */ + +#define PMU_CNTENSET_CNT30_ENABLE_Pos 30U /*!< PMU CNTENSET: Event Counter 30 Enable Set Position */ +#define PMU_CNTENSET_CNT30_ENABLE_Msk (1UL << PMU_CNTENSET_CNT30_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 30 Enable Set Mask */ + +#define PMU_CNTENSET_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENSET: Cycle Counter Enable Set Position */ +#define PMU_CNTENSET_CCNTR_ENABLE_Msk (1UL << PMU_CNTENSET_CCNTR_ENABLE_Pos) /*!< PMU CNTENSET: Cycle Counter Enable Set Mask */ + +/** \brief PMU Count Enable Clear Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Position */ +#define PMU_CNTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU CNTENCLR: Event Counter 1 Enable Clear Position */ +#define PMU_CNTENCLR_CNT1_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT1_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 1 Enable Clear */ + +#define PMU_CNTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Position */ +#define PMU_CNTENCLR_CNT2_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT2_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Position */ +#define PMU_CNTENCLR_CNT3_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT3_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Position */ +#define PMU_CNTENCLR_CNT4_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT4_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Position */ +#define PMU_CNTENCLR_CNT5_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT5_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Position */ +#define PMU_CNTENCLR_CNT6_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT6_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Position */ +#define PMU_CNTENCLR_CNT7_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT7_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Position */ +#define PMU_CNTENCLR_CNT8_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT8_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Position */ +#define PMU_CNTENCLR_CNT9_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT9_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Position */ +#define PMU_CNTENCLR_CNT10_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT10_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Position */ +#define PMU_CNTENCLR_CNT11_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT11_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Position */ +#define PMU_CNTENCLR_CNT12_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT12_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Position */ +#define PMU_CNTENCLR_CNT13_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT13_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Position */ +#define PMU_CNTENCLR_CNT14_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT14_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Position */ +#define PMU_CNTENCLR_CNT15_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT15_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Position */ +#define PMU_CNTENCLR_CNT16_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT16_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Position */ +#define PMU_CNTENCLR_CNT17_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT17_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Position */ +#define PMU_CNTENCLR_CNT18_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT18_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Position */ +#define PMU_CNTENCLR_CNT19_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT19_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Position */ +#define PMU_CNTENCLR_CNT20_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT20_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Position */ +#define PMU_CNTENCLR_CNT21_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT21_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Position */ +#define PMU_CNTENCLR_CNT22_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT22_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Position */ +#define PMU_CNTENCLR_CNT23_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT23_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Position */ +#define PMU_CNTENCLR_CNT24_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT24_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Position */ +#define PMU_CNTENCLR_CNT25_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT25_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Position */ +#define PMU_CNTENCLR_CNT26_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT26_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Position */ +#define PMU_CNTENCLR_CNT27_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT27_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Position */ +#define PMU_CNTENCLR_CNT28_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT28_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Position */ +#define PMU_CNTENCLR_CNT29_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT29_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Position */ +#define PMU_CNTENCLR_CNT30_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT30_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Mask */ + +#define PMU_CNTENCLR_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENCLR: Cycle Counter Enable Clear Position */ +#define PMU_CNTENCLR_CCNTR_ENABLE_Msk (1UL << PMU_CNTENCLR_CCNTR_ENABLE_Pos) /*!< PMU CNTENCLR: Cycle Counter Enable Clear Mask */ + +/** \brief PMU Interrupt Enable Set Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENSET_CNT0_ENABLE_Pos*/) /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT1_ENABLE_Pos 1U /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT1_ENABLE_Msk (1UL << PMU_INTENSET_CNT1_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT2_ENABLE_Pos 2U /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT2_ENABLE_Msk (1UL << PMU_INTENSET_CNT2_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT3_ENABLE_Pos 3U /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT3_ENABLE_Msk (1UL << PMU_INTENSET_CNT3_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT4_ENABLE_Pos 4U /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT4_ENABLE_Msk (1UL << PMU_INTENSET_CNT4_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT5_ENABLE_Pos 5U /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT5_ENABLE_Msk (1UL << PMU_INTENSET_CNT5_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT6_ENABLE_Pos 6U /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT6_ENABLE_Msk (1UL << PMU_INTENSET_CNT6_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT7_ENABLE_Pos 7U /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT7_ENABLE_Msk (1UL << PMU_INTENSET_CNT7_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT8_ENABLE_Pos 8U /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT8_ENABLE_Msk (1UL << PMU_INTENSET_CNT8_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT9_ENABLE_Pos 9U /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT9_ENABLE_Msk (1UL << PMU_INTENSET_CNT9_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT10_ENABLE_Pos 10U /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT10_ENABLE_Msk (1UL << PMU_INTENSET_CNT10_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT11_ENABLE_Pos 11U /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT11_ENABLE_Msk (1UL << PMU_INTENSET_CNT11_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT12_ENABLE_Pos 12U /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT12_ENABLE_Msk (1UL << PMU_INTENSET_CNT12_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT13_ENABLE_Pos 13U /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT13_ENABLE_Msk (1UL << PMU_INTENSET_CNT13_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT14_ENABLE_Pos 14U /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT14_ENABLE_Msk (1UL << PMU_INTENSET_CNT14_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT15_ENABLE_Pos 15U /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT15_ENABLE_Msk (1UL << PMU_INTENSET_CNT15_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT16_ENABLE_Pos 16U /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT16_ENABLE_Msk (1UL << PMU_INTENSET_CNT16_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT17_ENABLE_Pos 17U /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT17_ENABLE_Msk (1UL << PMU_INTENSET_CNT17_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT18_ENABLE_Pos 18U /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT18_ENABLE_Msk (1UL << PMU_INTENSET_CNT18_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT19_ENABLE_Pos 19U /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT19_ENABLE_Msk (1UL << PMU_INTENSET_CNT19_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT20_ENABLE_Pos 20U /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT20_ENABLE_Msk (1UL << PMU_INTENSET_CNT20_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT21_ENABLE_Pos 21U /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT21_ENABLE_Msk (1UL << PMU_INTENSET_CNT21_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT22_ENABLE_Pos 22U /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT22_ENABLE_Msk (1UL << PMU_INTENSET_CNT22_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT23_ENABLE_Pos 23U /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT23_ENABLE_Msk (1UL << PMU_INTENSET_CNT23_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT24_ENABLE_Pos 24U /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT24_ENABLE_Msk (1UL << PMU_INTENSET_CNT24_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT25_ENABLE_Pos 25U /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT25_ENABLE_Msk (1UL << PMU_INTENSET_CNT25_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT26_ENABLE_Pos 26U /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT26_ENABLE_Msk (1UL << PMU_INTENSET_CNT26_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT27_ENABLE_Pos 27U /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT27_ENABLE_Msk (1UL << PMU_INTENSET_CNT27_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT28_ENABLE_Pos 28U /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT28_ENABLE_Msk (1UL << PMU_INTENSET_CNT28_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT29_ENABLE_Pos 29U /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT29_ENABLE_Msk (1UL << PMU_INTENSET_CNT29_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT30_ENABLE_Pos 30U /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT30_ENABLE_Msk (1UL << PMU_INTENSET_CNT30_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Position */ +#define PMU_INTENSET_CCYCNT_ENABLE_Msk (1UL << PMU_INTENSET_CYCCNT_ENABLE_Pos) /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Mask */ + +/** \brief PMU Interrupt Enable Clear Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT1_ENABLE_Msk (1UL << PMU_INTENCLR_CNT1_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear */ + +#define PMU_INTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT2_ENABLE_Msk (1UL << PMU_INTENCLR_CNT2_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT3_ENABLE_Msk (1UL << PMU_INTENCLR_CNT3_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT4_ENABLE_Msk (1UL << PMU_INTENCLR_CNT4_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT5_ENABLE_Msk (1UL << PMU_INTENCLR_CNT5_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT6_ENABLE_Msk (1UL << PMU_INTENCLR_CNT6_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT7_ENABLE_Msk (1UL << PMU_INTENCLR_CNT7_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT8_ENABLE_Msk (1UL << PMU_INTENCLR_CNT8_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT9_ENABLE_Msk (1UL << PMU_INTENCLR_CNT9_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT10_ENABLE_Msk (1UL << PMU_INTENCLR_CNT10_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT11_ENABLE_Msk (1UL << PMU_INTENCLR_CNT11_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT12_ENABLE_Msk (1UL << PMU_INTENCLR_CNT12_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT13_ENABLE_Msk (1UL << PMU_INTENCLR_CNT13_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT14_ENABLE_Msk (1UL << PMU_INTENCLR_CNT14_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT15_ENABLE_Msk (1UL << PMU_INTENCLR_CNT15_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT16_ENABLE_Msk (1UL << PMU_INTENCLR_CNT16_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT17_ENABLE_Msk (1UL << PMU_INTENCLR_CNT17_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT18_ENABLE_Msk (1UL << PMU_INTENCLR_CNT18_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT19_ENABLE_Msk (1UL << PMU_INTENCLR_CNT19_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT20_ENABLE_Msk (1UL << PMU_INTENCLR_CNT20_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT21_ENABLE_Msk (1UL << PMU_INTENCLR_CNT21_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT22_ENABLE_Msk (1UL << PMU_INTENCLR_CNT22_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT23_ENABLE_Msk (1UL << PMU_INTENCLR_CNT23_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT24_ENABLE_Msk (1UL << PMU_INTENCLR_CNT24_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT25_ENABLE_Msk (1UL << PMU_INTENCLR_CNT25_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT26_ENABLE_Msk (1UL << PMU_INTENCLR_CNT26_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT27_ENABLE_Msk (1UL << PMU_INTENCLR_CNT27_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT28_ENABLE_Msk (1UL << PMU_INTENCLR_CNT28_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT29_ENABLE_Msk (1UL << PMU_INTENCLR_CNT29_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT30_ENABLE_Msk (1UL << PMU_INTENCLR_CNT30_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CYCCNT_ENABLE_Msk (1UL << PMU_INTENCLR_CYCCNT_ENABLE_Pos) /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Mask */ + +/** \brief PMU Overflow Flag Status Set Register Definitions */ + +#define PMU_OVSSET_CNT0_STATUS_Pos 0U /*!< PMU OVSSET: Event Counter 0 Overflow Set Position */ +#define PMU_OVSSET_CNT0_STATUS_Msk (1UL /*<< PMU_OVSSET_CNT0_STATUS_Pos*/) /*!< PMU OVSSET: Event Counter 0 Overflow Set Mask */ + +#define PMU_OVSSET_CNT1_STATUS_Pos 1U /*!< PMU OVSSET: Event Counter 1 Overflow Set Position */ +#define PMU_OVSSET_CNT1_STATUS_Msk (1UL << PMU_OVSSET_CNT1_STATUS_Pos) /*!< PMU OVSSET: Event Counter 1 Overflow Set Mask */ + +#define PMU_OVSSET_CNT2_STATUS_Pos 2U /*!< PMU OVSSET: Event Counter 2 Overflow Set Position */ +#define PMU_OVSSET_CNT2_STATUS_Msk (1UL << PMU_OVSSET_CNT2_STATUS_Pos) /*!< PMU OVSSET: Event Counter 2 Overflow Set Mask */ + +#define PMU_OVSSET_CNT3_STATUS_Pos 3U /*!< PMU OVSSET: Event Counter 3 Overflow Set Position */ +#define PMU_OVSSET_CNT3_STATUS_Msk (1UL << PMU_OVSSET_CNT3_STATUS_Pos) /*!< PMU OVSSET: Event Counter 3 Overflow Set Mask */ + +#define PMU_OVSSET_CNT4_STATUS_Pos 4U /*!< PMU OVSSET: Event Counter 4 Overflow Set Position */ +#define PMU_OVSSET_CNT4_STATUS_Msk (1UL << PMU_OVSSET_CNT4_STATUS_Pos) /*!< PMU OVSSET: Event Counter 4 Overflow Set Mask */ + +#define PMU_OVSSET_CNT5_STATUS_Pos 5U /*!< PMU OVSSET: Event Counter 5 Overflow Set Position */ +#define PMU_OVSSET_CNT5_STATUS_Msk (1UL << PMU_OVSSET_CNT5_STATUS_Pos) /*!< PMU OVSSET: Event Counter 5 Overflow Set Mask */ + +#define PMU_OVSSET_CNT6_STATUS_Pos 6U /*!< PMU OVSSET: Event Counter 6 Overflow Set Position */ +#define PMU_OVSSET_CNT6_STATUS_Msk (1UL << PMU_OVSSET_CNT6_STATUS_Pos) /*!< PMU OVSSET: Event Counter 6 Overflow Set Mask */ + +#define PMU_OVSSET_CNT7_STATUS_Pos 7U /*!< PMU OVSSET: Event Counter 7 Overflow Set Position */ +#define PMU_OVSSET_CNT7_STATUS_Msk (1UL << PMU_OVSSET_CNT7_STATUS_Pos) /*!< PMU OVSSET: Event Counter 7 Overflow Set Mask */ + +#define PMU_OVSSET_CNT8_STATUS_Pos 8U /*!< PMU OVSSET: Event Counter 8 Overflow Set Position */ +#define PMU_OVSSET_CNT8_STATUS_Msk (1UL << PMU_OVSSET_CNT8_STATUS_Pos) /*!< PMU OVSSET: Event Counter 8 Overflow Set Mask */ + +#define PMU_OVSSET_CNT9_STATUS_Pos 9U /*!< PMU OVSSET: Event Counter 9 Overflow Set Position */ +#define PMU_OVSSET_CNT9_STATUS_Msk (1UL << PMU_OVSSET_CNT9_STATUS_Pos) /*!< PMU OVSSET: Event Counter 9 Overflow Set Mask */ + +#define PMU_OVSSET_CNT10_STATUS_Pos 10U /*!< PMU OVSSET: Event Counter 10 Overflow Set Position */ +#define PMU_OVSSET_CNT10_STATUS_Msk (1UL << PMU_OVSSET_CNT10_STATUS_Pos) /*!< PMU OVSSET: Event Counter 10 Overflow Set Mask */ + +#define PMU_OVSSET_CNT11_STATUS_Pos 11U /*!< PMU OVSSET: Event Counter 11 Overflow Set Position */ +#define PMU_OVSSET_CNT11_STATUS_Msk (1UL << PMU_OVSSET_CNT11_STATUS_Pos) /*!< PMU OVSSET: Event Counter 11 Overflow Set Mask */ + +#define PMU_OVSSET_CNT12_STATUS_Pos 12U /*!< PMU OVSSET: Event Counter 12 Overflow Set Position */ +#define PMU_OVSSET_CNT12_STATUS_Msk (1UL << PMU_OVSSET_CNT12_STATUS_Pos) /*!< PMU OVSSET: Event Counter 12 Overflow Set Mask */ + +#define PMU_OVSSET_CNT13_STATUS_Pos 13U /*!< PMU OVSSET: Event Counter 13 Overflow Set Position */ +#define PMU_OVSSET_CNT13_STATUS_Msk (1UL << PMU_OVSSET_CNT13_STATUS_Pos) /*!< PMU OVSSET: Event Counter 13 Overflow Set Mask */ + +#define PMU_OVSSET_CNT14_STATUS_Pos 14U /*!< PMU OVSSET: Event Counter 14 Overflow Set Position */ +#define PMU_OVSSET_CNT14_STATUS_Msk (1UL << PMU_OVSSET_CNT14_STATUS_Pos) /*!< PMU OVSSET: Event Counter 14 Overflow Set Mask */ + +#define PMU_OVSSET_CNT15_STATUS_Pos 15U /*!< PMU OVSSET: Event Counter 15 Overflow Set Position */ +#define PMU_OVSSET_CNT15_STATUS_Msk (1UL << PMU_OVSSET_CNT15_STATUS_Pos) /*!< PMU OVSSET: Event Counter 15 Overflow Set Mask */ + +#define PMU_OVSSET_CNT16_STATUS_Pos 16U /*!< PMU OVSSET: Event Counter 16 Overflow Set Position */ +#define PMU_OVSSET_CNT16_STATUS_Msk (1UL << PMU_OVSSET_CNT16_STATUS_Pos) /*!< PMU OVSSET: Event Counter 16 Overflow Set Mask */ + +#define PMU_OVSSET_CNT17_STATUS_Pos 17U /*!< PMU OVSSET: Event Counter 17 Overflow Set Position */ +#define PMU_OVSSET_CNT17_STATUS_Msk (1UL << PMU_OVSSET_CNT17_STATUS_Pos) /*!< PMU OVSSET: Event Counter 17 Overflow Set Mask */ + +#define PMU_OVSSET_CNT18_STATUS_Pos 18U /*!< PMU OVSSET: Event Counter 18 Overflow Set Position */ +#define PMU_OVSSET_CNT18_STATUS_Msk (1UL << PMU_OVSSET_CNT18_STATUS_Pos) /*!< PMU OVSSET: Event Counter 18 Overflow Set Mask */ + +#define PMU_OVSSET_CNT19_STATUS_Pos 19U /*!< PMU OVSSET: Event Counter 19 Overflow Set Position */ +#define PMU_OVSSET_CNT19_STATUS_Msk (1UL << PMU_OVSSET_CNT19_STATUS_Pos) /*!< PMU OVSSET: Event Counter 19 Overflow Set Mask */ + +#define PMU_OVSSET_CNT20_STATUS_Pos 20U /*!< PMU OVSSET: Event Counter 20 Overflow Set Position */ +#define PMU_OVSSET_CNT20_STATUS_Msk (1UL << PMU_OVSSET_CNT20_STATUS_Pos) /*!< PMU OVSSET: Event Counter 20 Overflow Set Mask */ + +#define PMU_OVSSET_CNT21_STATUS_Pos 21U /*!< PMU OVSSET: Event Counter 21 Overflow Set Position */ +#define PMU_OVSSET_CNT21_STATUS_Msk (1UL << PMU_OVSSET_CNT21_STATUS_Pos) /*!< PMU OVSSET: Event Counter 21 Overflow Set Mask */ + +#define PMU_OVSSET_CNT22_STATUS_Pos 22U /*!< PMU OVSSET: Event Counter 22 Overflow Set Position */ +#define PMU_OVSSET_CNT22_STATUS_Msk (1UL << PMU_OVSSET_CNT22_STATUS_Pos) /*!< PMU OVSSET: Event Counter 22 Overflow Set Mask */ + +#define PMU_OVSSET_CNT23_STATUS_Pos 23U /*!< PMU OVSSET: Event Counter 23 Overflow Set Position */ +#define PMU_OVSSET_CNT23_STATUS_Msk (1UL << PMU_OVSSET_CNT23_STATUS_Pos) /*!< PMU OVSSET: Event Counter 23 Overflow Set Mask */ + +#define PMU_OVSSET_CNT24_STATUS_Pos 24U /*!< PMU OVSSET: Event Counter 24 Overflow Set Position */ +#define PMU_OVSSET_CNT24_STATUS_Msk (1UL << PMU_OVSSET_CNT24_STATUS_Pos) /*!< PMU OVSSET: Event Counter 24 Overflow Set Mask */ + +#define PMU_OVSSET_CNT25_STATUS_Pos 25U /*!< PMU OVSSET: Event Counter 25 Overflow Set Position */ +#define PMU_OVSSET_CNT25_STATUS_Msk (1UL << PMU_OVSSET_CNT25_STATUS_Pos) /*!< PMU OVSSET: Event Counter 25 Overflow Set Mask */ + +#define PMU_OVSSET_CNT26_STATUS_Pos 26U /*!< PMU OVSSET: Event Counter 26 Overflow Set Position */ +#define PMU_OVSSET_CNT26_STATUS_Msk (1UL << PMU_OVSSET_CNT26_STATUS_Pos) /*!< PMU OVSSET: Event Counter 26 Overflow Set Mask */ + +#define PMU_OVSSET_CNT27_STATUS_Pos 27U /*!< PMU OVSSET: Event Counter 27 Overflow Set Position */ +#define PMU_OVSSET_CNT27_STATUS_Msk (1UL << PMU_OVSSET_CNT27_STATUS_Pos) /*!< PMU OVSSET: Event Counter 27 Overflow Set Mask */ + +#define PMU_OVSSET_CNT28_STATUS_Pos 28U /*!< PMU OVSSET: Event Counter 28 Overflow Set Position */ +#define PMU_OVSSET_CNT28_STATUS_Msk (1UL << PMU_OVSSET_CNT28_STATUS_Pos) /*!< PMU OVSSET: Event Counter 28 Overflow Set Mask */ + +#define PMU_OVSSET_CNT29_STATUS_Pos 29U /*!< PMU OVSSET: Event Counter 29 Overflow Set Position */ +#define PMU_OVSSET_CNT29_STATUS_Msk (1UL << PMU_OVSSET_CNT29_STATUS_Pos) /*!< PMU OVSSET: Event Counter 29 Overflow Set Mask */ + +#define PMU_OVSSET_CNT30_STATUS_Pos 30U /*!< PMU OVSSET: Event Counter 30 Overflow Set Position */ +#define PMU_OVSSET_CNT30_STATUS_Msk (1UL << PMU_OVSSET_CNT30_STATUS_Pos) /*!< PMU OVSSET: Event Counter 30 Overflow Set Mask */ + +#define PMU_OVSSET_CYCCNT_STATUS_Pos 31U /*!< PMU OVSSET: Cycle Counter Overflow Set Position */ +#define PMU_OVSSET_CYCCNT_STATUS_Msk (1UL << PMU_OVSSET_CYCCNT_STATUS_Pos) /*!< PMU OVSSET: Cycle Counter Overflow Set Mask */ + +/** \brief PMU Overflow Flag Status Clear Register Definitions */ + +#define PMU_OVSCLR_CNT0_STATUS_Pos 0U /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Position */ +#define PMU_OVSCLR_CNT0_STATUS_Msk (1UL /*<< PMU_OVSCLR_CNT0_STATUS_Pos*/) /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT1_STATUS_Pos 1U /*!< PMU OVSCLR: Event Counter 1 Overflow Clear Position */ +#define PMU_OVSCLR_CNT1_STATUS_Msk (1UL << PMU_OVSCLR_CNT1_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 1 Overflow Clear */ + +#define PMU_OVSCLR_CNT2_STATUS_Pos 2U /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Position */ +#define PMU_OVSCLR_CNT2_STATUS_Msk (1UL << PMU_OVSCLR_CNT2_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT3_STATUS_Pos 3U /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Position */ +#define PMU_OVSCLR_CNT3_STATUS_Msk (1UL << PMU_OVSCLR_CNT3_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT4_STATUS_Pos 4U /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Position */ +#define PMU_OVSCLR_CNT4_STATUS_Msk (1UL << PMU_OVSCLR_CNT4_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT5_STATUS_Pos 5U /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Position */ +#define PMU_OVSCLR_CNT5_STATUS_Msk (1UL << PMU_OVSCLR_CNT5_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT6_STATUS_Pos 6U /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Position */ +#define PMU_OVSCLR_CNT6_STATUS_Msk (1UL << PMU_OVSCLR_CNT6_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT7_STATUS_Pos 7U /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Position */ +#define PMU_OVSCLR_CNT7_STATUS_Msk (1UL << PMU_OVSCLR_CNT7_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT8_STATUS_Pos 8U /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Position */ +#define PMU_OVSCLR_CNT8_STATUS_Msk (1UL << PMU_OVSCLR_CNT8_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT9_STATUS_Pos 9U /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Position */ +#define PMU_OVSCLR_CNT9_STATUS_Msk (1UL << PMU_OVSCLR_CNT9_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT10_STATUS_Pos 10U /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Position */ +#define PMU_OVSCLR_CNT10_STATUS_Msk (1UL << PMU_OVSCLR_CNT10_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT11_STATUS_Pos 11U /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Position */ +#define PMU_OVSCLR_CNT11_STATUS_Msk (1UL << PMU_OVSCLR_CNT11_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT12_STATUS_Pos 12U /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Position */ +#define PMU_OVSCLR_CNT12_STATUS_Msk (1UL << PMU_OVSCLR_CNT12_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT13_STATUS_Pos 13U /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Position */ +#define PMU_OVSCLR_CNT13_STATUS_Msk (1UL << PMU_OVSCLR_CNT13_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT14_STATUS_Pos 14U /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Position */ +#define PMU_OVSCLR_CNT14_STATUS_Msk (1UL << PMU_OVSCLR_CNT14_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT15_STATUS_Pos 15U /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Position */ +#define PMU_OVSCLR_CNT15_STATUS_Msk (1UL << PMU_OVSCLR_CNT15_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT16_STATUS_Pos 16U /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Position */ +#define PMU_OVSCLR_CNT16_STATUS_Msk (1UL << PMU_OVSCLR_CNT16_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT17_STATUS_Pos 17U /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Position */ +#define PMU_OVSCLR_CNT17_STATUS_Msk (1UL << PMU_OVSCLR_CNT17_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT18_STATUS_Pos 18U /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Position */ +#define PMU_OVSCLR_CNT18_STATUS_Msk (1UL << PMU_OVSCLR_CNT18_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT19_STATUS_Pos 19U /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Position */ +#define PMU_OVSCLR_CNT19_STATUS_Msk (1UL << PMU_OVSCLR_CNT19_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT20_STATUS_Pos 20U /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Position */ +#define PMU_OVSCLR_CNT20_STATUS_Msk (1UL << PMU_OVSCLR_CNT20_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT21_STATUS_Pos 21U /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Position */ +#define PMU_OVSCLR_CNT21_STATUS_Msk (1UL << PMU_OVSCLR_CNT21_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT22_STATUS_Pos 22U /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Position */ +#define PMU_OVSCLR_CNT22_STATUS_Msk (1UL << PMU_OVSCLR_CNT22_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT23_STATUS_Pos 23U /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Position */ +#define PMU_OVSCLR_CNT23_STATUS_Msk (1UL << PMU_OVSCLR_CNT23_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT24_STATUS_Pos 24U /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Position */ +#define PMU_OVSCLR_CNT24_STATUS_Msk (1UL << PMU_OVSCLR_CNT24_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT25_STATUS_Pos 25U /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Position */ +#define PMU_OVSCLR_CNT25_STATUS_Msk (1UL << PMU_OVSCLR_CNT25_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT26_STATUS_Pos 26U /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Position */ +#define PMU_OVSCLR_CNT26_STATUS_Msk (1UL << PMU_OVSCLR_CNT26_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT27_STATUS_Pos 27U /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Position */ +#define PMU_OVSCLR_CNT27_STATUS_Msk (1UL << PMU_OVSCLR_CNT27_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT28_STATUS_Pos 28U /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Position */ +#define PMU_OVSCLR_CNT28_STATUS_Msk (1UL << PMU_OVSCLR_CNT28_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT29_STATUS_Pos 29U /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Position */ +#define PMU_OVSCLR_CNT29_STATUS_Msk (1UL << PMU_OVSCLR_CNT29_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT30_STATUS_Pos 30U /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Position */ +#define PMU_OVSCLR_CNT30_STATUS_Msk (1UL << PMU_OVSCLR_CNT30_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Mask */ + +#define PMU_OVSCLR_CYCCNT_STATUS_Pos 31U /*!< PMU OVSCLR: Cycle Counter Overflow Clear Position */ +#define PMU_OVSCLR_CYCCNT_STATUS_Msk (1UL << PMU_OVSCLR_CYCCNT_STATUS_Pos) /*!< PMU OVSCLR: Cycle Counter Overflow Clear Mask */ + +/** \brief PMU Software Increment Counter */ + +#define PMU_SWINC_CNT0_Pos 0U /*!< PMU SWINC: Event Counter 0 Software Increment Position */ +#define PMU_SWINC_CNT0_Msk (1UL /*<< PMU_SWINC_CNT0_Pos */) /*!< PMU SWINC: Event Counter 0 Software Increment Mask */ + +#define PMU_SWINC_CNT1_Pos 1U /*!< PMU SWINC: Event Counter 1 Software Increment Position */ +#define PMU_SWINC_CNT1_Msk (1UL << PMU_SWINC_CNT1_Pos) /*!< PMU SWINC: Event Counter 1 Software Increment Mask */ + +#define PMU_SWINC_CNT2_Pos 2U /*!< PMU SWINC: Event Counter 2 Software Increment Position */ +#define PMU_SWINC_CNT2_Msk (1UL << PMU_SWINC_CNT2_Pos) /*!< PMU SWINC: Event Counter 2 Software Increment Mask */ + +#define PMU_SWINC_CNT3_Pos 3U /*!< PMU SWINC: Event Counter 3 Software Increment Position */ +#define PMU_SWINC_CNT3_Msk (1UL << PMU_SWINC_CNT3_Pos) /*!< PMU SWINC: Event Counter 3 Software Increment Mask */ + +#define PMU_SWINC_CNT4_Pos 4U /*!< PMU SWINC: Event Counter 4 Software Increment Position */ +#define PMU_SWINC_CNT4_Msk (1UL << PMU_SWINC_CNT4_Pos) /*!< PMU SWINC: Event Counter 4 Software Increment Mask */ + +#define PMU_SWINC_CNT5_Pos 5U /*!< PMU SWINC: Event Counter 5 Software Increment Position */ +#define PMU_SWINC_CNT5_Msk (1UL << PMU_SWINC_CNT5_Pos) /*!< PMU SWINC: Event Counter 5 Software Increment Mask */ + +#define PMU_SWINC_CNT6_Pos 6U /*!< PMU SWINC: Event Counter 6 Software Increment Position */ +#define PMU_SWINC_CNT6_Msk (1UL << PMU_SWINC_CNT6_Pos) /*!< PMU SWINC: Event Counter 6 Software Increment Mask */ + +#define PMU_SWINC_CNT7_Pos 7U /*!< PMU SWINC: Event Counter 7 Software Increment Position */ +#define PMU_SWINC_CNT7_Msk (1UL << PMU_SWINC_CNT7_Pos) /*!< PMU SWINC: Event Counter 7 Software Increment Mask */ + +#define PMU_SWINC_CNT8_Pos 8U /*!< PMU SWINC: Event Counter 8 Software Increment Position */ +#define PMU_SWINC_CNT8_Msk (1UL << PMU_SWINC_CNT8_Pos) /*!< PMU SWINC: Event Counter 8 Software Increment Mask */ + +#define PMU_SWINC_CNT9_Pos 9U /*!< PMU SWINC: Event Counter 9 Software Increment Position */ +#define PMU_SWINC_CNT9_Msk (1UL << PMU_SWINC_CNT9_Pos) /*!< PMU SWINC: Event Counter 9 Software Increment Mask */ + +#define PMU_SWINC_CNT10_Pos 10U /*!< PMU SWINC: Event Counter 10 Software Increment Position */ +#define PMU_SWINC_CNT10_Msk (1UL << PMU_SWINC_CNT10_Pos) /*!< PMU SWINC: Event Counter 10 Software Increment Mask */ + +#define PMU_SWINC_CNT11_Pos 11U /*!< PMU SWINC: Event Counter 11 Software Increment Position */ +#define PMU_SWINC_CNT11_Msk (1UL << PMU_SWINC_CNT11_Pos) /*!< PMU SWINC: Event Counter 11 Software Increment Mask */ + +#define PMU_SWINC_CNT12_Pos 12U /*!< PMU SWINC: Event Counter 12 Software Increment Position */ +#define PMU_SWINC_CNT12_Msk (1UL << PMU_SWINC_CNT12_Pos) /*!< PMU SWINC: Event Counter 12 Software Increment Mask */ + +#define PMU_SWINC_CNT13_Pos 13U /*!< PMU SWINC: Event Counter 13 Software Increment Position */ +#define PMU_SWINC_CNT13_Msk (1UL << PMU_SWINC_CNT13_Pos) /*!< PMU SWINC: Event Counter 13 Software Increment Mask */ + +#define PMU_SWINC_CNT14_Pos 14U /*!< PMU SWINC: Event Counter 14 Software Increment Position */ +#define PMU_SWINC_CNT14_Msk (1UL << PMU_SWINC_CNT14_Pos) /*!< PMU SWINC: Event Counter 14 Software Increment Mask */ + +#define PMU_SWINC_CNT15_Pos 15U /*!< PMU SWINC: Event Counter 15 Software Increment Position */ +#define PMU_SWINC_CNT15_Msk (1UL << PMU_SWINC_CNT15_Pos) /*!< PMU SWINC: Event Counter 15 Software Increment Mask */ + +#define PMU_SWINC_CNT16_Pos 16U /*!< PMU SWINC: Event Counter 16 Software Increment Position */ +#define PMU_SWINC_CNT16_Msk (1UL << PMU_SWINC_CNT16_Pos) /*!< PMU SWINC: Event Counter 16 Software Increment Mask */ + +#define PMU_SWINC_CNT17_Pos 17U /*!< PMU SWINC: Event Counter 17 Software Increment Position */ +#define PMU_SWINC_CNT17_Msk (1UL << PMU_SWINC_CNT17_Pos) /*!< PMU SWINC: Event Counter 17 Software Increment Mask */ + +#define PMU_SWINC_CNT18_Pos 18U /*!< PMU SWINC: Event Counter 18 Software Increment Position */ +#define PMU_SWINC_CNT18_Msk (1UL << PMU_SWINC_CNT18_Pos) /*!< PMU SWINC: Event Counter 18 Software Increment Mask */ + +#define PMU_SWINC_CNT19_Pos 19U /*!< PMU SWINC: Event Counter 19 Software Increment Position */ +#define PMU_SWINC_CNT19_Msk (1UL << PMU_SWINC_CNT19_Pos) /*!< PMU SWINC: Event Counter 19 Software Increment Mask */ + +#define PMU_SWINC_CNT20_Pos 20U /*!< PMU SWINC: Event Counter 20 Software Increment Position */ +#define PMU_SWINC_CNT20_Msk (1UL << PMU_SWINC_CNT20_Pos) /*!< PMU SWINC: Event Counter 20 Software Increment Mask */ + +#define PMU_SWINC_CNT21_Pos 21U /*!< PMU SWINC: Event Counter 21 Software Increment Position */ +#define PMU_SWINC_CNT21_Msk (1UL << PMU_SWINC_CNT21_Pos) /*!< PMU SWINC: Event Counter 21 Software Increment Mask */ + +#define PMU_SWINC_CNT22_Pos 22U /*!< PMU SWINC: Event Counter 22 Software Increment Position */ +#define PMU_SWINC_CNT22_Msk (1UL << PMU_SWINC_CNT22_Pos) /*!< PMU SWINC: Event Counter 22 Software Increment Mask */ + +#define PMU_SWINC_CNT23_Pos 23U /*!< PMU SWINC: Event Counter 23 Software Increment Position */ +#define PMU_SWINC_CNT23_Msk (1UL << PMU_SWINC_CNT23_Pos) /*!< PMU SWINC: Event Counter 23 Software Increment Mask */ + +#define PMU_SWINC_CNT24_Pos 24U /*!< PMU SWINC: Event Counter 24 Software Increment Position */ +#define PMU_SWINC_CNT24_Msk (1UL << PMU_SWINC_CNT24_Pos) /*!< PMU SWINC: Event Counter 24 Software Increment Mask */ + +#define PMU_SWINC_CNT25_Pos 25U /*!< PMU SWINC: Event Counter 25 Software Increment Position */ +#define PMU_SWINC_CNT25_Msk (1UL << PMU_SWINC_CNT25_Pos) /*!< PMU SWINC: Event Counter 25 Software Increment Mask */ + +#define PMU_SWINC_CNT26_Pos 26U /*!< PMU SWINC: Event Counter 26 Software Increment Position */ +#define PMU_SWINC_CNT26_Msk (1UL << PMU_SWINC_CNT26_Pos) /*!< PMU SWINC: Event Counter 26 Software Increment Mask */ + +#define PMU_SWINC_CNT27_Pos 27U /*!< PMU SWINC: Event Counter 27 Software Increment Position */ +#define PMU_SWINC_CNT27_Msk (1UL << PMU_SWINC_CNT27_Pos) /*!< PMU SWINC: Event Counter 27 Software Increment Mask */ + +#define PMU_SWINC_CNT28_Pos 28U /*!< PMU SWINC: Event Counter 28 Software Increment Position */ +#define PMU_SWINC_CNT28_Msk (1UL << PMU_SWINC_CNT28_Pos) /*!< PMU SWINC: Event Counter 28 Software Increment Mask */ + +#define PMU_SWINC_CNT29_Pos 29U /*!< PMU SWINC: Event Counter 29 Software Increment Position */ +#define PMU_SWINC_CNT29_Msk (1UL << PMU_SWINC_CNT29_Pos) /*!< PMU SWINC: Event Counter 29 Software Increment Mask */ + +#define PMU_SWINC_CNT30_Pos 30U /*!< PMU SWINC: Event Counter 30 Software Increment Position */ +#define PMU_SWINC_CNT30_Msk (1UL << PMU_SWINC_CNT30_Pos) /*!< PMU SWINC: Event Counter 30 Software Increment Mask */ + +/** \brief PMU Control Register Definitions */ + +#define PMU_CTRL_ENABLE_Pos 0U /*!< PMU CTRL: ENABLE Position */ +#define PMU_CTRL_ENABLE_Msk (1UL /*<< PMU_CTRL_ENABLE_Pos*/) /*!< PMU CTRL: ENABLE Mask */ + +#define PMU_CTRL_EVENTCNT_RESET_Pos 1U /*!< PMU CTRL: Event Counter Reset Position */ +#define PMU_CTRL_EVENTCNT_RESET_Msk (1UL << PMU_CTRL_EVENTCNT_RESET_Pos) /*!< PMU CTRL: Event Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_RESET_Pos 2U /*!< PMU CTRL: Cycle Counter Reset Position */ +#define PMU_CTRL_CYCCNT_RESET_Msk (1UL << PMU_CTRL_CYCCNT_RESET_Pos) /*!< PMU CTRL: Cycle Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_DISABLE_Pos 5U /*!< PMU CTRL: Disable Cycle Counter Position */ +#define PMU_CTRL_CYCCNT_DISABLE_Msk (1UL << PMU_CTRL_CYCCNT_DISABLE_Pos) /*!< PMU CTRL: Disable Cycle Counter Mask */ + +#define PMU_CTRL_FRZ_ON_OV_Pos 9U /*!< PMU CTRL: Freeze-on-overflow Position */ +#define PMU_CTRL_FRZ_ON_OV_Msk (1UL << PMU_CTRL_FRZ_ON_OVERFLOW_Pos) /*!< PMU CTRL: Freeze-on-overflow Mask */ + +#define PMU_CTRL_TRACE_ON_OV_Pos 11U /*!< PMU CTRL: Trace-on-overflow Position */ +#define PMU_CTRL_TRACE_ON_OV_Msk (1UL << PMU_CTRL_TRACE_ON_OVERFLOW_Pos) /*!< PMU CTRL: Trace-on-overflow Mask */ + +/** \brief PMU Type Register Definitions */ + +#define PMU_TYPE_NUM_CNTS_Pos 0U /*!< PMU TYPE: Number of Counters Position */ +#define PMU_TYPE_NUM_CNTS_Msk (0xFFUL /*<< PMU_TYPE_NUM_CNTS_Pos*/) /*!< PMU TYPE: Number of Counters Mask */ + +#define PMU_TYPE_SIZE_CNTS_Pos 8U /*!< PMU TYPE: Size of Counters Position */ +#define PMU_TYPE_SIZE_CNTS_Msk (0x3FUL << PMU_TYPE_SIZE_CNTS_Pos) /*!< PMU TYPE: Size of Counters Mask */ + +#define PMU_TYPE_CYCCNT_PRESENT_Pos 14U /*!< PMU TYPE: Cycle Counter Present Position */ +#define PMU_TYPE_CYCCNT_PRESENT_Msk (1UL << PMU_TYPE_CYCCNT_PRESENT_Pos) /*!< PMU TYPE: Cycle Counter Present Mask */ + +#define PMU_TYPE_FRZ_OV_SUPPORT_Pos 21U /*!< PMU TYPE: Freeze-on-overflow Support Position */ +#define PMU_TYPE_FRZ_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Freeze-on-overflow Support Mask */ + +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Pos 23U /*!< PMU TYPE: Trace-on-overflow Support Position */ +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Trace-on-overflow Support Mask */ + +/** \brief PMU Authentication Status Register Definitions */ + +#define PMU_AUTHSTATUS_NSID_Pos 0U /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSID_Msk (0x3UL /*<< PMU_AUTHSTATUS_NSID_Pos*/) /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSNID_Pos 2U /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSNID_Msk (0x3UL << PMU_AUTHSTATUS_NSNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SID_Pos 4U /*!< PMU AUTHSTATUS: Secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_SID_Msk (0x3UL << PMU_AUTHSTATUS_SID_Pos) /*!< PMU AUTHSTATUS: Secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SNID_Pos 6U /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SNID_Msk (0x3UL << PMU_AUTHSTATUS_SNID_Pos) /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUID_Pos 16U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUID_Msk (0x3UL << PMU_AUTHSTATUS_NSUID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUNID_Pos 18U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUNID_Msk (0x3UL << PMU_AUTHSTATUS_NSUNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUID_Pos 20U /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_SUID_Msk (0x3UL << PMU_AUTHSTATUS_SUID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUNID_Pos 22U /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SUNID_Msk (0x3UL << PMU_AUTHSTATUS_SUNID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Mask */ + + +/*@} end of group CMSIS_PMU */ +#endif + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +#define FPU_FPDSCR_FZ16_Pos 19U /*!< FPDSCR: FZ16 bit Position */ +#define FPU_FPDSCR_FZ16_Msk (1UL << FPU_FPDSCR_FZ16_Pos) /*!< FPDSCR: FZ16 bit Mask */ + +#define FPU_FPDSCR_LTPSIZE_Pos 16U /*!< FPDSCR: LTPSIZE bit Position */ +#define FPU_FPDSCR_LTPSIZE_Msk (7UL << FPU_FPDSCR_LTPSIZE_Pos) /*!< FPDSCR: LTPSIZE bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FPRound_Pos 28U /*!< MVFR0: FPRound bits Position */ +#define FPU_MVFR0_FPRound_Msk (0xFUL << FPU_MVFR0_FPRound_Pos) /*!< MVFR0: FPRound bits Mask */ + +#define FPU_MVFR0_FPSqrt_Pos 20U /*!< MVFR0: FPSqrt bits Position */ +#define FPU_MVFR0_FPSqrt_Msk (0xFUL << FPU_MVFR0_FPSqrt_Pos) /*!< MVFR0: FPSqrt bits Mask */ + +#define FPU_MVFR0_FPDivide_Pos 16U /*!< MVFR0: FPDivide bits Position */ +#define FPU_MVFR0_FPDivide_Msk (0xFUL << FPU_MVFR0_FPDivide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FPDP_Pos 8U /*!< MVFR0: FPDP bits Position */ +#define FPU_MVFR0_FPDP_Msk (0xFUL << FPU_MVFR0_FPDP_Pos) /*!< MVFR0: FPDP bits Mask */ + +#define FPU_MVFR0_FPSP_Pos 4U /*!< MVFR0: FPSP bits Position */ +#define FPU_MVFR0_FPSP_Msk (0xFUL << FPU_MVFR0_FPSP_Pos) /*!< MVFR0: FPSP bits Mask */ + +#define FPU_MVFR0_SIMDReg_Pos 0U /*!< MVFR0: SIMDReg bits Position */ +#define FPU_MVFR0_SIMDReg_Msk (0xFUL /*<< FPU_MVFR0_SIMDReg_Pos*/) /*!< MVFR0: SIMDReg bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FMAC_Pos 28U /*!< MVFR1: FMAC bits Position */ +#define FPU_MVFR1_FMAC_Msk (0xFUL << FPU_MVFR1_FMAC_Pos) /*!< MVFR1: FMAC bits Mask */ + +#define FPU_MVFR1_FPHP_Pos 24U /*!< MVFR1: FPHP bits Position */ +#define FPU_MVFR1_FPHP_Msk (0xFUL << FPU_MVFR1_FPHP_Pos) /*!< MVFR1: FPHP bits Mask */ + +#define FPU_MVFR1_FP16_Pos 20U /*!< MVFR1: FP16 bits Position */ +#define FPU_MVFR1_FP16_Msk (0xFUL << FPU_MVFR1_FP16_Pos) /*!< MVFR1: FP16 bits Mask */ + +#define FPU_MVFR1_MVE_Pos 8U /*!< MVFR1: MVE bits Position */ +#define FPU_MVFR1_MVE_Msk (0xFUL << FPU_MVFR1_MVE_Pos) /*!< MVFR1: MVE bits Mask */ + +#define FPU_MVFR1_FPDNaN_Pos 4U /*!< MVFR1: FPDNaN bits Position */ +#define FPU_MVFR1_FPDNaN_Msk (0xFUL << FPU_MVFR1_FPDNaN_Pos) /*!< MVFR1: FPDNaN bits Mask */ + +#define FPU_MVFR1_FPFtZ_Pos 0U /*!< MVFR1: FPFtZ bits Position */ +#define FPU_MVFR1_FPFtZ_Msk (0xFUL /*<< FPU_MVFR1_FPFtZ_Pos*/) /*!< MVFR1: FPFtZ bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_FPD_Pos 23U /*!< \deprecated CoreDebug DHCSR: S_FPD Position */ +#define CoreDebug_DHCSR_S_FPD_Msk (1UL << CoreDebug_DHCSR_S_FPD_Pos) /*!< \deprecated CoreDebug DHCSR: S_FPD Mask */ + +#define CoreDebug_DHCSR_S_SUIDE_Pos 22U /*!< \deprecated CoreDebug DHCSR: S_SUIDE Position */ +#define CoreDebug_DHCSR_S_SUIDE_Msk (1UL << CoreDebug_DHCSR_S_SUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SUIDE Mask */ + +#define CoreDebug_DHCSR_S_NSUIDE_Pos 21U /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Position */ +#define CoreDebug_DHCSR_S_NSUIDE_Msk (1UL << CoreDebug_DHCSR_S_NSUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Mask */ + +#define CoreDebug_DHCSR_S_SDE_Pos 20U /*!< \deprecated CoreDebug DHCSR: S_SDE Position */ +#define CoreDebug_DHCSR_S_SDE_Msk (1UL << CoreDebug_DHCSR_S_SDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SDE Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_PMOV_Pos 6U /*!< \deprecated CoreDebug DHCSR: C_PMOV Position */ +#define CoreDebug_DHCSR_C_PMOV_Msk (1UL << CoreDebug_DHCSR_C_PMOV_Pos) /*!< \deprecated CoreDebug DHCSR: C_PMOV Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Set Clear Exception and Monitor Control Register Definitions */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_REQ_Pos 3U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_SET_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_PEND_Pos 1U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_SET_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_UIDEN_Pos 10U /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_UIDAPEN_Pos 9U /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDAPEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDAPEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Mask */ + +#define CoreDebug_DAUTHCTRL_FSDMA_Pos 8U /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Position */ +#define CoreDebug_DAUTHCTRL_FSDMA_Msk (1UL << CoreDebug_DAUTHCTRL_FSDMA_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_FPD_Pos 23U /*!< DCB DHCSR: Floating-point registers Debuggable Position */ +#define DCB_DHCSR_S_FPD_Msk (0x1UL << DCB_DHCSR_S_FPD_Pos) /*!< DCB DHCSR: Floating-point registers Debuggable Mask */ + +#define DCB_DHCSR_S_SUIDE_Pos 22U /*!< DCB DHCSR: Secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_SUIDE_Msk (0x1UL << DCB_DHCSR_S_SUIDE_Pos) /*!< DCB DHCSR: Secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_NSUIDE_Pos 21U /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_NSUIDE_Msk (0x1UL << DCB_DHCSR_S_NSUIDE_Pos) /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_PMOV_Pos 6U /*!< DCB DHCSR: Halt on PMU overflow control Position */ +#define DCB_DHCSR_C_PMOV_Msk (0x1UL << DCB_DHCSR_C_PMOV_Pos) /*!< DCB DHCSR: Halt on PMU overflow control Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DSCEMCR, Debug Set Clear Exception and Monitor Control Register Definitions */ +#define DCB_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< DCB DSCEMCR: Clear monitor request Position */ +#define DCB_DSCEMCR_CLR_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_REQ_Pos) /*!< DCB DSCEMCR: Clear monitor request Mask */ + +#define DCB_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< DCB DSCEMCR: Clear monitor pend Position */ +#define DCB_DSCEMCR_CLR_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_PEND_Pos) /*!< DCB DSCEMCR: Clear monitor pend Mask */ + +#define DCB_DSCEMCR_SET_MON_REQ_Pos 3U /*!< DCB DSCEMCR: Set monitor request Position */ +#define DCB_DSCEMCR_SET_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_SET_MON_REQ_Pos) /*!< DCB DSCEMCR: Set monitor request Mask */ + +#define DCB_DSCEMCR_SET_MON_PEND_Pos 1U /*!< DCB DSCEMCR: Set monitor pend Position */ +#define DCB_DSCEMCR_SET_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_SET_MON_PEND_Pos) /*!< DCB DSCEMCR: Set monitor pend Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_UIDEN_Pos 10U /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Position */ +#define DCB_DAUTHCTRL_UIDEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Mask */ + +#define DCB_DAUTHCTRL_UIDAPEN_Pos 9U /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Position */ +#define DCB_DAUTHCTRL_UIDAPEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDAPEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Mask */ + +#define DCB_DAUTHCTRL_FSDMA_Pos 8U /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Position */ +#define DCB_DAUTHCTRL_FSDMA_Msk (0x1UL << DCB_DAUTHCTRL_FSDMA_Pos) /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Mask */ + +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SUNID_Pos 22U /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUNID_Msk (0x3UL << DIB_DAUTHSTATUS_SUNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SUID_Pos 20U /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUID_Msk (0x3UL << DIB_DAUTHSTATUS_SUID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_NSUNID_Pos 18U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Position */ +#define DIB_DAUTHSTATUS_NSUNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Mask */ + +#define DIB_DAUTHSTATUS_NSUID_Pos 16U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_NSUID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define MEMSYSCTL_BASE (0xE001E000UL) /*!< Memory System Control Base Address */ + #define ERRBNK_BASE (0xE001E100UL) /*!< Error Banking Base Address */ + #define PWRMODCTL_BASE (0xE001E300UL) /*!< Power Mode Control Base Address */ + #define EWIC_BASE (0xE001E400UL) /*!< External Wakeup Interrupt Controller Base Address */ + #define PRCCFGINF_BASE (0xE001E700UL) /*!< Processor Configuration Information Base Address */ + #define STL_BASE (0xE001E800UL) /*!< Software Test Library Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define ICB ((ICB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define MEMSYSCTL ((MemSysCtl_Type *) MEMSYSCTL_BASE ) /*!< Memory System Control configuration struct */ + #define ERRBNK ((ErrBnk_Type *) ERRBNK_BASE ) /*!< Error Banking configuration struct */ + #define PWRMODCTL ((PwrModCtl_Type *) PWRMODCTL_BASE ) /*!< Power Mode Control configuration struct */ + #define EWIC ((EWIC_Type *) EWIC_BASE ) /*!< EWIC configuration struct */ + #define PRCCFGINF ((PrcCfgInf_Type *) PRCCFGINF_BASE ) /*!< Processor Configuration Information configuration struct */ + #define STL ((STL_Type *) STL_BASE ) /*!< Software Test Library configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + #define PMU_BASE (0xE0003000UL) /*!< PMU Base Address */ + #define PMU ((PMU_Type *) PMU_BASE ) /*!< PMU configuration struct */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define ICB_NS ((ICB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ +#define ID_ADR (ID_AFR) /*!< SCB Auxiliary Feature Register */ + +/* 'SCnSCB' is deprecated and replaced by 'ICB' */ +typedef ICB_Type SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISCRITAXIRUW_Pos (ICB_ACTLR_DISCRITAXIRUW_Pos) +#define SCnSCB_ACTLR_DISCRITAXIRUW_Msk (ICB_ACTLR_DISCRITAXIRUW_Msk) + +#define SCnSCB_ACTLR_DISDI_Pos (ICB_ACTLR_DISDI_Pos) +#define SCnSCB_ACTLR_DISDI_Msk (ICB_ACTLR_DISDI_Msk) + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos (ICB_ACTLR_DISCRITAXIRUR_Pos) +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (ICB_ACTLR_DISCRITAXIRUR_Msk) + +#define SCnSCB_ACTLR_EVENTBUSEN_Pos (ICB_ACTLR_EVENTBUSEN_Pos) +#define SCnSCB_ACTLR_EVENTBUSEN_Msk (ICB_ACTLR_EVENTBUSEN_Msk) + +#define SCnSCB_ACTLR_EVENTBUSEN_S_Pos (ICB_ACTLR_EVENTBUSEN_S_Pos) +#define SCnSCB_ACTLR_EVENTBUSEN_S_Msk (ICB_ACTLR_EVENTBUSEN_S_Msk) + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos (ICB_ACTLR_DISITMATBFLUSH_Pos) +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (ICB_ACTLR_DISITMATBFLUSH_Msk) + +#define SCnSCB_ACTLR_DISNWAMODE_Pos (ICB_ACTLR_DISNWAMODE_Pos) +#define SCnSCB_ACTLR_DISNWAMODE_Msk (ICB_ACTLR_DISNWAMODE_Msk) + +#define SCnSCB_ACTLR_FPEXCODIS_Pos (ICB_ACTLR_FPEXCODIS_Pos) +#define SCnSCB_ACTLR_FPEXCODIS_Msk (ICB_ACTLR_FPEXCODIS_Msk) + +#define SCnSCB_ACTLR_DISOLAP_Pos (ICB_ACTLR_DISOLAP_Pos) +#define SCnSCB_ACTLR_DISOLAP_Msk (ICB_ACTLR_DISOLAP_Msk) + +#define SCnSCB_ACTLR_DISOLAPS_Pos (ICB_ACTLR_DISOLAPS_Pos) +#define SCnSCB_ACTLR_DISOLAPS_Msk (ICB_ACTLR_DISOLAPS_Msk) + +#define SCnSCB_ACTLR_DISLOBR_Pos (ICB_ACTLR_DISLOBR_Pos) +#define SCnSCB_ACTLR_DISLOBR_Msk (ICB_ACTLR_DISLOBR_Msk) + +#define SCnSCB_ACTLR_DISLO_Pos (ICB_ACTLR_DISLO_Pos) +#define SCnSCB_ACTLR_DISLO_Msk (ICB_ACTLR_DISLO_Msk) + +#define SCnSCB_ACTLR_DISLOLEP_Pos (ICB_ACTLR_DISLOLEP_Pos) +#define SCnSCB_ACTLR_DISLOLEP_Msk (ICB_ACTLR_DISLOLEP_Msk) + +#define SCnSCB_ACTLR_DISFOLD_Pos (ICB_ACTLR_DISFOLD_Pos) +#define SCnSCB_ACTLR_DISFOLD_Msk (ICB_ACTLR_DISFOLD_Msk) + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos (ICB_ICTR_INTLINESNUM_Pos) +#define SCnSCB_ICTR_INTLINESNUM_Msk (ICB_ICTR_INTLINESNUM_Msk) + +#define SCnSCB (ICB) +#define SCnSCB_NS (ICB_NS) + +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## PMU functions and events #################################### */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + +#include "pmu_armv8.h" + +/** + \brief Cortex-M55 PMU events + \note Architectural PMU events can be found in pmu_armv8.h +*/ + +#define ARMCM55_PMU_ECC_ERR 0xC000 /*!< Any ECC error */ +#define ARMCM55_PMU_ECC_ERR_FATAL 0xC001 /*!< Any fatal ECC error */ +#define ARMCM55_PMU_ECC_ERR_DCACHE 0xC010 /*!< Any ECC error in the data cache */ +#define ARMCM55_PMU_ECC_ERR_ICACHE 0xC011 /*!< Any ECC error in the instruction cache */ +#define ARMCM55_PMU_ECC_ERR_FATAL_DCACHE 0xC012 /*!< Any fatal ECC error in the data cache */ +#define ARMCM55_PMU_ECC_ERR_FATAL_ICACHE 0xC013 /*!< Any fatal ECC error in the instruction cache*/ +#define ARMCM55_PMU_ECC_ERR_DTCM 0xC020 /*!< Any ECC error in the DTCM */ +#define ARMCM55_PMU_ECC_ERR_ITCM 0xC021 /*!< Any ECC error in the ITCM */ +#define ARMCM55_PMU_ECC_ERR_FATAL_DTCM 0xC022 /*!< Any fatal ECC error in the DTCM */ +#define ARMCM55_PMU_ECC_ERR_FATAL_ITCM 0xC023 /*!< Any fatal ECC error in the ITCM */ +#define ARMCM55_PMU_PF_LINEFILL 0xC100 /*!< A prefetcher starts a line-fill */ +#define ARMCM55_PMU_PF_CANCEL 0xC101 /*!< A prefetcher stops prefetching */ +#define ARMCM55_PMU_PF_DROP_LINEFILL 0xC102 /*!< A linefill triggered by a prefetcher has been dropped because of lack of buffering */ +#define ARMCM55_PMU_NWAMODE_ENTER 0xC200 /*!< No write-allocate mode entry */ +#define ARMCM55_PMU_NWAMODE 0xC201 /*!< Write-allocate store is not allocated into the data cache due to no-write-allocate mode */ +#define ARMCM55_PMU_SAHB_ACCESS 0xC300 /*!< Read or write access on the S-AHB interface to the TCM */ +#define ARMCM55_PMU_PAHB_ACCESS 0xC301 /*!< Read or write access to the P-AHB write interface */ +#define ARMCM55_PMU_AXI_WRITE_ACCESS 0xC302 /*!< Any beat access to M-AXI write interface */ +#define ARMCM55_PMU_AXI_READ_ACCESS 0xC303 /*!< Any beat access to M-AXI read interface */ +#define ARMCM55_PMU_DOSTIMEOUT_DOUBLE 0xC400 /*!< Denial of Service timeout has fired twice and caused buffers to drain to allow forward progress */ +#define ARMCM55_PMU_DOSTIMEOUT_TRIPLE 0xC401 /*!< Denial of Service timeout has fired three times and blocked the LSU to force forward progress */ + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + +/* ########################## MVE functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_MveFunctions MVE Functions + \brief Function that provides MVE type. + @{ + */ + +/** + \brief get MVE type + \details returns the MVE type + \returns + - \b 0: No Vector Extension (MVE) + - \b 1: Integer Vector Extension (MVE-I) + - \b 2: Floating-point Vector Extension (MVE-F) + */ +__STATIC_INLINE uint32_t SCB_GetMVEType(void) +{ + const uint32_t mvfr1 = FPU->MVFR1; + if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x2U << FPU_MVFR1_MVE_Pos)) + { + return 2U; + } + else if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x1U << FPU_MVFR1_MVE_Pos)) + { + return 1U; + } + else + { + return 0U; + } +} + + +/*@} end of CMSIS_Core_MveFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM55_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm7.h b/Drivers/CMSIS/Include/core_cm7.h new file mode 100644 index 0000000..010506e --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm7.h @@ -0,0 +1,2366 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.1.6 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ + uint32_t RESERVED7[5U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< \deprecated SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< \deprecated SCB CACR: ECCEN Mask */ + +#define SCB_CACR_ECCDIS_Pos 1U /*!< SCB CACR: ECCDIS Position */ +#define SCB_CACR_ECCDIS_Msk (1UL << SCB_CACR_ECCDIS_Pos) /*!< SCB CACR: ECCDIS Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBSCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBSCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBSCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ +#define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ + +#define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ +#define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ + +#define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ +#define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ + +#define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ +#define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + +/*@} end of CMSIS_Core_FpuFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_cm85.h b/Drivers/CMSIS/Include/core_cm85.h new file mode 100644 index 0000000..6046311 --- /dev/null +++ b/Drivers/CMSIS/Include/core_cm85.h @@ -0,0 +1,4672 @@ +/**************************************************************************//** + * @file core_cm85.h + * @brief CMSIS Cortex-M85 Core Peripheral Access Layer Header File + * @version V1.0.4 + * @date 21. April 2022 + ******************************************************************************/ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_CM85_H_GENERIC +#define __CORE_CM85_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M85 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM85 definitions */ + +#define __CORTEX_M (85U) /*!< Cortex-M Core */ + +#if defined ( __CC_ARM ) + #error Legacy Arm Compiler does not support Armv8.1-M target architecture. +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM85_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM85_H_DEPENDANT +#define __CORE_CM85_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM85_REV + #define __CM85_REV 0x0001U + #warning "__CM85_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #if __FPU_PRESENT != 0U + #ifndef __FPU_DP + #define __FPU_DP 0U + #warning "__FPU_DP not defined in device header file; using default!" + #endif + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __PMU_PRESENT + #define __PMU_PRESENT 0U + #warning "__PMU_PRESENT not defined in device header file; using default!" + #endif + + #if __PMU_PRESENT != 0U + #ifndef __PMU_NUM_EVENTCNT + #define __PMU_NUM_EVENTCNT 8U + #warning "__PMU_NUM_EVENTCNT not defined in device header file; using default!" + #elif (__PMU_NUM_EVENTCNT > 8 || __PMU_NUM_EVENTCNT < 2) + #error "__PMU_NUM_EVENTCNT is out of range in device header file!" */ + #endif + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M85 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core EWIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core PMU Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:1; /*!< bit: 20 Reserved */ + uint32_t B:1; /*!< bit: 21 BTI active (read 0) */ + uint32_t _reserved2:2; /*!< bit: 22..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_B_Pos 21U /*!< xPSR: B Position */ +#define xPSR_B_Msk (1UL << xPSR_B_Pos) /*!< xPSR: B Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t BTI_EN:1; /*!< bit: 4 Privileged branch target identification enable */ + uint32_t UBTI_EN:1; /*!< bit: 5 Unprivileged branch target identification enable */ + uint32_t PAC_EN:1; /*!< bit: 6 Privileged pointer authentication enable */ + uint32_t UPAC_EN:1; /*!< bit: 7 Unprivileged pointer authentication enable */ + uint32_t _reserved1:24; /*!< bit: 8..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_UPAC_EN_Pos 7U /*!< CONTROL: UPAC_EN Position */ +#define CONTROL_UPAC_EN_Msk (1UL << CONTROL_UPAC_EN_Pos) /*!< CONTROL: UPAC_EN Mask */ + +#define CONTROL_PAC_EN_Pos 6U /*!< CONTROL: PAC_EN Position */ +#define CONTROL_PAC_EN_Msk (1UL << CONTROL_PAC_EN_Pos) /*!< CONTROL: PAC_EN Mask */ + +#define CONTROL_UBTI_EN_Pos 5U /*!< CONTROL: UBTI_EN Position */ +#define CONTROL_UBTI_EN_Msk (1UL << CONTROL_UBTI_EN_Pos) /*!< CONTROL: UBTI_EN Mask */ + +#define CONTROL_BTI_EN_Pos 4U /*!< CONTROL: BTI_EN Position */ +#define CONTROL_BTI_EN_Msk (1UL << CONTROL_BTI_EN_Pos) /*!< CONTROL: BTI_EN Mask */ + +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED7[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + __IOM uint32_t RFSR; /*!< Offset: 0x204 (R/W) RAS Fault Status Register */ + uint32_t RESERVED4[14U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_IESB_Pos 5U /*!< SCB AIRCR: Implicit ESB Enable Position */ +#define SCB_AIRCR_IESB_Msk (1UL << SCB_AIRCR_IESB_Pos) /*!< SCB AIRCR: Implicit ESB Enable Mask */ + +#define SCB_AIRCR_DIT_Pos 4U /*!< SCB AIRCR: Data Independent Timing Position */ +#define SCB_AIRCR_DIT_Msk (1UL << SCB_AIRCR_DIT_Pos) /*!< SCB AIRCR: Data Independent Timing Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_TRD_Pos 20U /*!< SCB CCR: TRD Position */ +#define SCB_CCR_TRD_Msk (1UL << SCB_CCR_TRD_Pos) /*!< SCB CCR: TRD Mask */ + +#define SCB_CCR_LOB_Pos 19U /*!< SCB CCR: LOB Position */ +#define SCB_CCR_LOB_Msk (1UL << SCB_CCR_LOB_Pos) /*!< SCB CCR: LOB Mask */ + +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_PMU_Pos 5U /*!< SCB DFSR: PMU Position */ +#define SCB_DFSR_PMU_Msk (1UL << SCB_DFSR_PMU_Pos) /*!< SCB DFSR: PMU Mask */ + +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CP7_Pos 7U /*!< SCB NSACR: CP7 Position */ +#define SCB_NSACR_CP7_Msk (1UL << SCB_NSACR_CP7_Pos) /*!< SCB NSACR: CP7 Mask */ + +#define SCB_NSACR_CP6_Pos 6U /*!< SCB NSACR: CP6 Position */ +#define SCB_NSACR_CP6_Msk (1UL << SCB_NSACR_CP6_Pos) /*!< SCB NSACR: CP6 Mask */ + +#define SCB_NSACR_CP5_Pos 5U /*!< SCB NSACR: CP5 Position */ +#define SCB_NSACR_CP5_Msk (1UL << SCB_NSACR_CP5_Pos) /*!< SCB NSACR: CP5 Mask */ + +#define SCB_NSACR_CP4_Pos 4U /*!< SCB NSACR: CP4 Position */ +#define SCB_NSACR_CP4_Msk (1UL << SCB_NSACR_CP4_Pos) /*!< SCB NSACR: CP4 Mask */ + +#define SCB_NSACR_CP3_Pos 3U /*!< SCB NSACR: CP3 Position */ +#define SCB_NSACR_CP3_Msk (1UL << SCB_NSACR_CP3_Pos) /*!< SCB NSACR: CP3 Mask */ + +#define SCB_NSACR_CP2_Pos 2U /*!< SCB NSACR: CP2 Position */ +#define SCB_NSACR_CP2_Msk (1UL << SCB_NSACR_CP2_Pos) /*!< SCB NSACR: CP2 Mask */ + +#define SCB_NSACR_CP1_Pos 1U /*!< SCB NSACR: CP1 Position */ +#define SCB_NSACR_CP1_Msk (1UL << SCB_NSACR_CP1_Pos) /*!< SCB NSACR: CP1 Mask */ + +#define SCB_NSACR_CP0_Pos 0U /*!< SCB NSACR: CP0 Position */ +#define SCB_NSACR_CP0_Msk (1UL /*<< SCB_NSACR_CP0_Pos*/) /*!< SCB NSACR: CP0 Mask */ + +/* SCB Debug Feature Register 0 Definitions */ +#define SCB_ID_DFR_UDE_Pos 28U /*!< SCB ID_DFR: UDE Position */ +#define SCB_ID_DFR_UDE_Msk (0xFUL << SCB_ID_DFR_UDE_Pos) /*!< SCB ID_DFR: UDE Mask */ + +#define SCB_ID_DFR_MProfDbg_Pos 20U /*!< SCB ID_DFR: MProfDbg Position */ +#define SCB_ID_DFR_MProfDbg_Msk (0xFUL << SCB_ID_DFR_MProfDbg_Pos) /*!< SCB ID_DFR: MProfDbg Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB RAS Fault Status Register Definitions */ +#define SCB_RFSR_V_Pos 31U /*!< SCB RFSR: V Position */ +#define SCB_RFSR_V_Msk (1UL << SCB_RFSR_V_Pos) /*!< SCB RFSR: V Mask */ + +#define SCB_RFSR_IS_Pos 16U /*!< SCB RFSR: IS Position */ +#define SCB_RFSR_IS_Msk (0x7FFFUL << SCB_RFSR_IS_Pos) /*!< SCB RFSR: IS Mask */ + +#define SCB_RFSR_UET_Pos 0U /*!< SCB RFSR: UET Position */ +#define SCB_RFSR_UET_Msk (3UL /*<< SCB_RFSR_UET_Pos*/) /*!< SCB RFSR: UET Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ICB Implementation Control Block register (ICB) + \brief Type definitions for the Implementation Control Block Register + @{ + */ + +/** + \brief Structure type to access the Implementation Control Block (ICB). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} ICB_Type; + +/* Auxiliary Control Register Definitions */ +#define ICB_ACTLR_DISCRITAXIRUW_Pos 27U /*!< ACTLR: DISCRITAXIRUW Position */ +#define ICB_ACTLR_DISCRITAXIRUW_Msk (1UL << ICB_ACTLR_DISCRITAXIRUW_Pos) /*!< ACTLR: DISCRITAXIRUW Mask */ + +#define ICB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define ICB_ACTLR_DISCRITAXIRUR_Msk (1UL << ICB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define ICB_ACTLR_EVENTBUSEN_Pos 14U /*!< ACTLR: EVENTBUSEN Position */ +#define ICB_ACTLR_EVENTBUSEN_Msk (1UL << ICB_ACTLR_EVENTBUSEN_Pos) /*!< ACTLR: EVENTBUSEN Mask */ + +#define ICB_ACTLR_EVENTBUSEN_S_Pos 13U /*!< ACTLR: EVENTBUSEN_S Position */ +#define ICB_ACTLR_EVENTBUSEN_S_Msk (1UL << ICB_ACTLR_EVENTBUSEN_S_Pos) /*!< ACTLR: EVENTBUSEN_S Mask */ + +#define ICB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define ICB_ACTLR_DISITMATBFLUSH_Msk (1UL << ICB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define ICB_ACTLR_DISNWAMODE_Pos 11U /*!< ACTLR: DISNWAMODE Position */ +#define ICB_ACTLR_DISNWAMODE_Msk (1UL << ICB_ACTLR_DISNWAMODE_Pos) /*!< ACTLR: DISNWAMODE Mask */ + +#define ICB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define ICB_ACTLR_FPEXCODIS_Msk (1UL << ICB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +/* Interrupt Controller Type Register Definitions */ +#define ICB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define ICB_ICTR_INTLINESNUM_Msk (0xFUL /*<< ICB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_ICB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[3U]; + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) ITM Device Type Register */ + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup MemSysCtl_Type Memory System Control Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Memory System Control Registers (MEMSYSCTL) + @{ + */ + +/** + \brief Structure type to access the Memory System Control Registers (MEMSYSCTL). + */ +typedef struct +{ + __IOM uint32_t MSCR; /*!< Offset: 0x000 (R/W) Memory System Control Register */ + __IOM uint32_t PFCR; /*!< Offset: 0x004 (R/W) Prefetcher Control Register */ + uint32_t RESERVED1[2U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x010 (R/W) ITCM Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x014 (R/W) DTCM Control Register */ + __IOM uint32_t PAHBCR; /*!< Offset: 0x018 (R/W) P-AHB Control Register */ + uint32_t RESERVED2[313U]; + __IOM uint32_t ITGU_CTRL; /*!< Offset: 0x500 (R/W) ITGU Control Register */ + __IOM uint32_t ITGU_CFG; /*!< Offset: 0x504 (R/W) ITGU Configuration Register */ + uint32_t RESERVED3[2U]; + __IOM uint32_t ITGU_LUT[16U]; /*!< Offset: 0x510 (R/W) ITGU Look Up Table Register */ + uint32_t RESERVED4[44U]; + __IOM uint32_t DTGU_CTRL; /*!< Offset: 0x600 (R/W) DTGU Control Registers */ + __IOM uint32_t DTGU_CFG; /*!< Offset: 0x604 (R/W) DTGU Configuration Register */ + uint32_t RESERVED5[2U]; + __IOM uint32_t DTGU_LUT[16U]; /*!< Offset: 0x610 (R/W) DTGU Look Up Table Register */ +} MemSysCtl_Type; + +/* MEMSYSCTL Memory System Control Register (MSCR) Register Definitions */ +#define MEMSYSCTL_MSCR_CPWRDN_Pos 17U /*!< MEMSYSCTL MSCR: CPWRDN Position */ +#define MEMSYSCTL_MSCR_CPWRDN_Msk (0x1UL << MEMSYSCTL_MSCR_CPWRDN_Pos) /*!< MEMSYSCTL MSCR: CPWRDN Mask */ + +#define MEMSYSCTL_MSCR_DCCLEAN_Pos 16U /*!< MEMSYSCTL MSCR: DCCLEAN Position */ +#define MEMSYSCTL_MSCR_DCCLEAN_Msk (0x1UL << MEMSYSCTL_MSCR_DCCLEAN_Pos) /*!< MEMSYSCTL MSCR: DCCLEAN Mask */ + +#define MEMSYSCTL_MSCR_ICACTIVE_Pos 13U /*!< MEMSYSCTL MSCR: ICACTIVE Position */ +#define MEMSYSCTL_MSCR_ICACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_ICACTIVE_Pos) /*!< MEMSYSCTL MSCR: ICACTIVE Mask */ + +#define MEMSYSCTL_MSCR_DCACTIVE_Pos 12U /*!< MEMSYSCTL MSCR: DCACTIVE Position */ +#define MEMSYSCTL_MSCR_DCACTIVE_Msk (0x1UL << MEMSYSCTL_MSCR_DCACTIVE_Pos) /*!< MEMSYSCTL MSCR: DCACTIVE Mask */ + +#define MEMSYSCTL_MSCR_EVECCFAULT_Pos 3U /*!< MEMSYSCTL MSCR: EVECCFAULT Position */ +#define MEMSYSCTL_MSCR_EVECCFAULT_Msk (0x1UL << MEMSYSCTL_MSCR_EVECCFAULT_Pos) /*!< MEMSYSCTL MSCR: EVECCFAULT Mask */ + +#define MEMSYSCTL_MSCR_FORCEWT_Pos 2U /*!< MEMSYSCTL MSCR: FORCEWT Position */ +#define MEMSYSCTL_MSCR_FORCEWT_Msk (0x1UL << MEMSYSCTL_MSCR_FORCEWT_Pos) /*!< MEMSYSCTL MSCR: FORCEWT Mask */ + +#define MEMSYSCTL_MSCR_ECCEN_Pos 1U /*!< MEMSYSCTL MSCR: ECCEN Position */ +#define MEMSYSCTL_MSCR_ECCEN_Msk (0x1UL << MEMSYSCTL_MSCR_ECCEN_Pos) /*!< MEMSYSCTL MSCR: ECCEN Mask */ + +/* MEMSYSCTL Prefetcher Control Register (PFCR) Register Definitions */ +#define MEMSYSCTL_PFCR_DIS_NLP_Pos 7U /*!< MEMSYSCTL PFCR: DIS_NLP Position */ +#define MEMSYSCTL_PFCR_DIS_NLP_Msk (0x1UL << MEMSYSCTL_PFCR_DIS_NLP_Pos) /*!< MEMSYSCTL PFCR: DIS_NLP Mask */ + +#define MEMSYSCTL_PFCR_ENABLE_Pos 0U /*!< MEMSYSCTL PFCR: ENABLE Position */ +#define MEMSYSCTL_PFCR_ENABLE_Msk (0x1UL /*<< MEMSYSCTL_PFCR_ENABLE_Pos*/) /*!< MEMSYSCTL PFCR: ENABLE Mask */ + +/* MEMSYSCTL ITCM Control Register (ITCMCR) Register Definitions */ +#define MEMSYSCTL_ITCMCR_SZ_Pos 3U /*!< MEMSYSCTL ITCMCR: SZ Position */ +#define MEMSYSCTL_ITCMCR_SZ_Msk (0xFUL << MEMSYSCTL_ITCMCR_SZ_Pos) /*!< MEMSYSCTL ITCMCR: SZ Mask */ + +#define MEMSYSCTL_ITCMCR_EN_Pos 0U /*!< MEMSYSCTL ITCMCR: EN Position */ +#define MEMSYSCTL_ITCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_ITCMCR_EN_Pos*/) /*!< MEMSYSCTL ITCMCR: EN Mask */ + +/* MEMSYSCTL DTCM Control Register (DTCMCR) Register Definitions */ +#define MEMSYSCTL_DTCMCR_SZ_Pos 3U /*!< MEMSYSCTL DTCMCR: SZ Position */ +#define MEMSYSCTL_DTCMCR_SZ_Msk (0xFUL << MEMSYSCTL_DTCMCR_SZ_Pos) /*!< MEMSYSCTL DTCMCR: SZ Mask */ + +#define MEMSYSCTL_DTCMCR_EN_Pos 0U /*!< MEMSYSCTL DTCMCR: EN Position */ +#define MEMSYSCTL_DTCMCR_EN_Msk (0x1UL /*<< MEMSYSCTL_DTCMCR_EN_Pos*/) /*!< MEMSYSCTL DTCMCR: EN Mask */ + +/* MEMSYSCTL P-AHB Control Register (PAHBCR) Register Definitions */ +#define MEMSYSCTL_PAHBCR_SZ_Pos 1U /*!< MEMSYSCTL PAHBCR: SZ Position */ +#define MEMSYSCTL_PAHBCR_SZ_Msk (0x7UL << MEMSYSCTL_PAHBCR_SZ_Pos) /*!< MEMSYSCTL PAHBCR: SZ Mask */ + +#define MEMSYSCTL_PAHBCR_EN_Pos 0U /*!< MEMSYSCTL PAHBCR: EN Position */ +#define MEMSYSCTL_PAHBCR_EN_Msk (0x1UL /*<< MEMSYSCTL_PAHBCR_EN_Pos*/) /*!< MEMSYSCTL PAHBCR: EN Mask */ + +/* MEMSYSCTL ITGU Control Register (ITGU_CTRL) Register Definitions */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL ITGU_CTRL: DEREN Position */ +#define MEMSYSCTL_ITGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_ITGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL ITGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL ITGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_ITGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_ITGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL ITGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL ITGU Configuration Register (ITGU_CFG) Register Definitions */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL ITGU_CFG: PRESENT Position */ +#define MEMSYSCTL_ITGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_ITGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL ITGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_ITGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_ITGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL ITGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL ITGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_ITGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_ITGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL ITGU_CFG: BLKSZ Mask */ + +/* MEMSYSCTL DTGU Control Registers (DTGU_CTRL) Register Definitions */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Pos 1U /*!< MEMSYSCTL DTGU_CTRL: DEREN Position */ +#define MEMSYSCTL_DTGU_CTRL_DEREN_Msk (0x1UL << MEMSYSCTL_DTGU_CTRL_DEREN_Pos) /*!< MEMSYSCTL DTGU_CTRL: DEREN Mask */ + +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Pos 0U /*!< MEMSYSCTL DTGU_CTRL: DBFEN Position */ +#define MEMSYSCTL_DTGU_CTRL_DBFEN_Msk (0x1UL /*<< MEMSYSCTL_DTGU_CTRL_DBFEN_Pos*/) /*!< MEMSYSCTL DTGU_CTRL: DBFEN Mask */ + +/* MEMSYSCTL DTGU Configuration Register (DTGU_CFG) Register Definitions */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Pos 31U /*!< MEMSYSCTL DTGU_CFG: PRESENT Position */ +#define MEMSYSCTL_DTGU_CFG_PRESENT_Msk (0x1UL << MEMSYSCTL_DTGU_CFG_PRESENT_Pos) /*!< MEMSYSCTL DTGU_CFG: PRESENT Mask */ + +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos 8U /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Position */ +#define MEMSYSCTL_DTGU_CFG_NUMBLKS_Msk (0xFUL << MEMSYSCTL_DTGU_CFG_NUMBLKS_Pos) /*!< MEMSYSCTL DTGU_CFG: NUMBLKS Mask */ + +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Pos 0U /*!< MEMSYSCTL DTGU_CFG: BLKSZ Position */ +#define MEMSYSCTL_DTGU_CFG_BLKSZ_Msk (0xFUL /*<< MEMSYSCTL_DTGU_CFG_BLKSZ_Pos*/) /*!< MEMSYSCTL DTGU_CFG: BLKSZ Mask */ + + +/*@}*/ /* end of group MemSysCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PwrModCtl_Type Power Mode Control Registers + \brief Type definitions for the Power Mode Control Registers (PWRMODCTL) + @{ + */ + +/** + \brief Structure type to access the Power Mode Control Registers (PWRMODCTL). + */ +typedef struct +{ + __IOM uint32_t CPDLPSTATE; /*!< Offset: 0x000 (R/W) Core Power Domain Low Power State Register */ + __IOM uint32_t DPDLPSTATE; /*!< Offset: 0x004 (R/W) Debug Power Domain Low Power State Register */ +} PwrModCtl_Type; + +/* PWRMODCTL Core Power Domain Low Power State (CPDLPSTATE) Register Definitions */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos 8U /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_RLPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_RLPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: RLPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos 4U /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk (0x3UL << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos) /*!< PWRMODCTL CPDLPSTATE: ELPSTATE Mask */ + +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos 0U /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Position */ +#define PWRMODCTL_CPDLPSTATE_CLPSTATE_Msk (0x3UL /*<< PWRMODCTL_CPDLPSTATE_CLPSTATE_Pos*/) /*!< PWRMODCTL CPDLPSTATE: CLPSTATE Mask */ + +/* PWRMODCTL Debug Power Domain Low Power State (DPDLPSTATE) Register Definitions */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos 0U /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Position */ +#define PWRMODCTL_DPDLPSTATE_DLPSTATE_Msk (0x3UL /*<< PWRMODCTL_DPDLPSTATE_DLPSTATE_Pos*/) /*!< PWRMODCTL DPDLPSTATE: DLPSTATE Mask */ + +/*@}*/ /* end of group PwrModCtl_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup EWIC_Type External Wakeup Interrupt Controller Registers + \brief Type definitions for the External Wakeup Interrupt Controller Registers (EWIC) + @{ + */ + +/** + \brief Structure type to access the External Wakeup Interrupt Controller Registers (EWIC). + */ +typedef struct +{ + __OM uint32_t EVENTSPR; /*!< Offset: 0x000 ( /W) Event Set Pending Register */ + uint32_t RESERVED0[31U]; + __IM uint32_t EVENTMASKA; /*!< Offset: 0x080 (R/W) Event Mask A Register */ + __IM uint32_t EVENTMASK[15]; /*!< Offset: 0x084 (R/W) Event Mask Register */ +} EWIC_Type; + +/* EWIC External Wakeup Interrupt Controller (EVENTSPR) Register Definitions */ +#define EWIC_EVENTSPR_EDBGREQ_Pos 2U /*!< EWIC EVENTSPR: EDBGREQ Position */ +#define EWIC_EVENTSPR_EDBGREQ_Msk (0x1UL << EWIC_EVENTSPR_EDBGREQ_Pos) /*!< EWIC EVENTSPR: EDBGREQ Mask */ + +#define EWIC_EVENTSPR_NMI_Pos 1U /*!< EWIC EVENTSPR: NMI Position */ +#define EWIC_EVENTSPR_NMI_Msk (0x1UL << EWIC_EVENTSPR_NMI_Pos) /*!< EWIC EVENTSPR: NMI Mask */ + +#define EWIC_EVENTSPR_EVENT_Pos 0U /*!< EWIC EVENTSPR: EVENT Position */ +#define EWIC_EVENTSPR_EVENT_Msk (0x1UL /*<< EWIC_EVENTSPR_EVENT_Pos*/) /*!< EWIC EVENTSPR: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASKA) Register Definitions */ +#define EWIC_EVENTMASKA_EDBGREQ_Pos 2U /*!< EWIC EVENTMASKA: EDBGREQ Position */ +#define EWIC_EVENTMASKA_EDBGREQ_Msk (0x1UL << EWIC_EVENTMASKA_EDBGREQ_Pos) /*!< EWIC EVENTMASKA: EDBGREQ Mask */ + +#define EWIC_EVENTMASKA_NMI_Pos 1U /*!< EWIC EVENTMASKA: NMI Position */ +#define EWIC_EVENTMASKA_NMI_Msk (0x1UL << EWIC_EVENTMASKA_NMI_Pos) /*!< EWIC EVENTMASKA: NMI Mask */ + +#define EWIC_EVENTMASKA_EVENT_Pos 0U /*!< EWIC EVENTMASKA: EVENT Position */ +#define EWIC_EVENTMASKA_EVENT_Msk (0x1UL /*<< EWIC_EVENTMASKA_EVENT_Pos*/) /*!< EWIC EVENTMASKA: EVENT Mask */ + +/* EWIC External Wakeup Interrupt Controller (EVENTMASK) Register Definitions */ +#define EWIC_EVENTMASK_IRQ_Pos 0U /*!< EWIC EVENTMASKA: IRQ Position */ +#define EWIC_EVENTMASK_IRQ_Msk (0xFFFFFFFFUL /*<< EWIC_EVENTMASKA_IRQ_Pos*/) /*!< EWIC EVENTMASKA: IRQ Mask */ + +/*@}*/ /* end of group EWIC_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup ErrBnk_Type Error Banking Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Error Banking Registers (ERRBNK) + @{ + */ + +/** + \brief Structure type to access the Error Banking Registers (ERRBNK). + */ +typedef struct +{ + __IOM uint32_t IEBR0; /*!< Offset: 0x000 (R/W) Instruction Cache Error Bank Register 0 */ + __IOM uint32_t IEBR1; /*!< Offset: 0x004 (R/W) Instruction Cache Error Bank Register 1 */ + uint32_t RESERVED0[2U]; + __IOM uint32_t DEBR0; /*!< Offset: 0x010 (R/W) Data Cache Error Bank Register 0 */ + __IOM uint32_t DEBR1; /*!< Offset: 0x014 (R/W) Data Cache Error Bank Register 1 */ + uint32_t RESERVED1[2U]; + __IOM uint32_t TEBR0; /*!< Offset: 0x020 (R/W) TCM Error Bank Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t TEBR1; /*!< Offset: 0x028 (R/W) TCM Error Bank Register 1 */ +} ErrBnk_Type; + +/* ERRBNK Instruction Cache Error Bank Register 0 (IEBR0) Register Definitions */ +#define ERRBNK_IEBR0_SWDEF_Pos 30U /*!< ERRBNK IEBR0: SWDEF Position */ +#define ERRBNK_IEBR0_SWDEF_Msk (0x3UL << ERRBNK_IEBR0_SWDEF_Pos) /*!< ERRBNK IEBR0: SWDEF Mask */ + +#define ERRBNK_IEBR0_BANK_Pos 16U /*!< ERRBNK IEBR0: BANK Position */ +#define ERRBNK_IEBR0_BANK_Msk (0x1UL << ERRBNK_IEBR0_BANK_Pos) /*!< ERRBNK IEBR0: BANK Mask */ + +#define ERRBNK_IEBR0_LOCATION_Pos 2U /*!< ERRBNK IEBR0: LOCATION Position */ +#define ERRBNK_IEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR0_LOCATION_Pos) /*!< ERRBNK IEBR0: LOCATION Mask */ + +#define ERRBNK_IEBR0_LOCKED_Pos 1U /*!< ERRBNK IEBR0: LOCKED Position */ +#define ERRBNK_IEBR0_LOCKED_Msk (0x1UL << ERRBNK_IEBR0_LOCKED_Pos) /*!< ERRBNK IEBR0: LOCKED Mask */ + +#define ERRBNK_IEBR0_VALID_Pos 0U /*!< ERRBNK IEBR0: VALID Position */ +#define ERRBNK_IEBR0_VALID_Msk (0x1UL << /*ERRBNK_IEBR0_VALID_Pos*/) /*!< ERRBNK IEBR0: VALID Mask */ + +/* ERRBNK Instruction Cache Error Bank Register 1 (IEBR1) Register Definitions */ +#define ERRBNK_IEBR1_SWDEF_Pos 30U /*!< ERRBNK IEBR1: SWDEF Position */ +#define ERRBNK_IEBR1_SWDEF_Msk (0x3UL << ERRBNK_IEBR1_SWDEF_Pos) /*!< ERRBNK IEBR1: SWDEF Mask */ + +#define ERRBNK_IEBR1_BANK_Pos 16U /*!< ERRBNK IEBR1: BANK Position */ +#define ERRBNK_IEBR1_BANK_Msk (0x1UL << ERRBNK_IEBR1_BANK_Pos) /*!< ERRBNK IEBR1: BANK Mask */ + +#define ERRBNK_IEBR1_LOCATION_Pos 2U /*!< ERRBNK IEBR1: LOCATION Position */ +#define ERRBNK_IEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_IEBR1_LOCATION_Pos) /*!< ERRBNK IEBR1: LOCATION Mask */ + +#define ERRBNK_IEBR1_LOCKED_Pos 1U /*!< ERRBNK IEBR1: LOCKED Position */ +#define ERRBNK_IEBR1_LOCKED_Msk (0x1UL << ERRBNK_IEBR1_LOCKED_Pos) /*!< ERRBNK IEBR1: LOCKED Mask */ + +#define ERRBNK_IEBR1_VALID_Pos 0U /*!< ERRBNK IEBR1: VALID Position */ +#define ERRBNK_IEBR1_VALID_Msk (0x1UL << /*ERRBNK_IEBR1_VALID_Pos*/) /*!< ERRBNK IEBR1: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 0 (DEBR0) Register Definitions */ +#define ERRBNK_DEBR0_SWDEF_Pos 30U /*!< ERRBNK DEBR0: SWDEF Position */ +#define ERRBNK_DEBR0_SWDEF_Msk (0x3UL << ERRBNK_DEBR0_SWDEF_Pos) /*!< ERRBNK DEBR0: SWDEF Mask */ + +#define ERRBNK_DEBR0_TYPE_Pos 17U /*!< ERRBNK DEBR0: TYPE Position */ +#define ERRBNK_DEBR0_TYPE_Msk (0x1UL << ERRBNK_DEBR0_TYPE_Pos) /*!< ERRBNK DEBR0: TYPE Mask */ + +#define ERRBNK_DEBR0_BANK_Pos 16U /*!< ERRBNK DEBR0: BANK Position */ +#define ERRBNK_DEBR0_BANK_Msk (0x1UL << ERRBNK_DEBR0_BANK_Pos) /*!< ERRBNK DEBR0: BANK Mask */ + +#define ERRBNK_DEBR0_LOCATION_Pos 2U /*!< ERRBNK DEBR0: LOCATION Position */ +#define ERRBNK_DEBR0_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR0_LOCATION_Pos) /*!< ERRBNK DEBR0: LOCATION Mask */ + +#define ERRBNK_DEBR0_LOCKED_Pos 1U /*!< ERRBNK DEBR0: LOCKED Position */ +#define ERRBNK_DEBR0_LOCKED_Msk (0x1UL << ERRBNK_DEBR0_LOCKED_Pos) /*!< ERRBNK DEBR0: LOCKED Mask */ + +#define ERRBNK_DEBR0_VALID_Pos 0U /*!< ERRBNK DEBR0: VALID Position */ +#define ERRBNK_DEBR0_VALID_Msk (0x1UL << /*ERRBNK_DEBR0_VALID_Pos*/) /*!< ERRBNK DEBR0: VALID Mask */ + +/* ERRBNK Data Cache Error Bank Register 1 (DEBR1) Register Definitions */ +#define ERRBNK_DEBR1_SWDEF_Pos 30U /*!< ERRBNK DEBR1: SWDEF Position */ +#define ERRBNK_DEBR1_SWDEF_Msk (0x3UL << ERRBNK_DEBR1_SWDEF_Pos) /*!< ERRBNK DEBR1: SWDEF Mask */ + +#define ERRBNK_DEBR1_TYPE_Pos 17U /*!< ERRBNK DEBR1: TYPE Position */ +#define ERRBNK_DEBR1_TYPE_Msk (0x1UL << ERRBNK_DEBR1_TYPE_Pos) /*!< ERRBNK DEBR1: TYPE Mask */ + +#define ERRBNK_DEBR1_BANK_Pos 16U /*!< ERRBNK DEBR1: BANK Position */ +#define ERRBNK_DEBR1_BANK_Msk (0x1UL << ERRBNK_DEBR1_BANK_Pos) /*!< ERRBNK DEBR1: BANK Mask */ + +#define ERRBNK_DEBR1_LOCATION_Pos 2U /*!< ERRBNK DEBR1: LOCATION Position */ +#define ERRBNK_DEBR1_LOCATION_Msk (0x3FFFUL << ERRBNK_DEBR1_LOCATION_Pos) /*!< ERRBNK DEBR1: LOCATION Mask */ + +#define ERRBNK_DEBR1_LOCKED_Pos 1U /*!< ERRBNK DEBR1: LOCKED Position */ +#define ERRBNK_DEBR1_LOCKED_Msk (0x1UL << ERRBNK_DEBR1_LOCKED_Pos) /*!< ERRBNK DEBR1: LOCKED Mask */ + +#define ERRBNK_DEBR1_VALID_Pos 0U /*!< ERRBNK DEBR1: VALID Position */ +#define ERRBNK_DEBR1_VALID_Msk (0x1UL << /*ERRBNK_DEBR1_VALID_Pos*/) /*!< ERRBNK DEBR1: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 0 (TEBR0) Register Definitions */ +#define ERRBNK_TEBR0_SWDEF_Pos 30U /*!< ERRBNK TEBR0: SWDEF Position */ +#define ERRBNK_TEBR0_SWDEF_Msk (0x3UL << ERRBNK_TEBR0_SWDEF_Pos) /*!< ERRBNK TEBR0: SWDEF Mask */ + +#define ERRBNK_TEBR0_POISON_Pos 28U /*!< ERRBNK TEBR0: POISON Position */ +#define ERRBNK_TEBR0_POISON_Msk (0x1UL << ERRBNK_TEBR0_POISON_Pos) /*!< ERRBNK TEBR0: POISON Mask */ + +#define ERRBNK_TEBR0_TYPE_Pos 27U /*!< ERRBNK TEBR0: TYPE Position */ +#define ERRBNK_TEBR0_TYPE_Msk (0x1UL << ERRBNK_TEBR0_TYPE_Pos) /*!< ERRBNK TEBR0: TYPE Mask */ + +#define ERRBNK_TEBR0_BANK_Pos 24U /*!< ERRBNK TEBR0: BANK Position */ +#define ERRBNK_TEBR0_BANK_Msk (0x3UL << ERRBNK_TEBR0_BANK_Pos) /*!< ERRBNK TEBR0: BANK Mask */ + +#define ERRBNK_TEBR0_LOCATION_Pos 2U /*!< ERRBNK TEBR0: LOCATION Position */ +#define ERRBNK_TEBR0_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR0_LOCATION_Pos) /*!< ERRBNK TEBR0: LOCATION Mask */ + +#define ERRBNK_TEBR0_LOCKED_Pos 1U /*!< ERRBNK TEBR0: LOCKED Position */ +#define ERRBNK_TEBR0_LOCKED_Msk (0x1UL << ERRBNK_TEBR0_LOCKED_Pos) /*!< ERRBNK TEBR0: LOCKED Mask */ + +#define ERRBNK_TEBR0_VALID_Pos 0U /*!< ERRBNK TEBR0: VALID Position */ +#define ERRBNK_TEBR0_VALID_Msk (0x1UL << /*ERRBNK_TEBR0_VALID_Pos*/) /*!< ERRBNK TEBR0: VALID Mask */ + +/* ERRBNK TCM Error Bank Register 1 (TEBR1) Register Definitions */ +#define ERRBNK_TEBR1_SWDEF_Pos 30U /*!< ERRBNK TEBR1: SWDEF Position */ +#define ERRBNK_TEBR1_SWDEF_Msk (0x3UL << ERRBNK_TEBR1_SWDEF_Pos) /*!< ERRBNK TEBR1: SWDEF Mask */ + +#define ERRBNK_TEBR1_POISON_Pos 28U /*!< ERRBNK TEBR1: POISON Position */ +#define ERRBNK_TEBR1_POISON_Msk (0x1UL << ERRBNK_TEBR1_POISON_Pos) /*!< ERRBNK TEBR1: POISON Mask */ + +#define ERRBNK_TEBR1_TYPE_Pos 27U /*!< ERRBNK TEBR1: TYPE Position */ +#define ERRBNK_TEBR1_TYPE_Msk (0x1UL << ERRBNK_TEBR1_TYPE_Pos) /*!< ERRBNK TEBR1: TYPE Mask */ + +#define ERRBNK_TEBR1_BANK_Pos 24U /*!< ERRBNK TEBR1: BANK Position */ +#define ERRBNK_TEBR1_BANK_Msk (0x3UL << ERRBNK_TEBR1_BANK_Pos) /*!< ERRBNK TEBR1: BANK Mask */ + +#define ERRBNK_TEBR1_LOCATION_Pos 2U /*!< ERRBNK TEBR1: LOCATION Position */ +#define ERRBNK_TEBR1_LOCATION_Msk (0x3FFFFFUL << ERRBNK_TEBR1_LOCATION_Pos) /*!< ERRBNK TEBR1: LOCATION Mask */ + +#define ERRBNK_TEBR1_LOCKED_Pos 1U /*!< ERRBNK TEBR1: LOCKED Position */ +#define ERRBNK_TEBR1_LOCKED_Msk (0x1UL << ERRBNK_TEBR1_LOCKED_Pos) /*!< ERRBNK TEBR1: LOCKED Mask */ + +#define ERRBNK_TEBR1_VALID_Pos 0U /*!< ERRBNK TEBR1: VALID Position */ +#define ERRBNK_TEBR1_VALID_Msk (0x1UL << /*ERRBNK_TEBR1_VALID_Pos*/) /*!< ERRBNK TEBR1: VALID Mask */ + +/*@}*/ /* end of group ErrBnk_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup PrcCfgInf_Type Processor Configuration Information Registers (IMPLEMENTATION DEFINED) + \brief Type definitions for the Processor Configuration Information Registerss (PRCCFGINF) + @{ + */ + +/** + \brief Structure type to access the Processor Configuration Information Registerss (PRCCFGINF). + */ +typedef struct +{ + __OM uint32_t CFGINFOSEL; /*!< Offset: 0x000 ( /W) Processor Configuration Information Selection Register */ + __IM uint32_t CFGINFORD; /*!< Offset: 0x004 (R/ ) Processor Configuration Information Read Data Register */ +} PrcCfgInf_Type; + +/* PRCCFGINF Processor Configuration Information Selection Register (CFGINFOSEL) Definitions */ + +/* PRCCFGINF Processor Configuration Information Read Data Register (CFGINFORD) Definitions */ + +/*@}*/ /* end of group PrcCfgInf_Type */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFmt_Pos 0U /*!< TPI FFCR: EnFmt Position */ +#define TPI_FFCR_EnFmt_Msk (0x3UL << /*TPI_FFCR_EnFmt_Pos*/) /*!< TPI FFCR: EnFmt Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_PMU Performance Monitoring Unit (PMU) + \brief Type definitions for the Performance Monitoring Unit (PMU) + @{ + */ + +/** + \brief Structure type to access the Performance Monitoring Unit (PMU). + */ +typedef struct +{ + __IOM uint32_t EVCNTR[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x0 (R/W) PMU Event Counter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED0[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCNTR; /*!< Offset: 0x7C (R/W) PMU Cycle Counter Register */ + uint32_t RESERVED1[224]; + __IOM uint32_t EVTYPER[__PMU_NUM_EVENTCNT]; /*!< Offset: 0x400 (R/W) PMU Event Type and Filter Registers */ +#if __PMU_NUM_EVENTCNT<31 + uint32_t RESERVED2[31U-__PMU_NUM_EVENTCNT]; +#endif + __IOM uint32_t CCFILTR; /*!< Offset: 0x47C (R/W) PMU Cycle Counter Filter Register */ + uint32_t RESERVED3[480]; + __IOM uint32_t CNTENSET; /*!< Offset: 0xC00 (R/W) PMU Count Enable Set Register */ + uint32_t RESERVED4[7]; + __IOM uint32_t CNTENCLR; /*!< Offset: 0xC20 (R/W) PMU Count Enable Clear Register */ + uint32_t RESERVED5[7]; + __IOM uint32_t INTENSET; /*!< Offset: 0xC40 (R/W) PMU Interrupt Enable Set Register */ + uint32_t RESERVED6[7]; + __IOM uint32_t INTENCLR; /*!< Offset: 0xC60 (R/W) PMU Interrupt Enable Clear Register */ + uint32_t RESERVED7[7]; + __IOM uint32_t OVSCLR; /*!< Offset: 0xC80 (R/W) PMU Overflow Flag Status Clear Register */ + uint32_t RESERVED8[7]; + __IOM uint32_t SWINC; /*!< Offset: 0xCA0 (R/W) PMU Software Increment Register */ + uint32_t RESERVED9[7]; + __IOM uint32_t OVSSET; /*!< Offset: 0xCC0 (R/W) PMU Overflow Flag Status Set Register */ + uint32_t RESERVED10[79]; + __IOM uint32_t TYPE; /*!< Offset: 0xE00 (R/W) PMU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0xE04 (R/W) PMU Control Register */ + uint32_t RESERVED11[108]; + __IOM uint32_t AUTHSTATUS; /*!< Offset: 0xFB8 (R/W) PMU Authentication Status Register */ + __IOM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/W) PMU Device Architecture Register */ + uint32_t RESERVED12[3]; + __IOM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/W) PMU Device Type Register */ + __IOM uint32_t PIDR4; /*!< Offset: 0xFD0 (R/W) PMU Peripheral Identification Register 4 */ + uint32_t RESERVED13[3]; + __IOM uint32_t PIDR0; /*!< Offset: 0xFE0 (R/W) PMU Peripheral Identification Register 0 */ + __IOM uint32_t PIDR1; /*!< Offset: 0xFE4 (R/W) PMU Peripheral Identification Register 1 */ + __IOM uint32_t PIDR2; /*!< Offset: 0xFE8 (R/W) PMU Peripheral Identification Register 2 */ + __IOM uint32_t PIDR3; /*!< Offset: 0xFEC (R/W) PMU Peripheral Identification Register 3 */ + __IOM uint32_t CIDR0; /*!< Offset: 0xFF0 (R/W) PMU Component Identification Register 0 */ + __IOM uint32_t CIDR1; /*!< Offset: 0xFF4 (R/W) PMU Component Identification Register 1 */ + __IOM uint32_t CIDR2; /*!< Offset: 0xFF8 (R/W) PMU Component Identification Register 2 */ + __IOM uint32_t CIDR3; /*!< Offset: 0xFFC (R/W) PMU Component Identification Register 3 */ +} PMU_Type; + +/** \brief PMU Event Counter Registers (0-30) Definitions */ + +#define PMU_EVCNTR_CNT_Pos 0U /*!< PMU EVCNTR: Counter Position */ +#define PMU_EVCNTR_CNT_Msk (0xFFFFUL /*<< PMU_EVCNTRx_CNT_Pos*/) /*!< PMU EVCNTR: Counter Mask */ + +/** \brief PMU Event Type and Filter Registers (0-30) Definitions */ + +#define PMU_EVTYPER_EVENTTOCNT_Pos 0U /*!< PMU EVTYPER: Event to Count Position */ +#define PMU_EVTYPER_EVENTTOCNT_Msk (0xFFFFUL /*<< EVTYPERx_EVENTTOCNT_Pos*/) /*!< PMU EVTYPER: Event to Count Mask */ + +/** \brief PMU Count Enable Set Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENSET: Event Counter 0 Enable Set Position */ +#define PMU_CNTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENSET_CNT0_ENABLE_Pos*/) /*!< PMU CNTENSET: Event Counter 0 Enable Set Mask */ + +#define PMU_CNTENSET_CNT1_ENABLE_Pos 1U /*!< PMU CNTENSET: Event Counter 1 Enable Set Position */ +#define PMU_CNTENSET_CNT1_ENABLE_Msk (1UL << PMU_CNTENSET_CNT1_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 1 Enable Set Mask */ + +#define PMU_CNTENSET_CNT2_ENABLE_Pos 2U /*!< PMU CNTENSET: Event Counter 2 Enable Set Position */ +#define PMU_CNTENSET_CNT2_ENABLE_Msk (1UL << PMU_CNTENSET_CNT2_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 2 Enable Set Mask */ + +#define PMU_CNTENSET_CNT3_ENABLE_Pos 3U /*!< PMU CNTENSET: Event Counter 3 Enable Set Position */ +#define PMU_CNTENSET_CNT3_ENABLE_Msk (1UL << PMU_CNTENSET_CNT3_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 3 Enable Set Mask */ + +#define PMU_CNTENSET_CNT4_ENABLE_Pos 4U /*!< PMU CNTENSET: Event Counter 4 Enable Set Position */ +#define PMU_CNTENSET_CNT4_ENABLE_Msk (1UL << PMU_CNTENSET_CNT4_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 4 Enable Set Mask */ + +#define PMU_CNTENSET_CNT5_ENABLE_Pos 5U /*!< PMU CNTENSET: Event Counter 5 Enable Set Position */ +#define PMU_CNTENSET_CNT5_ENABLE_Msk (1UL << PMU_CNTENSET_CNT5_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 5 Enable Set Mask */ + +#define PMU_CNTENSET_CNT6_ENABLE_Pos 6U /*!< PMU CNTENSET: Event Counter 6 Enable Set Position */ +#define PMU_CNTENSET_CNT6_ENABLE_Msk (1UL << PMU_CNTENSET_CNT6_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 6 Enable Set Mask */ + +#define PMU_CNTENSET_CNT7_ENABLE_Pos 7U /*!< PMU CNTENSET: Event Counter 7 Enable Set Position */ +#define PMU_CNTENSET_CNT7_ENABLE_Msk (1UL << PMU_CNTENSET_CNT7_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 7 Enable Set Mask */ + +#define PMU_CNTENSET_CNT8_ENABLE_Pos 8U /*!< PMU CNTENSET: Event Counter 8 Enable Set Position */ +#define PMU_CNTENSET_CNT8_ENABLE_Msk (1UL << PMU_CNTENSET_CNT8_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 8 Enable Set Mask */ + +#define PMU_CNTENSET_CNT9_ENABLE_Pos 9U /*!< PMU CNTENSET: Event Counter 9 Enable Set Position */ +#define PMU_CNTENSET_CNT9_ENABLE_Msk (1UL << PMU_CNTENSET_CNT9_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 9 Enable Set Mask */ + +#define PMU_CNTENSET_CNT10_ENABLE_Pos 10U /*!< PMU CNTENSET: Event Counter 10 Enable Set Position */ +#define PMU_CNTENSET_CNT10_ENABLE_Msk (1UL << PMU_CNTENSET_CNT10_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 10 Enable Set Mask */ + +#define PMU_CNTENSET_CNT11_ENABLE_Pos 11U /*!< PMU CNTENSET: Event Counter 11 Enable Set Position */ +#define PMU_CNTENSET_CNT11_ENABLE_Msk (1UL << PMU_CNTENSET_CNT11_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 11 Enable Set Mask */ + +#define PMU_CNTENSET_CNT12_ENABLE_Pos 12U /*!< PMU CNTENSET: Event Counter 12 Enable Set Position */ +#define PMU_CNTENSET_CNT12_ENABLE_Msk (1UL << PMU_CNTENSET_CNT12_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 12 Enable Set Mask */ + +#define PMU_CNTENSET_CNT13_ENABLE_Pos 13U /*!< PMU CNTENSET: Event Counter 13 Enable Set Position */ +#define PMU_CNTENSET_CNT13_ENABLE_Msk (1UL << PMU_CNTENSET_CNT13_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 13 Enable Set Mask */ + +#define PMU_CNTENSET_CNT14_ENABLE_Pos 14U /*!< PMU CNTENSET: Event Counter 14 Enable Set Position */ +#define PMU_CNTENSET_CNT14_ENABLE_Msk (1UL << PMU_CNTENSET_CNT14_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 14 Enable Set Mask */ + +#define PMU_CNTENSET_CNT15_ENABLE_Pos 15U /*!< PMU CNTENSET: Event Counter 15 Enable Set Position */ +#define PMU_CNTENSET_CNT15_ENABLE_Msk (1UL << PMU_CNTENSET_CNT15_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 15 Enable Set Mask */ + +#define PMU_CNTENSET_CNT16_ENABLE_Pos 16U /*!< PMU CNTENSET: Event Counter 16 Enable Set Position */ +#define PMU_CNTENSET_CNT16_ENABLE_Msk (1UL << PMU_CNTENSET_CNT16_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 16 Enable Set Mask */ + +#define PMU_CNTENSET_CNT17_ENABLE_Pos 17U /*!< PMU CNTENSET: Event Counter 17 Enable Set Position */ +#define PMU_CNTENSET_CNT17_ENABLE_Msk (1UL << PMU_CNTENSET_CNT17_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 17 Enable Set Mask */ + +#define PMU_CNTENSET_CNT18_ENABLE_Pos 18U /*!< PMU CNTENSET: Event Counter 18 Enable Set Position */ +#define PMU_CNTENSET_CNT18_ENABLE_Msk (1UL << PMU_CNTENSET_CNT18_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 18 Enable Set Mask */ + +#define PMU_CNTENSET_CNT19_ENABLE_Pos 19U /*!< PMU CNTENSET: Event Counter 19 Enable Set Position */ +#define PMU_CNTENSET_CNT19_ENABLE_Msk (1UL << PMU_CNTENSET_CNT19_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 19 Enable Set Mask */ + +#define PMU_CNTENSET_CNT20_ENABLE_Pos 20U /*!< PMU CNTENSET: Event Counter 20 Enable Set Position */ +#define PMU_CNTENSET_CNT20_ENABLE_Msk (1UL << PMU_CNTENSET_CNT20_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 20 Enable Set Mask */ + +#define PMU_CNTENSET_CNT21_ENABLE_Pos 21U /*!< PMU CNTENSET: Event Counter 21 Enable Set Position */ +#define PMU_CNTENSET_CNT21_ENABLE_Msk (1UL << PMU_CNTENSET_CNT21_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 21 Enable Set Mask */ + +#define PMU_CNTENSET_CNT22_ENABLE_Pos 22U /*!< PMU CNTENSET: Event Counter 22 Enable Set Position */ +#define PMU_CNTENSET_CNT22_ENABLE_Msk (1UL << PMU_CNTENSET_CNT22_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 22 Enable Set Mask */ + +#define PMU_CNTENSET_CNT23_ENABLE_Pos 23U /*!< PMU CNTENSET: Event Counter 23 Enable Set Position */ +#define PMU_CNTENSET_CNT23_ENABLE_Msk (1UL << PMU_CNTENSET_CNT23_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 23 Enable Set Mask */ + +#define PMU_CNTENSET_CNT24_ENABLE_Pos 24U /*!< PMU CNTENSET: Event Counter 24 Enable Set Position */ +#define PMU_CNTENSET_CNT24_ENABLE_Msk (1UL << PMU_CNTENSET_CNT24_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 24 Enable Set Mask */ + +#define PMU_CNTENSET_CNT25_ENABLE_Pos 25U /*!< PMU CNTENSET: Event Counter 25 Enable Set Position */ +#define PMU_CNTENSET_CNT25_ENABLE_Msk (1UL << PMU_CNTENSET_CNT25_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 25 Enable Set Mask */ + +#define PMU_CNTENSET_CNT26_ENABLE_Pos 26U /*!< PMU CNTENSET: Event Counter 26 Enable Set Position */ +#define PMU_CNTENSET_CNT26_ENABLE_Msk (1UL << PMU_CNTENSET_CNT26_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 26 Enable Set Mask */ + +#define PMU_CNTENSET_CNT27_ENABLE_Pos 27U /*!< PMU CNTENSET: Event Counter 27 Enable Set Position */ +#define PMU_CNTENSET_CNT27_ENABLE_Msk (1UL << PMU_CNTENSET_CNT27_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 27 Enable Set Mask */ + +#define PMU_CNTENSET_CNT28_ENABLE_Pos 28U /*!< PMU CNTENSET: Event Counter 28 Enable Set Position */ +#define PMU_CNTENSET_CNT28_ENABLE_Msk (1UL << PMU_CNTENSET_CNT28_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 28 Enable Set Mask */ + +#define PMU_CNTENSET_CNT29_ENABLE_Pos 29U /*!< PMU CNTENSET: Event Counter 29 Enable Set Position */ +#define PMU_CNTENSET_CNT29_ENABLE_Msk (1UL << PMU_CNTENSET_CNT29_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 29 Enable Set Mask */ + +#define PMU_CNTENSET_CNT30_ENABLE_Pos 30U /*!< PMU CNTENSET: Event Counter 30 Enable Set Position */ +#define PMU_CNTENSET_CNT30_ENABLE_Msk (1UL << PMU_CNTENSET_CNT30_ENABLE_Pos) /*!< PMU CNTENSET: Event Counter 30 Enable Set Mask */ + +#define PMU_CNTENSET_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENSET: Cycle Counter Enable Set Position */ +#define PMU_CNTENSET_CCNTR_ENABLE_Msk (1UL << PMU_CNTENSET_CCNTR_ENABLE_Pos) /*!< PMU CNTENSET: Cycle Counter Enable Set Mask */ + +/** \brief PMU Count Enable Clear Register Definitions */ + +#define PMU_CNTENSET_CNT0_ENABLE_Pos 0U /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Position */ +#define PMU_CNTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_CNTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU CNTENCLR: Event Counter 0 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU CNTENCLR: Event Counter 1 Enable Clear Position */ +#define PMU_CNTENCLR_CNT1_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT1_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 1 Enable Clear */ + +#define PMU_CNTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Position */ +#define PMU_CNTENCLR_CNT2_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT2_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 2 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Position */ +#define PMU_CNTENCLR_CNT3_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT3_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 3 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Position */ +#define PMU_CNTENCLR_CNT4_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT4_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 4 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Position */ +#define PMU_CNTENCLR_CNT5_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT5_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 5 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Position */ +#define PMU_CNTENCLR_CNT6_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT6_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 6 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Position */ +#define PMU_CNTENCLR_CNT7_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT7_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 7 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Position */ +#define PMU_CNTENCLR_CNT8_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT8_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 8 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Position */ +#define PMU_CNTENCLR_CNT9_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT9_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 9 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Position */ +#define PMU_CNTENCLR_CNT10_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT10_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 10 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Position */ +#define PMU_CNTENCLR_CNT11_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT11_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 11 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Position */ +#define PMU_CNTENCLR_CNT12_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT12_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 12 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Position */ +#define PMU_CNTENCLR_CNT13_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT13_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 13 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Position */ +#define PMU_CNTENCLR_CNT14_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT14_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 14 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Position */ +#define PMU_CNTENCLR_CNT15_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT15_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 15 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Position */ +#define PMU_CNTENCLR_CNT16_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT16_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 16 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Position */ +#define PMU_CNTENCLR_CNT17_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT17_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 17 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Position */ +#define PMU_CNTENCLR_CNT18_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT18_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 18 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Position */ +#define PMU_CNTENCLR_CNT19_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT19_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 19 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Position */ +#define PMU_CNTENCLR_CNT20_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT20_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 20 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Position */ +#define PMU_CNTENCLR_CNT21_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT21_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 21 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Position */ +#define PMU_CNTENCLR_CNT22_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT22_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 22 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Position */ +#define PMU_CNTENCLR_CNT23_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT23_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 23 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Position */ +#define PMU_CNTENCLR_CNT24_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT24_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 24 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Position */ +#define PMU_CNTENCLR_CNT25_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT25_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 25 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Position */ +#define PMU_CNTENCLR_CNT26_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT26_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 26 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Position */ +#define PMU_CNTENCLR_CNT27_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT27_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 27 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Position */ +#define PMU_CNTENCLR_CNT28_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT28_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 28 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Position */ +#define PMU_CNTENCLR_CNT29_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT29_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 29 Enable Clear Mask */ + +#define PMU_CNTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Position */ +#define PMU_CNTENCLR_CNT30_ENABLE_Msk (1UL << PMU_CNTENCLR_CNT30_ENABLE_Pos) /*!< PMU CNTENCLR: Event Counter 30 Enable Clear Mask */ + +#define PMU_CNTENCLR_CCNTR_ENABLE_Pos 31U /*!< PMU CNTENCLR: Cycle Counter Enable Clear Position */ +#define PMU_CNTENCLR_CCNTR_ENABLE_Msk (1UL << PMU_CNTENCLR_CCNTR_ENABLE_Pos) /*!< PMU CNTENCLR: Cycle Counter Enable Clear Mask */ + +/** \brief PMU Interrupt Enable Set Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENSET_CNT0_ENABLE_Pos*/) /*!< PMU INTENSET: Event Counter 0 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT1_ENABLE_Pos 1U /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT1_ENABLE_Msk (1UL << PMU_INTENSET_CNT1_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 1 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT2_ENABLE_Pos 2U /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT2_ENABLE_Msk (1UL << PMU_INTENSET_CNT2_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 2 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT3_ENABLE_Pos 3U /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT3_ENABLE_Msk (1UL << PMU_INTENSET_CNT3_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 3 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT4_ENABLE_Pos 4U /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT4_ENABLE_Msk (1UL << PMU_INTENSET_CNT4_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 4 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT5_ENABLE_Pos 5U /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT5_ENABLE_Msk (1UL << PMU_INTENSET_CNT5_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 5 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT6_ENABLE_Pos 6U /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT6_ENABLE_Msk (1UL << PMU_INTENSET_CNT6_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 6 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT7_ENABLE_Pos 7U /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT7_ENABLE_Msk (1UL << PMU_INTENSET_CNT7_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 7 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT8_ENABLE_Pos 8U /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT8_ENABLE_Msk (1UL << PMU_INTENSET_CNT8_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 8 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT9_ENABLE_Pos 9U /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT9_ENABLE_Msk (1UL << PMU_INTENSET_CNT9_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 9 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT10_ENABLE_Pos 10U /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT10_ENABLE_Msk (1UL << PMU_INTENSET_CNT10_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 10 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT11_ENABLE_Pos 11U /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT11_ENABLE_Msk (1UL << PMU_INTENSET_CNT11_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 11 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT12_ENABLE_Pos 12U /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT12_ENABLE_Msk (1UL << PMU_INTENSET_CNT12_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 12 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT13_ENABLE_Pos 13U /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT13_ENABLE_Msk (1UL << PMU_INTENSET_CNT13_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 13 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT14_ENABLE_Pos 14U /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT14_ENABLE_Msk (1UL << PMU_INTENSET_CNT14_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 14 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT15_ENABLE_Pos 15U /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT15_ENABLE_Msk (1UL << PMU_INTENSET_CNT15_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 15 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT16_ENABLE_Pos 16U /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT16_ENABLE_Msk (1UL << PMU_INTENSET_CNT16_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 16 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT17_ENABLE_Pos 17U /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT17_ENABLE_Msk (1UL << PMU_INTENSET_CNT17_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 17 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT18_ENABLE_Pos 18U /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT18_ENABLE_Msk (1UL << PMU_INTENSET_CNT18_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 18 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT19_ENABLE_Pos 19U /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT19_ENABLE_Msk (1UL << PMU_INTENSET_CNT19_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 19 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT20_ENABLE_Pos 20U /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT20_ENABLE_Msk (1UL << PMU_INTENSET_CNT20_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 20 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT21_ENABLE_Pos 21U /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT21_ENABLE_Msk (1UL << PMU_INTENSET_CNT21_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 21 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT22_ENABLE_Pos 22U /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT22_ENABLE_Msk (1UL << PMU_INTENSET_CNT22_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 22 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT23_ENABLE_Pos 23U /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT23_ENABLE_Msk (1UL << PMU_INTENSET_CNT23_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 23 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT24_ENABLE_Pos 24U /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT24_ENABLE_Msk (1UL << PMU_INTENSET_CNT24_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 24 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT25_ENABLE_Pos 25U /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT25_ENABLE_Msk (1UL << PMU_INTENSET_CNT25_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 25 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT26_ENABLE_Pos 26U /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT26_ENABLE_Msk (1UL << PMU_INTENSET_CNT26_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 26 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT27_ENABLE_Pos 27U /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT27_ENABLE_Msk (1UL << PMU_INTENSET_CNT27_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 27 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT28_ENABLE_Pos 28U /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT28_ENABLE_Msk (1UL << PMU_INTENSET_CNT28_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 28 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT29_ENABLE_Pos 29U /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT29_ENABLE_Msk (1UL << PMU_INTENSET_CNT29_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 29 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CNT30_ENABLE_Pos 30U /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Position */ +#define PMU_INTENSET_CNT30_ENABLE_Msk (1UL << PMU_INTENSET_CNT30_ENABLE_Pos) /*!< PMU INTENSET: Event Counter 30 Interrupt Enable Set Mask */ + +#define PMU_INTENSET_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Position */ +#define PMU_INTENSET_CCYCNT_ENABLE_Msk (1UL << PMU_INTENSET_CYCCNT_ENABLE_Pos) /*!< PMU INTENSET: Cycle Counter Interrupt Enable Set Mask */ + +/** \brief PMU Interrupt Enable Clear Register Definitions */ + +#define PMU_INTENSET_CNT0_ENABLE_Pos 0U /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT0_ENABLE_Msk (1UL /*<< PMU_INTENCLR_CNT0_ENABLE_Pos*/) /*!< PMU INTENCLR: Event Counter 0 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT1_ENABLE_Pos 1U /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT1_ENABLE_Msk (1UL << PMU_INTENCLR_CNT1_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 1 Interrupt Enable Clear */ + +#define PMU_INTENCLR_CNT2_ENABLE_Pos 2U /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT2_ENABLE_Msk (1UL << PMU_INTENCLR_CNT2_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 2 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT3_ENABLE_Pos 3U /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT3_ENABLE_Msk (1UL << PMU_INTENCLR_CNT3_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 3 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT4_ENABLE_Pos 4U /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT4_ENABLE_Msk (1UL << PMU_INTENCLR_CNT4_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 4 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT5_ENABLE_Pos 5U /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT5_ENABLE_Msk (1UL << PMU_INTENCLR_CNT5_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 5 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT6_ENABLE_Pos 6U /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT6_ENABLE_Msk (1UL << PMU_INTENCLR_CNT6_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 6 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT7_ENABLE_Pos 7U /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT7_ENABLE_Msk (1UL << PMU_INTENCLR_CNT7_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 7 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT8_ENABLE_Pos 8U /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT8_ENABLE_Msk (1UL << PMU_INTENCLR_CNT8_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 8 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT9_ENABLE_Pos 9U /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT9_ENABLE_Msk (1UL << PMU_INTENCLR_CNT9_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 9 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT10_ENABLE_Pos 10U /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT10_ENABLE_Msk (1UL << PMU_INTENCLR_CNT10_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 10 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT11_ENABLE_Pos 11U /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT11_ENABLE_Msk (1UL << PMU_INTENCLR_CNT11_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 11 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT12_ENABLE_Pos 12U /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT12_ENABLE_Msk (1UL << PMU_INTENCLR_CNT12_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 12 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT13_ENABLE_Pos 13U /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT13_ENABLE_Msk (1UL << PMU_INTENCLR_CNT13_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 13 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT14_ENABLE_Pos 14U /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT14_ENABLE_Msk (1UL << PMU_INTENCLR_CNT14_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 14 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT15_ENABLE_Pos 15U /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT15_ENABLE_Msk (1UL << PMU_INTENCLR_CNT15_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 15 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT16_ENABLE_Pos 16U /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT16_ENABLE_Msk (1UL << PMU_INTENCLR_CNT16_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 16 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT17_ENABLE_Pos 17U /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT17_ENABLE_Msk (1UL << PMU_INTENCLR_CNT17_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 17 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT18_ENABLE_Pos 18U /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT18_ENABLE_Msk (1UL << PMU_INTENCLR_CNT18_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 18 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT19_ENABLE_Pos 19U /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT19_ENABLE_Msk (1UL << PMU_INTENCLR_CNT19_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 19 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT20_ENABLE_Pos 20U /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT20_ENABLE_Msk (1UL << PMU_INTENCLR_CNT20_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 20 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT21_ENABLE_Pos 21U /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT21_ENABLE_Msk (1UL << PMU_INTENCLR_CNT21_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 21 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT22_ENABLE_Pos 22U /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT22_ENABLE_Msk (1UL << PMU_INTENCLR_CNT22_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 22 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT23_ENABLE_Pos 23U /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT23_ENABLE_Msk (1UL << PMU_INTENCLR_CNT23_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 23 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT24_ENABLE_Pos 24U /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT24_ENABLE_Msk (1UL << PMU_INTENCLR_CNT24_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 24 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT25_ENABLE_Pos 25U /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT25_ENABLE_Msk (1UL << PMU_INTENCLR_CNT25_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 25 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT26_ENABLE_Pos 26U /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT26_ENABLE_Msk (1UL << PMU_INTENCLR_CNT26_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 26 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT27_ENABLE_Pos 27U /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT27_ENABLE_Msk (1UL << PMU_INTENCLR_CNT27_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 27 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT28_ENABLE_Pos 28U /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT28_ENABLE_Msk (1UL << PMU_INTENCLR_CNT28_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 28 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT29_ENABLE_Pos 29U /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT29_ENABLE_Msk (1UL << PMU_INTENCLR_CNT29_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 29 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CNT30_ENABLE_Pos 30U /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CNT30_ENABLE_Msk (1UL << PMU_INTENCLR_CNT30_ENABLE_Pos) /*!< PMU INTENCLR: Event Counter 30 Interrupt Enable Clear Mask */ + +#define PMU_INTENCLR_CYCCNT_ENABLE_Pos 31U /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Position */ +#define PMU_INTENCLR_CYCCNT_ENABLE_Msk (1UL << PMU_INTENCLR_CYCCNT_ENABLE_Pos) /*!< PMU INTENCLR: Cycle Counter Interrupt Enable Clear Mask */ + +/** \brief PMU Overflow Flag Status Set Register Definitions */ + +#define PMU_OVSSET_CNT0_STATUS_Pos 0U /*!< PMU OVSSET: Event Counter 0 Overflow Set Position */ +#define PMU_OVSSET_CNT0_STATUS_Msk (1UL /*<< PMU_OVSSET_CNT0_STATUS_Pos*/) /*!< PMU OVSSET: Event Counter 0 Overflow Set Mask */ + +#define PMU_OVSSET_CNT1_STATUS_Pos 1U /*!< PMU OVSSET: Event Counter 1 Overflow Set Position */ +#define PMU_OVSSET_CNT1_STATUS_Msk (1UL << PMU_OVSSET_CNT1_STATUS_Pos) /*!< PMU OVSSET: Event Counter 1 Overflow Set Mask */ + +#define PMU_OVSSET_CNT2_STATUS_Pos 2U /*!< PMU OVSSET: Event Counter 2 Overflow Set Position */ +#define PMU_OVSSET_CNT2_STATUS_Msk (1UL << PMU_OVSSET_CNT2_STATUS_Pos) /*!< PMU OVSSET: Event Counter 2 Overflow Set Mask */ + +#define PMU_OVSSET_CNT3_STATUS_Pos 3U /*!< PMU OVSSET: Event Counter 3 Overflow Set Position */ +#define PMU_OVSSET_CNT3_STATUS_Msk (1UL << PMU_OVSSET_CNT3_STATUS_Pos) /*!< PMU OVSSET: Event Counter 3 Overflow Set Mask */ + +#define PMU_OVSSET_CNT4_STATUS_Pos 4U /*!< PMU OVSSET: Event Counter 4 Overflow Set Position */ +#define PMU_OVSSET_CNT4_STATUS_Msk (1UL << PMU_OVSSET_CNT4_STATUS_Pos) /*!< PMU OVSSET: Event Counter 4 Overflow Set Mask */ + +#define PMU_OVSSET_CNT5_STATUS_Pos 5U /*!< PMU OVSSET: Event Counter 5 Overflow Set Position */ +#define PMU_OVSSET_CNT5_STATUS_Msk (1UL << PMU_OVSSET_CNT5_STATUS_Pos) /*!< PMU OVSSET: Event Counter 5 Overflow Set Mask */ + +#define PMU_OVSSET_CNT6_STATUS_Pos 6U /*!< PMU OVSSET: Event Counter 6 Overflow Set Position */ +#define PMU_OVSSET_CNT6_STATUS_Msk (1UL << PMU_OVSSET_CNT6_STATUS_Pos) /*!< PMU OVSSET: Event Counter 6 Overflow Set Mask */ + +#define PMU_OVSSET_CNT7_STATUS_Pos 7U /*!< PMU OVSSET: Event Counter 7 Overflow Set Position */ +#define PMU_OVSSET_CNT7_STATUS_Msk (1UL << PMU_OVSSET_CNT7_STATUS_Pos) /*!< PMU OVSSET: Event Counter 7 Overflow Set Mask */ + +#define PMU_OVSSET_CNT8_STATUS_Pos 8U /*!< PMU OVSSET: Event Counter 8 Overflow Set Position */ +#define PMU_OVSSET_CNT8_STATUS_Msk (1UL << PMU_OVSSET_CNT8_STATUS_Pos) /*!< PMU OVSSET: Event Counter 8 Overflow Set Mask */ + +#define PMU_OVSSET_CNT9_STATUS_Pos 9U /*!< PMU OVSSET: Event Counter 9 Overflow Set Position */ +#define PMU_OVSSET_CNT9_STATUS_Msk (1UL << PMU_OVSSET_CNT9_STATUS_Pos) /*!< PMU OVSSET: Event Counter 9 Overflow Set Mask */ + +#define PMU_OVSSET_CNT10_STATUS_Pos 10U /*!< PMU OVSSET: Event Counter 10 Overflow Set Position */ +#define PMU_OVSSET_CNT10_STATUS_Msk (1UL << PMU_OVSSET_CNT10_STATUS_Pos) /*!< PMU OVSSET: Event Counter 10 Overflow Set Mask */ + +#define PMU_OVSSET_CNT11_STATUS_Pos 11U /*!< PMU OVSSET: Event Counter 11 Overflow Set Position */ +#define PMU_OVSSET_CNT11_STATUS_Msk (1UL << PMU_OVSSET_CNT11_STATUS_Pos) /*!< PMU OVSSET: Event Counter 11 Overflow Set Mask */ + +#define PMU_OVSSET_CNT12_STATUS_Pos 12U /*!< PMU OVSSET: Event Counter 12 Overflow Set Position */ +#define PMU_OVSSET_CNT12_STATUS_Msk (1UL << PMU_OVSSET_CNT12_STATUS_Pos) /*!< PMU OVSSET: Event Counter 12 Overflow Set Mask */ + +#define PMU_OVSSET_CNT13_STATUS_Pos 13U /*!< PMU OVSSET: Event Counter 13 Overflow Set Position */ +#define PMU_OVSSET_CNT13_STATUS_Msk (1UL << PMU_OVSSET_CNT13_STATUS_Pos) /*!< PMU OVSSET: Event Counter 13 Overflow Set Mask */ + +#define PMU_OVSSET_CNT14_STATUS_Pos 14U /*!< PMU OVSSET: Event Counter 14 Overflow Set Position */ +#define PMU_OVSSET_CNT14_STATUS_Msk (1UL << PMU_OVSSET_CNT14_STATUS_Pos) /*!< PMU OVSSET: Event Counter 14 Overflow Set Mask */ + +#define PMU_OVSSET_CNT15_STATUS_Pos 15U /*!< PMU OVSSET: Event Counter 15 Overflow Set Position */ +#define PMU_OVSSET_CNT15_STATUS_Msk (1UL << PMU_OVSSET_CNT15_STATUS_Pos) /*!< PMU OVSSET: Event Counter 15 Overflow Set Mask */ + +#define PMU_OVSSET_CNT16_STATUS_Pos 16U /*!< PMU OVSSET: Event Counter 16 Overflow Set Position */ +#define PMU_OVSSET_CNT16_STATUS_Msk (1UL << PMU_OVSSET_CNT16_STATUS_Pos) /*!< PMU OVSSET: Event Counter 16 Overflow Set Mask */ + +#define PMU_OVSSET_CNT17_STATUS_Pos 17U /*!< PMU OVSSET: Event Counter 17 Overflow Set Position */ +#define PMU_OVSSET_CNT17_STATUS_Msk (1UL << PMU_OVSSET_CNT17_STATUS_Pos) /*!< PMU OVSSET: Event Counter 17 Overflow Set Mask */ + +#define PMU_OVSSET_CNT18_STATUS_Pos 18U /*!< PMU OVSSET: Event Counter 18 Overflow Set Position */ +#define PMU_OVSSET_CNT18_STATUS_Msk (1UL << PMU_OVSSET_CNT18_STATUS_Pos) /*!< PMU OVSSET: Event Counter 18 Overflow Set Mask */ + +#define PMU_OVSSET_CNT19_STATUS_Pos 19U /*!< PMU OVSSET: Event Counter 19 Overflow Set Position */ +#define PMU_OVSSET_CNT19_STATUS_Msk (1UL << PMU_OVSSET_CNT19_STATUS_Pos) /*!< PMU OVSSET: Event Counter 19 Overflow Set Mask */ + +#define PMU_OVSSET_CNT20_STATUS_Pos 20U /*!< PMU OVSSET: Event Counter 20 Overflow Set Position */ +#define PMU_OVSSET_CNT20_STATUS_Msk (1UL << PMU_OVSSET_CNT20_STATUS_Pos) /*!< PMU OVSSET: Event Counter 20 Overflow Set Mask */ + +#define PMU_OVSSET_CNT21_STATUS_Pos 21U /*!< PMU OVSSET: Event Counter 21 Overflow Set Position */ +#define PMU_OVSSET_CNT21_STATUS_Msk (1UL << PMU_OVSSET_CNT21_STATUS_Pos) /*!< PMU OVSSET: Event Counter 21 Overflow Set Mask */ + +#define PMU_OVSSET_CNT22_STATUS_Pos 22U /*!< PMU OVSSET: Event Counter 22 Overflow Set Position */ +#define PMU_OVSSET_CNT22_STATUS_Msk (1UL << PMU_OVSSET_CNT22_STATUS_Pos) /*!< PMU OVSSET: Event Counter 22 Overflow Set Mask */ + +#define PMU_OVSSET_CNT23_STATUS_Pos 23U /*!< PMU OVSSET: Event Counter 23 Overflow Set Position */ +#define PMU_OVSSET_CNT23_STATUS_Msk (1UL << PMU_OVSSET_CNT23_STATUS_Pos) /*!< PMU OVSSET: Event Counter 23 Overflow Set Mask */ + +#define PMU_OVSSET_CNT24_STATUS_Pos 24U /*!< PMU OVSSET: Event Counter 24 Overflow Set Position */ +#define PMU_OVSSET_CNT24_STATUS_Msk (1UL << PMU_OVSSET_CNT24_STATUS_Pos) /*!< PMU OVSSET: Event Counter 24 Overflow Set Mask */ + +#define PMU_OVSSET_CNT25_STATUS_Pos 25U /*!< PMU OVSSET: Event Counter 25 Overflow Set Position */ +#define PMU_OVSSET_CNT25_STATUS_Msk (1UL << PMU_OVSSET_CNT25_STATUS_Pos) /*!< PMU OVSSET: Event Counter 25 Overflow Set Mask */ + +#define PMU_OVSSET_CNT26_STATUS_Pos 26U /*!< PMU OVSSET: Event Counter 26 Overflow Set Position */ +#define PMU_OVSSET_CNT26_STATUS_Msk (1UL << PMU_OVSSET_CNT26_STATUS_Pos) /*!< PMU OVSSET: Event Counter 26 Overflow Set Mask */ + +#define PMU_OVSSET_CNT27_STATUS_Pos 27U /*!< PMU OVSSET: Event Counter 27 Overflow Set Position */ +#define PMU_OVSSET_CNT27_STATUS_Msk (1UL << PMU_OVSSET_CNT27_STATUS_Pos) /*!< PMU OVSSET: Event Counter 27 Overflow Set Mask */ + +#define PMU_OVSSET_CNT28_STATUS_Pos 28U /*!< PMU OVSSET: Event Counter 28 Overflow Set Position */ +#define PMU_OVSSET_CNT28_STATUS_Msk (1UL << PMU_OVSSET_CNT28_STATUS_Pos) /*!< PMU OVSSET: Event Counter 28 Overflow Set Mask */ + +#define PMU_OVSSET_CNT29_STATUS_Pos 29U /*!< PMU OVSSET: Event Counter 29 Overflow Set Position */ +#define PMU_OVSSET_CNT29_STATUS_Msk (1UL << PMU_OVSSET_CNT29_STATUS_Pos) /*!< PMU OVSSET: Event Counter 29 Overflow Set Mask */ + +#define PMU_OVSSET_CNT30_STATUS_Pos 30U /*!< PMU OVSSET: Event Counter 30 Overflow Set Position */ +#define PMU_OVSSET_CNT30_STATUS_Msk (1UL << PMU_OVSSET_CNT30_STATUS_Pos) /*!< PMU OVSSET: Event Counter 30 Overflow Set Mask */ + +#define PMU_OVSSET_CYCCNT_STATUS_Pos 31U /*!< PMU OVSSET: Cycle Counter Overflow Set Position */ +#define PMU_OVSSET_CYCCNT_STATUS_Msk (1UL << PMU_OVSSET_CYCCNT_STATUS_Pos) /*!< PMU OVSSET: Cycle Counter Overflow Set Mask */ + +/** \brief PMU Overflow Flag Status Clear Register Definitions */ + +#define PMU_OVSCLR_CNT0_STATUS_Pos 0U /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Position */ +#define PMU_OVSCLR_CNT0_STATUS_Msk (1UL /*<< PMU_OVSCLR_CNT0_STATUS_Pos*/) /*!< PMU OVSCLR: Event Counter 0 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT1_STATUS_Pos 1U /*!< PMU OVSCLR: Event Counter 1 Overflow Clear Position */ +#define PMU_OVSCLR_CNT1_STATUS_Msk (1UL << PMU_OVSCLR_CNT1_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 1 Overflow Clear */ + +#define PMU_OVSCLR_CNT2_STATUS_Pos 2U /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Position */ +#define PMU_OVSCLR_CNT2_STATUS_Msk (1UL << PMU_OVSCLR_CNT2_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 2 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT3_STATUS_Pos 3U /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Position */ +#define PMU_OVSCLR_CNT3_STATUS_Msk (1UL << PMU_OVSCLR_CNT3_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 3 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT4_STATUS_Pos 4U /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Position */ +#define PMU_OVSCLR_CNT4_STATUS_Msk (1UL << PMU_OVSCLR_CNT4_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 4 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT5_STATUS_Pos 5U /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Position */ +#define PMU_OVSCLR_CNT5_STATUS_Msk (1UL << PMU_OVSCLR_CNT5_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 5 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT6_STATUS_Pos 6U /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Position */ +#define PMU_OVSCLR_CNT6_STATUS_Msk (1UL << PMU_OVSCLR_CNT6_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 6 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT7_STATUS_Pos 7U /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Position */ +#define PMU_OVSCLR_CNT7_STATUS_Msk (1UL << PMU_OVSCLR_CNT7_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 7 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT8_STATUS_Pos 8U /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Position */ +#define PMU_OVSCLR_CNT8_STATUS_Msk (1UL << PMU_OVSCLR_CNT8_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 8 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT9_STATUS_Pos 9U /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Position */ +#define PMU_OVSCLR_CNT9_STATUS_Msk (1UL << PMU_OVSCLR_CNT9_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 9 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT10_STATUS_Pos 10U /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Position */ +#define PMU_OVSCLR_CNT10_STATUS_Msk (1UL << PMU_OVSCLR_CNT10_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 10 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT11_STATUS_Pos 11U /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Position */ +#define PMU_OVSCLR_CNT11_STATUS_Msk (1UL << PMU_OVSCLR_CNT11_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 11 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT12_STATUS_Pos 12U /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Position */ +#define PMU_OVSCLR_CNT12_STATUS_Msk (1UL << PMU_OVSCLR_CNT12_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 12 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT13_STATUS_Pos 13U /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Position */ +#define PMU_OVSCLR_CNT13_STATUS_Msk (1UL << PMU_OVSCLR_CNT13_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 13 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT14_STATUS_Pos 14U /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Position */ +#define PMU_OVSCLR_CNT14_STATUS_Msk (1UL << PMU_OVSCLR_CNT14_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 14 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT15_STATUS_Pos 15U /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Position */ +#define PMU_OVSCLR_CNT15_STATUS_Msk (1UL << PMU_OVSCLR_CNT15_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 15 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT16_STATUS_Pos 16U /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Position */ +#define PMU_OVSCLR_CNT16_STATUS_Msk (1UL << PMU_OVSCLR_CNT16_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 16 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT17_STATUS_Pos 17U /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Position */ +#define PMU_OVSCLR_CNT17_STATUS_Msk (1UL << PMU_OVSCLR_CNT17_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 17 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT18_STATUS_Pos 18U /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Position */ +#define PMU_OVSCLR_CNT18_STATUS_Msk (1UL << PMU_OVSCLR_CNT18_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 18 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT19_STATUS_Pos 19U /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Position */ +#define PMU_OVSCLR_CNT19_STATUS_Msk (1UL << PMU_OVSCLR_CNT19_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 19 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT20_STATUS_Pos 20U /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Position */ +#define PMU_OVSCLR_CNT20_STATUS_Msk (1UL << PMU_OVSCLR_CNT20_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 20 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT21_STATUS_Pos 21U /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Position */ +#define PMU_OVSCLR_CNT21_STATUS_Msk (1UL << PMU_OVSCLR_CNT21_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 21 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT22_STATUS_Pos 22U /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Position */ +#define PMU_OVSCLR_CNT22_STATUS_Msk (1UL << PMU_OVSCLR_CNT22_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 22 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT23_STATUS_Pos 23U /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Position */ +#define PMU_OVSCLR_CNT23_STATUS_Msk (1UL << PMU_OVSCLR_CNT23_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 23 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT24_STATUS_Pos 24U /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Position */ +#define PMU_OVSCLR_CNT24_STATUS_Msk (1UL << PMU_OVSCLR_CNT24_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 24 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT25_STATUS_Pos 25U /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Position */ +#define PMU_OVSCLR_CNT25_STATUS_Msk (1UL << PMU_OVSCLR_CNT25_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 25 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT26_STATUS_Pos 26U /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Position */ +#define PMU_OVSCLR_CNT26_STATUS_Msk (1UL << PMU_OVSCLR_CNT26_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 26 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT27_STATUS_Pos 27U /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Position */ +#define PMU_OVSCLR_CNT27_STATUS_Msk (1UL << PMU_OVSCLR_CNT27_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 27 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT28_STATUS_Pos 28U /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Position */ +#define PMU_OVSCLR_CNT28_STATUS_Msk (1UL << PMU_OVSCLR_CNT28_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 28 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT29_STATUS_Pos 29U /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Position */ +#define PMU_OVSCLR_CNT29_STATUS_Msk (1UL << PMU_OVSCLR_CNT29_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 29 Overflow Clear Mask */ + +#define PMU_OVSCLR_CNT30_STATUS_Pos 30U /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Position */ +#define PMU_OVSCLR_CNT30_STATUS_Msk (1UL << PMU_OVSCLR_CNT30_STATUS_Pos) /*!< PMU OVSCLR: Event Counter 30 Overflow Clear Mask */ + +#define PMU_OVSCLR_CYCCNT_STATUS_Pos 31U /*!< PMU OVSCLR: Cycle Counter Overflow Clear Position */ +#define PMU_OVSCLR_CYCCNT_STATUS_Msk (1UL << PMU_OVSCLR_CYCCNT_STATUS_Pos) /*!< PMU OVSCLR: Cycle Counter Overflow Clear Mask */ + +/** \brief PMU Software Increment Counter */ + +#define PMU_SWINC_CNT0_Pos 0U /*!< PMU SWINC: Event Counter 0 Software Increment Position */ +#define PMU_SWINC_CNT0_Msk (1UL /*<< PMU_SWINC_CNT0_Pos */) /*!< PMU SWINC: Event Counter 0 Software Increment Mask */ + +#define PMU_SWINC_CNT1_Pos 1U /*!< PMU SWINC: Event Counter 1 Software Increment Position */ +#define PMU_SWINC_CNT1_Msk (1UL << PMU_SWINC_CNT1_Pos) /*!< PMU SWINC: Event Counter 1 Software Increment Mask */ + +#define PMU_SWINC_CNT2_Pos 2U /*!< PMU SWINC: Event Counter 2 Software Increment Position */ +#define PMU_SWINC_CNT2_Msk (1UL << PMU_SWINC_CNT2_Pos) /*!< PMU SWINC: Event Counter 2 Software Increment Mask */ + +#define PMU_SWINC_CNT3_Pos 3U /*!< PMU SWINC: Event Counter 3 Software Increment Position */ +#define PMU_SWINC_CNT3_Msk (1UL << PMU_SWINC_CNT3_Pos) /*!< PMU SWINC: Event Counter 3 Software Increment Mask */ + +#define PMU_SWINC_CNT4_Pos 4U /*!< PMU SWINC: Event Counter 4 Software Increment Position */ +#define PMU_SWINC_CNT4_Msk (1UL << PMU_SWINC_CNT4_Pos) /*!< PMU SWINC: Event Counter 4 Software Increment Mask */ + +#define PMU_SWINC_CNT5_Pos 5U /*!< PMU SWINC: Event Counter 5 Software Increment Position */ +#define PMU_SWINC_CNT5_Msk (1UL << PMU_SWINC_CNT5_Pos) /*!< PMU SWINC: Event Counter 5 Software Increment Mask */ + +#define PMU_SWINC_CNT6_Pos 6U /*!< PMU SWINC: Event Counter 6 Software Increment Position */ +#define PMU_SWINC_CNT6_Msk (1UL << PMU_SWINC_CNT6_Pos) /*!< PMU SWINC: Event Counter 6 Software Increment Mask */ + +#define PMU_SWINC_CNT7_Pos 7U /*!< PMU SWINC: Event Counter 7 Software Increment Position */ +#define PMU_SWINC_CNT7_Msk (1UL << PMU_SWINC_CNT7_Pos) /*!< PMU SWINC: Event Counter 7 Software Increment Mask */ + +#define PMU_SWINC_CNT8_Pos 8U /*!< PMU SWINC: Event Counter 8 Software Increment Position */ +#define PMU_SWINC_CNT8_Msk (1UL << PMU_SWINC_CNT8_Pos) /*!< PMU SWINC: Event Counter 8 Software Increment Mask */ + +#define PMU_SWINC_CNT9_Pos 9U /*!< PMU SWINC: Event Counter 9 Software Increment Position */ +#define PMU_SWINC_CNT9_Msk (1UL << PMU_SWINC_CNT9_Pos) /*!< PMU SWINC: Event Counter 9 Software Increment Mask */ + +#define PMU_SWINC_CNT10_Pos 10U /*!< PMU SWINC: Event Counter 10 Software Increment Position */ +#define PMU_SWINC_CNT10_Msk (1UL << PMU_SWINC_CNT10_Pos) /*!< PMU SWINC: Event Counter 10 Software Increment Mask */ + +#define PMU_SWINC_CNT11_Pos 11U /*!< PMU SWINC: Event Counter 11 Software Increment Position */ +#define PMU_SWINC_CNT11_Msk (1UL << PMU_SWINC_CNT11_Pos) /*!< PMU SWINC: Event Counter 11 Software Increment Mask */ + +#define PMU_SWINC_CNT12_Pos 12U /*!< PMU SWINC: Event Counter 12 Software Increment Position */ +#define PMU_SWINC_CNT12_Msk (1UL << PMU_SWINC_CNT12_Pos) /*!< PMU SWINC: Event Counter 12 Software Increment Mask */ + +#define PMU_SWINC_CNT13_Pos 13U /*!< PMU SWINC: Event Counter 13 Software Increment Position */ +#define PMU_SWINC_CNT13_Msk (1UL << PMU_SWINC_CNT13_Pos) /*!< PMU SWINC: Event Counter 13 Software Increment Mask */ + +#define PMU_SWINC_CNT14_Pos 14U /*!< PMU SWINC: Event Counter 14 Software Increment Position */ +#define PMU_SWINC_CNT14_Msk (1UL << PMU_SWINC_CNT14_Pos) /*!< PMU SWINC: Event Counter 14 Software Increment Mask */ + +#define PMU_SWINC_CNT15_Pos 15U /*!< PMU SWINC: Event Counter 15 Software Increment Position */ +#define PMU_SWINC_CNT15_Msk (1UL << PMU_SWINC_CNT15_Pos) /*!< PMU SWINC: Event Counter 15 Software Increment Mask */ + +#define PMU_SWINC_CNT16_Pos 16U /*!< PMU SWINC: Event Counter 16 Software Increment Position */ +#define PMU_SWINC_CNT16_Msk (1UL << PMU_SWINC_CNT16_Pos) /*!< PMU SWINC: Event Counter 16 Software Increment Mask */ + +#define PMU_SWINC_CNT17_Pos 17U /*!< PMU SWINC: Event Counter 17 Software Increment Position */ +#define PMU_SWINC_CNT17_Msk (1UL << PMU_SWINC_CNT17_Pos) /*!< PMU SWINC: Event Counter 17 Software Increment Mask */ + +#define PMU_SWINC_CNT18_Pos 18U /*!< PMU SWINC: Event Counter 18 Software Increment Position */ +#define PMU_SWINC_CNT18_Msk (1UL << PMU_SWINC_CNT18_Pos) /*!< PMU SWINC: Event Counter 18 Software Increment Mask */ + +#define PMU_SWINC_CNT19_Pos 19U /*!< PMU SWINC: Event Counter 19 Software Increment Position */ +#define PMU_SWINC_CNT19_Msk (1UL << PMU_SWINC_CNT19_Pos) /*!< PMU SWINC: Event Counter 19 Software Increment Mask */ + +#define PMU_SWINC_CNT20_Pos 20U /*!< PMU SWINC: Event Counter 20 Software Increment Position */ +#define PMU_SWINC_CNT20_Msk (1UL << PMU_SWINC_CNT20_Pos) /*!< PMU SWINC: Event Counter 20 Software Increment Mask */ + +#define PMU_SWINC_CNT21_Pos 21U /*!< PMU SWINC: Event Counter 21 Software Increment Position */ +#define PMU_SWINC_CNT21_Msk (1UL << PMU_SWINC_CNT21_Pos) /*!< PMU SWINC: Event Counter 21 Software Increment Mask */ + +#define PMU_SWINC_CNT22_Pos 22U /*!< PMU SWINC: Event Counter 22 Software Increment Position */ +#define PMU_SWINC_CNT22_Msk (1UL << PMU_SWINC_CNT22_Pos) /*!< PMU SWINC: Event Counter 22 Software Increment Mask */ + +#define PMU_SWINC_CNT23_Pos 23U /*!< PMU SWINC: Event Counter 23 Software Increment Position */ +#define PMU_SWINC_CNT23_Msk (1UL << PMU_SWINC_CNT23_Pos) /*!< PMU SWINC: Event Counter 23 Software Increment Mask */ + +#define PMU_SWINC_CNT24_Pos 24U /*!< PMU SWINC: Event Counter 24 Software Increment Position */ +#define PMU_SWINC_CNT24_Msk (1UL << PMU_SWINC_CNT24_Pos) /*!< PMU SWINC: Event Counter 24 Software Increment Mask */ + +#define PMU_SWINC_CNT25_Pos 25U /*!< PMU SWINC: Event Counter 25 Software Increment Position */ +#define PMU_SWINC_CNT25_Msk (1UL << PMU_SWINC_CNT25_Pos) /*!< PMU SWINC: Event Counter 25 Software Increment Mask */ + +#define PMU_SWINC_CNT26_Pos 26U /*!< PMU SWINC: Event Counter 26 Software Increment Position */ +#define PMU_SWINC_CNT26_Msk (1UL << PMU_SWINC_CNT26_Pos) /*!< PMU SWINC: Event Counter 26 Software Increment Mask */ + +#define PMU_SWINC_CNT27_Pos 27U /*!< PMU SWINC: Event Counter 27 Software Increment Position */ +#define PMU_SWINC_CNT27_Msk (1UL << PMU_SWINC_CNT27_Pos) /*!< PMU SWINC: Event Counter 27 Software Increment Mask */ + +#define PMU_SWINC_CNT28_Pos 28U /*!< PMU SWINC: Event Counter 28 Software Increment Position */ +#define PMU_SWINC_CNT28_Msk (1UL << PMU_SWINC_CNT28_Pos) /*!< PMU SWINC: Event Counter 28 Software Increment Mask */ + +#define PMU_SWINC_CNT29_Pos 29U /*!< PMU SWINC: Event Counter 29 Software Increment Position */ +#define PMU_SWINC_CNT29_Msk (1UL << PMU_SWINC_CNT29_Pos) /*!< PMU SWINC: Event Counter 29 Software Increment Mask */ + +#define PMU_SWINC_CNT30_Pos 30U /*!< PMU SWINC: Event Counter 30 Software Increment Position */ +#define PMU_SWINC_CNT30_Msk (1UL << PMU_SWINC_CNT30_Pos) /*!< PMU SWINC: Event Counter 30 Software Increment Mask */ + +/** \brief PMU Control Register Definitions */ + +#define PMU_CTRL_ENABLE_Pos 0U /*!< PMU CTRL: ENABLE Position */ +#define PMU_CTRL_ENABLE_Msk (1UL /*<< PMU_CTRL_ENABLE_Pos*/) /*!< PMU CTRL: ENABLE Mask */ + +#define PMU_CTRL_EVENTCNT_RESET_Pos 1U /*!< PMU CTRL: Event Counter Reset Position */ +#define PMU_CTRL_EVENTCNT_RESET_Msk (1UL << PMU_CTRL_EVENTCNT_RESET_Pos) /*!< PMU CTRL: Event Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_RESET_Pos 2U /*!< PMU CTRL: Cycle Counter Reset Position */ +#define PMU_CTRL_CYCCNT_RESET_Msk (1UL << PMU_CTRL_CYCCNT_RESET_Pos) /*!< PMU CTRL: Cycle Counter Reset Mask */ + +#define PMU_CTRL_CYCCNT_DISABLE_Pos 5U /*!< PMU CTRL: Disable Cycle Counter Position */ +#define PMU_CTRL_CYCCNT_DISABLE_Msk (1UL << PMU_CTRL_CYCCNT_DISABLE_Pos) /*!< PMU CTRL: Disable Cycle Counter Mask */ + +#define PMU_CTRL_FRZ_ON_OV_Pos 9U /*!< PMU CTRL: Freeze-on-overflow Position */ +#define PMU_CTRL_FRZ_ON_OV_Msk (1UL << PMU_CTRL_FRZ_ON_OVERFLOW_Pos) /*!< PMU CTRL: Freeze-on-overflow Mask */ + +#define PMU_CTRL_TRACE_ON_OV_Pos 11U /*!< PMU CTRL: Trace-on-overflow Position */ +#define PMU_CTRL_TRACE_ON_OV_Msk (1UL << PMU_CTRL_TRACE_ON_OVERFLOW_Pos) /*!< PMU CTRL: Trace-on-overflow Mask */ + +/** \brief PMU Type Register Definitions */ + +#define PMU_TYPE_NUM_CNTS_Pos 0U /*!< PMU TYPE: Number of Counters Position */ +#define PMU_TYPE_NUM_CNTS_Msk (0xFFUL /*<< PMU_TYPE_NUM_CNTS_Pos*/) /*!< PMU TYPE: Number of Counters Mask */ + +#define PMU_TYPE_SIZE_CNTS_Pos 8U /*!< PMU TYPE: Size of Counters Position */ +#define PMU_TYPE_SIZE_CNTS_Msk (0x3FUL << PMU_TYPE_SIZE_CNTS_Pos) /*!< PMU TYPE: Size of Counters Mask */ + +#define PMU_TYPE_CYCCNT_PRESENT_Pos 14U /*!< PMU TYPE: Cycle Counter Present Position */ +#define PMU_TYPE_CYCCNT_PRESENT_Msk (1UL << PMU_TYPE_CYCCNT_PRESENT_Pos) /*!< PMU TYPE: Cycle Counter Present Mask */ + +#define PMU_TYPE_FRZ_OV_SUPPORT_Pos 21U /*!< PMU TYPE: Freeze-on-overflow Support Position */ +#define PMU_TYPE_FRZ_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Freeze-on-overflow Support Mask */ + +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Pos 23U /*!< PMU TYPE: Trace-on-overflow Support Position */ +#define PMU_TYPE_TRACE_ON_OV_SUPPORT_Msk (1UL << PMU_TYPE_FRZ_OV_SUPPORT_Pos) /*!< PMU TYPE: Trace-on-overflow Support Mask */ + +/** \brief PMU Authentication Status Register Definitions */ + +#define PMU_AUTHSTATUS_NSID_Pos 0U /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSID_Msk (0x3UL /*<< PMU_AUTHSTATUS_NSID_Pos*/) /*!< PMU AUTHSTATUS: Non-secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSNID_Pos 2U /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSNID_Msk (0x3UL << PMU_AUTHSTATUS_NSNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SID_Pos 4U /*!< PMU AUTHSTATUS: Secure Invasive Debug Position */ +#define PMU_AUTHSTATUS_SID_Msk (0x3UL << PMU_AUTHSTATUS_SID_Pos) /*!< PMU AUTHSTATUS: Secure Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SNID_Pos 6U /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SNID_Msk (0x3UL << PMU_AUTHSTATUS_SNID_Pos) /*!< PMU AUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUID_Pos 16U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUID_Msk (0x3UL << PMU_AUTHSTATUS_NSUID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_NSUNID_Pos 18U /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_NSUNID_Msk (0x3UL << PMU_AUTHSTATUS_NSUNID_Pos) /*!< PMU AUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUID_Pos 20U /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Position */ +#define PMU_AUTHSTATUS_SUID_Msk (0x3UL << PMU_AUTHSTATUS_SUID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Invasive Debug Mask */ + +#define PMU_AUTHSTATUS_SUNID_Pos 22U /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Position */ +#define PMU_AUTHSTATUS_SUNID_Msk (0x3UL << PMU_AUTHSTATUS_SUNID_Pos) /*!< PMU AUTHSTATUS: Secure Unprivileged Non-invasive Debug Mask */ + + +/*@} end of group CMSIS_PMU */ +#endif + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_PXN_Pos 4U /*!< MPU RLAR: PXN Position */ +#define MPU_RLAR_PXN_Msk (1UL << MPU_RLAR_PXN_Pos) /*!< MPU RLAR: PXN Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +#define FPU_FPDSCR_FZ16_Pos 19U /*!< FPDSCR: FZ16 bit Position */ +#define FPU_FPDSCR_FZ16_Msk (1UL << FPU_FPDSCR_FZ16_Pos) /*!< FPDSCR: FZ16 bit Mask */ + +#define FPU_FPDSCR_LTPSIZE_Pos 16U /*!< FPDSCR: LTPSIZE bit Position */ +#define FPU_FPDSCR_LTPSIZE_Msk (7UL << FPU_FPDSCR_LTPSIZE_Pos) /*!< FPDSCR: LTPSIZE bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FPRound_Pos 28U /*!< MVFR0: FPRound bits Position */ +#define FPU_MVFR0_FPRound_Msk (0xFUL << FPU_MVFR0_FPRound_Pos) /*!< MVFR0: FPRound bits Mask */ + +#define FPU_MVFR0_FPSqrt_Pos 20U /*!< MVFR0: FPSqrt bits Position */ +#define FPU_MVFR0_FPSqrt_Msk (0xFUL << FPU_MVFR0_FPSqrt_Pos) /*!< MVFR0: FPSqrt bits Mask */ + +#define FPU_MVFR0_FPDivide_Pos 16U /*!< MVFR0: FPDivide bits Position */ +#define FPU_MVFR0_FPDivide_Msk (0xFUL << FPU_MVFR0_FPDivide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FPDP_Pos 8U /*!< MVFR0: FPDP bits Position */ +#define FPU_MVFR0_FPDP_Msk (0xFUL << FPU_MVFR0_FPDP_Pos) /*!< MVFR0: FPDP bits Mask */ + +#define FPU_MVFR0_FPSP_Pos 4U /*!< MVFR0: FPSP bits Position */ +#define FPU_MVFR0_FPSP_Msk (0xFUL << FPU_MVFR0_FPSP_Pos) /*!< MVFR0: FPSP bits Mask */ + +#define FPU_MVFR0_SIMDReg_Pos 0U /*!< MVFR0: SIMDReg bits Position */ +#define FPU_MVFR0_SIMDReg_Msk (0xFUL /*<< FPU_MVFR0_SIMDReg_Pos*/) /*!< MVFR0: SIMDReg bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FMAC_Pos 28U /*!< MVFR1: FMAC bits Position */ +#define FPU_MVFR1_FMAC_Msk (0xFUL << FPU_MVFR1_FMAC_Pos) /*!< MVFR1: FMAC bits Mask */ + +#define FPU_MVFR1_FPHP_Pos 24U /*!< MVFR1: FPHP bits Position */ +#define FPU_MVFR1_FPHP_Msk (0xFUL << FPU_MVFR1_FPHP_Pos) /*!< MVFR1: FPHP bits Mask */ + +#define FPU_MVFR1_FP16_Pos 20U /*!< MVFR1: FP16 bits Position */ +#define FPU_MVFR1_FP16_Msk (0xFUL << FPU_MVFR1_FP16_Pos) /*!< MVFR1: FP16 bits Mask */ + +#define FPU_MVFR1_MVE_Pos 8U /*!< MVFR1: MVE bits Position */ +#define FPU_MVFR1_MVE_Msk (0xFUL << FPU_MVFR1_MVE_Pos) /*!< MVFR1: MVE bits Mask */ + +#define FPU_MVFR1_FPDNaN_Pos 4U /*!< MVFR1: FPDNaN bits Position */ +#define FPU_MVFR1_FPDNaN_Msk (0xFUL << FPU_MVFR1_FPDNaN_Pos) /*!< MVFR1: FPDNaN bits Mask */ + +#define FPU_MVFR1_FPFtZ_Pos 0U /*!< MVFR1: FPFtZ bits Position */ +#define FPU_MVFR1_FPFtZ_Msk (0xFUL /*<< FPU_MVFR1_FPFtZ_Pos*/) /*!< MVFR1: FPFtZ bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + +/* CoreDebug is deprecated. replaced by DCB (Debug Control Block) */ +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief \deprecated Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< \deprecated CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< \deprecated CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< \deprecated CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_FPD_Pos 23U /*!< \deprecated CoreDebug DHCSR: S_FPD Position */ +#define CoreDebug_DHCSR_S_FPD_Msk (1UL << CoreDebug_DHCSR_S_FPD_Pos) /*!< \deprecated CoreDebug DHCSR: S_FPD Mask */ + +#define CoreDebug_DHCSR_S_SUIDE_Pos 22U /*!< \deprecated CoreDebug DHCSR: S_SUIDE Position */ +#define CoreDebug_DHCSR_S_SUIDE_Msk (1UL << CoreDebug_DHCSR_S_SUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SUIDE Mask */ + +#define CoreDebug_DHCSR_S_NSUIDE_Pos 21U /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Position */ +#define CoreDebug_DHCSR_S_NSUIDE_Msk (1UL << CoreDebug_DHCSR_S_NSUIDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_NSUIDE Mask */ + +#define CoreDebug_DHCSR_S_SDE_Pos 20U /*!< \deprecated CoreDebug DHCSR: S_SDE Position */ +#define CoreDebug_DHCSR_S_SDE_Msk (1UL << CoreDebug_DHCSR_S_SDE_Pos) /*!< \deprecated CoreDebug DHCSR: S_SDE Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< \deprecated CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< \deprecated CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< \deprecated CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< \deprecated CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< \deprecated CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< \deprecated CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_PMOV_Pos 6U /*!< \deprecated CoreDebug DHCSR: C_PMOV Position */ +#define CoreDebug_DHCSR_C_PMOV_Msk (1UL << CoreDebug_DHCSR_C_PMOV_Pos) /*!< \deprecated CoreDebug DHCSR: C_PMOV Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< \deprecated CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< \deprecated CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< \deprecated CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< \deprecated CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< \deprecated CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< \deprecated CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< \deprecated CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< \deprecated CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< \deprecated CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< \deprecated CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< \deprecated CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< \deprecated CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< \deprecated CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< \deprecated CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< \deprecated CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< \deprecated CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< \deprecated CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< \deprecated CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< \deprecated CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< \deprecated CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< \deprecated CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< \deprecated CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< \deprecated CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< \deprecated CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Set Clear Exception and Monitor Control Register Definitions */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_CLR_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_CLR_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: CLR_MON_PEND, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_REQ_Pos 3U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Position */ +#define CoreDebug_DSCEMCR_SET_MON_REQ_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_REQ_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_REQ, Mask */ + +#define CoreDebug_DSCEMCR_SET_MON_PEND_Pos 1U /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Position */ +#define CoreDebug_DSCEMCR_SET_MON_PEND_Msk (1UL << CoreDebug_DSCEMCR_SET_MON_PEND_Pos) /*!< \deprecated CoreDebug DSCEMCR: SET_MON_PEND, Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_UIDEN_Pos 10U /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_UIDAPEN_Pos 9U /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Position */ +#define CoreDebug_DAUTHCTRL_UIDAPEN_Msk (1UL << CoreDebug_DAUTHCTRL_UIDAPEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: UIDAPEN, Mask */ + +#define CoreDebug_DAUTHCTRL_FSDMA_Pos 8U /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Position */ +#define CoreDebug_DAUTHCTRL_FSDMA_Msk (1UL << CoreDebug_DAUTHCTRL_FSDMA_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: FSDMA, Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< \deprecated CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< \deprecated CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< \deprecated CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< \deprecated CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< \deprecated CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< \deprecated CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< \deprecated CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< \deprecated CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + __OM uint32_t DSCEMCR; /*!< Offset: 0x010 ( /W) Debug Set Clear Exception and Monitor Control Register */ + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_FPD_Pos 23U /*!< DCB DHCSR: Floating-point registers Debuggable Position */ +#define DCB_DHCSR_S_FPD_Msk (0x1UL << DCB_DHCSR_S_FPD_Pos) /*!< DCB DHCSR: Floating-point registers Debuggable Mask */ + +#define DCB_DHCSR_S_SUIDE_Pos 22U /*!< DCB DHCSR: Secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_SUIDE_Msk (0x1UL << DCB_DHCSR_S_SUIDE_Pos) /*!< DCB DHCSR: Secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_NSUIDE_Pos 21U /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Position */ +#define DCB_DHCSR_S_NSUIDE_Msk (0x1UL << DCB_DHCSR_S_NSUIDE_Pos) /*!< DCB DHCSR: Non-secure unprivileged halting debug enabled Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_PMOV_Pos 6U /*!< DCB DHCSR: Halt on PMU overflow control Position */ +#define DCB_DHCSR_C_PMOV_Msk (0x1UL << DCB_DHCSR_C_PMOV_Pos) /*!< DCB DHCSR: Halt on PMU overflow control Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DSCEMCR, Debug Set Clear Exception and Monitor Control Register Definitions */ +#define DCB_DSCEMCR_CLR_MON_REQ_Pos 19U /*!< DCB DSCEMCR: Clear monitor request Position */ +#define DCB_DSCEMCR_CLR_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_REQ_Pos) /*!< DCB DSCEMCR: Clear monitor request Mask */ + +#define DCB_DSCEMCR_CLR_MON_PEND_Pos 17U /*!< DCB DSCEMCR: Clear monitor pend Position */ +#define DCB_DSCEMCR_CLR_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_CLR_MON_PEND_Pos) /*!< DCB DSCEMCR: Clear monitor pend Mask */ + +#define DCB_DSCEMCR_SET_MON_REQ_Pos 3U /*!< DCB DSCEMCR: Set monitor request Position */ +#define DCB_DSCEMCR_SET_MON_REQ_Msk (0x1UL << DCB_DSCEMCR_SET_MON_REQ_Pos) /*!< DCB DSCEMCR: Set monitor request Mask */ + +#define DCB_DSCEMCR_SET_MON_PEND_Pos 1U /*!< DCB DSCEMCR: Set monitor pend Position */ +#define DCB_DSCEMCR_SET_MON_PEND_Msk (0x1UL << DCB_DSCEMCR_SET_MON_PEND_Pos) /*!< DCB DSCEMCR: Set monitor pend Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_UIDEN_Pos 10U /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Position */ +#define DCB_DAUTHCTRL_UIDEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive Debug Enable Mask */ + +#define DCB_DAUTHCTRL_UIDAPEN_Pos 9U /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Position */ +#define DCB_DAUTHCTRL_UIDAPEN_Msk (0x1UL << DCB_DAUTHCTRL_UIDAPEN_Pos) /*!< DCB DAUTHCTRL: Unprivileged Invasive DAP Access Enable Mask */ + +#define DCB_DAUTHCTRL_FSDMA_Pos 8U /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Position */ +#define DCB_DAUTHCTRL_FSDMA_Msk (0x1UL << DCB_DAUTHCTRL_FSDMA_Pos) /*!< DCB DAUTHCTRL: Force Secure DebugMonitor Allowed Mask */ + +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SUNID_Pos 22U /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUNID_Msk (0x3UL << DIB_DAUTHSTATUS_SUNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Non-invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SUID_Pos 20U /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_SUID_Msk (0x3UL << DIB_DAUTHSTATUS_SUID_Pos ) /*!< DIB DAUTHSTATUS: Secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_NSUNID_Pos 18U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Position */ +#define DIB_DAUTHSTATUS_NSUNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Non-invasive Debug Allo Mask */ + +#define DIB_DAUTHSTATUS_NSUID_Pos 16U /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Position */ +#define DIB_DAUTHSTATUS_NSUID_Msk (0x3UL << DIB_DAUTHSTATUS_NSUID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Unprivileged Invasive Debug Allowed Mask */ + +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define MEMSYSCTL_BASE (0xE001E000UL) /*!< Memory System Control Base Address */ + #define ERRBNK_BASE (0xE001E100UL) /*!< Error Banking Base Address */ + #define PWRMODCTL_BASE (0xE001E300UL) /*!< Power Mode Control Base Address */ + #define EWIC_BASE (0xE001E400UL) /*!< External Wakeup Interrupt Controller Base Address */ + #define PRCCFGINF_BASE (0xE001E700UL) /*!< Processor Configuration Information Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< \deprecated Core Debug Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define ICB ((ICB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define MEMSYSCTL ((MemSysCtl_Type *) MEMSYSCTL_BASE ) /*!< Memory System Control configuration struct */ + #define ERRBNK ((ErrBnk_Type *) ERRBNK_BASE ) /*!< Error Banking configuration struct */ + #define PWRMODCTL ((PwrModCtl_Type *) PWRMODCTL_BASE ) /*!< Power Mode Control configuration struct */ + #define EWIC ((EWIC_Type *) EWIC_BASE ) /*!< EWIC configuration struct */ + #define PRCCFGINF ((PrcCfgInf_Type *) PRCCFGINF_BASE ) /*!< Processor Configuration Information configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< \deprecated Core Debug configuration struct */ + #define DCB ((DCB_Type *) DCB_BASE ) /*!< DCB configuration struct */ + #define DIB ((DIB_Type *) DIB_BASE ) /*!< DIB configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + #define PMU_BASE (0xE0003000UL) /*!< PMU Base Address */ + #define PMU ((PMU_Type *) PMU_BASE ) /*!< PMU configuration struct */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< \deprecated Core Debug Base Address (non-secure address space) */ + #define DCB_BASE_NS (0xE002EDF0UL) /*!< DCB Base Address (non-secure address space) */ + #define DIB_BASE_NS (0xE002EFB0UL) /*!< DIB Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define ICB_NS ((ICB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< \deprecated Core Debug configuration struct (non-secure address space) */ + #define DCB_NS ((DCB_Type *) DCB_BASE_NS ) /*!< DCB configuration struct (non-secure address space) */ + #define DIB_NS ((DIB_Type *) DIB_BASE_NS ) /*!< DIB configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ + +/*@} */ + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## PMU functions and events #################################### */ + +#if defined (__PMU_PRESENT) && (__PMU_PRESENT == 1U) + +#include "pmu_armv8.h" + +/** + \brief Cortex-M85 PMU events + \note Architectural PMU events can be found in pmu_armv8.h +*/ + +#define ARMCM85_PMU_ECC_ERR 0xC000 /*!< One or more Error Correcting Code (ECC) errors detected */ +#define ARMCM85_PMU_ECC_ERR_MBIT 0xC001 /*!< One or more multi-bit ECC errors detected */ +#define ARMCM85_PMU_ECC_ERR_DCACHE 0xC010 /*!< One or more ECC errors in the data cache */ +#define ARMCM85_PMU_ECC_ERR_ICACHE 0xC011 /*!< One or more ECC errors in the instruction cache */ +#define ARMCM85_PMU_ECC_ERR_MBIT_DCACHE 0xC012 /*!< One or more multi-bit ECC errors in the data cache */ +#define ARMCM85_PMU_ECC_ERR_MBIT_ICACHE 0xC013 /*!< One or more multi-bit ECC errors in the instruction cache */ +#define ARMCM85_PMU_ECC_ERR_DTCM 0xC020 /*!< One or more ECC errors in the Data Tightly Coupled Memory (DTCM) */ +#define ARMCM85_PMU_ECC_ERR_ITCM 0xC021 /*!< One or more ECC errors in the Instruction Tightly Coupled Memory (ITCM) */ +#define ARMCM85_PMU_ECC_ERR_MBIT_DTCM 0xC022 /*!< One or more multi-bit ECC errors in the DTCM */ +#define ARMCM85_PMU_ECC_ERR_MBIT_ITCM 0xC023 /*!< One or more multi-bit ECC errors in the ITCM */ +#define ARMCM85_PMU_PF_LINEFILL 0xC100 /*!< The prefetcher starts a line-fill */ +#define ARMCM85_PMU_PF_CANCEL 0xC101 /*!< The prefetcher stops prefetching */ +#define ARMCM85_PMU_PF_DROP_LINEFILL 0xC102 /*!< A linefill triggered by a prefetcher has been dropped because of lack of buffering */ +#define ARMCM85_PMU_NWAMODE_ENTER 0xC200 /*!< No write-allocate mode entry */ +#define ARMCM85_PMU_NWAMODE 0xC201 /*!< Write-allocate store is not allocated into the data cache due to no-write-allocate mode */ +#define ARMCM85_PMU_SAHB_ACCESS 0xC300 /*!< Read or write access on the S-AHB interface to the TCM */ +#define ARMCM85_PMU_PAHB_ACCESS 0xC301 /*!< Read or write access on the P-AHB write interface */ +#define ARMCM85_PMU_AXI_WRITE_ACCESS 0xC302 /*!< Any beat access to M-AXI write interface */ +#define ARMCM85_PMU_AXI_READ_ACCESS 0xC303 /*!< Any beat access to M-AXI read interface */ +#define ARMCM85_PMU_DOSTIMEOUT_DOUBLE 0xC400 /*!< Denial of Service timeout has fired twice and caused buffers to drain to allow forward progress */ +#define ARMCM85_PMU_DOSTIMEOUT_TRIPLE 0xC401 /*!< Denial of Service timeout has fired three times and blocked the LSU to force forward progress */ + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_FPSP_Msk | FPU_MVFR0_FPDP_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + +/* ########################## MVE functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_MveFunctions MVE Functions + \brief Function that provides MVE type. + @{ + */ + +/** + \brief get MVE type + \details returns the MVE type + \returns + - \b 0: No Vector Extension (MVE) + - \b 1: Integer Vector Extension (MVE-I) + - \b 2: Floating-point Vector Extension (MVE-F) + */ +__STATIC_INLINE uint32_t SCB_GetMVEType(void) +{ + const uint32_t mvfr1 = FPU->MVFR1; + if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x2U << FPU_MVFR1_MVE_Pos)) + { + return 2U; + } + else if ((mvfr1 & FPU_MVFR1_MVE_Msk) == (0x1U << FPU_MVFR1_MVE_Pos)) + { + return 1U; + } + else + { + return 0U; + } +} + + +/*@} end of CMSIS_Core_MveFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + +/* ################### PAC Key functions ########################### */ + +#if (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) +#include "pac_armv81.h" +#endif + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM85_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_sc000.h b/Drivers/CMSIS/Include/core_sc000.h new file mode 100644 index 0000000..dbc755f --- /dev/null +++ b/Drivers/CMSIS/Include/core_sc000.h @@ -0,0 +1,1030 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 27. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M0 and M0+ do not require the architectural barrier - assume SC000 is the same */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_sc300.h b/Drivers/CMSIS/Include/core_sc300.h new file mode 100644 index 0000000..d666210 --- /dev/null +++ b/Drivers/CMSIS/Include/core_sc300.h @@ -0,0 +1,1917 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.10 + * @date 04. June 2021 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M3 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/core_starmc1.h b/Drivers/CMSIS/Include/core_starmc1.h new file mode 100644 index 0000000..d86c8d3 --- /dev/null +++ b/Drivers/CMSIS/Include/core_starmc1.h @@ -0,0 +1,3592 @@ +/**************************************************************************//** + * @file core_starmc1.h + * @brief CMSIS ArmChina STAR-MC1 Core Peripheral Access Layer Header File + * @version V1.0.2 + * @date 07. April 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. + * Copyright (c) 2018-2022 Arm China. + * All rights reserved. + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic ignored "-Wpedantic" /* disable pedantic warning due to unnamed structs/unions */ +#endif + +#ifndef __CORE_STAR_H_GENERIC +#define __CORE_STAR_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup STAR-MC1 + @{ + */ + +#include "cmsis_version.h" + +/* Macro Define for STAR-MC1 */ +#define __STAR_MC (1U) /*!< STAR-MC Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_STAR_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_STAR_H_DEPENDANT +#define __CORE_STAR_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __STAR_REV + #define __STAR_REV 0x0000U + #warning "__STAR_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group STAR-MC1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for STAR-MC1 processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED_ADD1[21U]; + __IOM uint32_t SFSR; /*!< Offset: 0x0E4 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x0E8 (R/W) Secure Fault Address Register */ + uint32_t RESERVED3[69U]; + __OM uint32_t STIR; /*!< Offset: F00-D00=0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ +} SCB_Type; + +typedef struct +{ + __IOM uint32_t CACR; /*!< Offset: 0x0 (R/W) L1 Cache Control Register */ + __IOM uint32_t ITCMCR; /*!< Offset: 0x10 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x14 (R/W) Data Tightly-Coupled Memory Control Registers */ +}EMSS_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +#define SCB_CLIDR_IC_Pos 0U /*!< SCB CLIDR: IC Position */ +#define SCB_CLIDR_IC_Msk (1UL << SCB_CLIDR_IC_Pos) /*!< SCB CLIDR: IC Mask */ + +#define SCB_CLIDR_DC_Pos 1U /*!< SCB CLIDR: DC Position */ +#define SCB_CLIDR_DC_Msk (1UL << SCB_CLIDR_DC_Pos) /*!< SCB CLIDR: DC Mask */ + + + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache line Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_LEVEL_Pos 1U /*!< SCB DCISW: Level Position */ +#define SCB_DCISW_LEVEL_Msk (7UL << SCB_DCISW_LEVEL_Pos) /*!< SCB DCISW: Level Mask */ + +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0xFFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean line by Set-way Register Definitions */ +#define SCB_DCCSW_LEVEL_Pos 1U /*!< SCB DCCSW: Level Position */ +#define SCB_DCCSW_LEVEL_Msk (7UL << SCB_DCCSW_LEVEL_Pos) /*!< SCB DCCSW: Level Mask */ + +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0xFFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_LEVEL_Pos 1U /*!< SCB DCCISW: Level Position */ +#define SCB_DCCISW_LEVEL_Msk (7UL << SCB_DCCISW_LEVEL_Pos) /*!< SCB DCCISW: Level Mask */ + +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0xFFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* ArmChina: Implementation Defined */ +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_DCCLEAN_Pos 16U /*!< SCB CACR: DCCLEAN Position */ +#define SCB_CACR_DCCLEAN_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: DCCLEAN Mask */ + +#define SCB_CACR_ICACTIVE_Pos 13U /*!< SCB CACR: ICACTIVE Position */ +#define SCB_CACR_ICACTIVE_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: ICACTIVE Mask */ + +#define SCB_CACR_DCACTIVE_Pos 12U /*!< SCB CACR: DCACTIVE Position */ +#define SCB_CACR_DCACTIVE_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: DCACTIVE Mask */ + +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and VFP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and VFP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and VFP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and VFP Feature Register 2 Definitions */ +#define FPU_MVFR2_FPMisc_Pos 4U /*!< MVFR2: FPMisc bits Position */ +#define FPU_MVFR2_FPMisc_Msk (0xFUL << FPU_MVFR2_FPMisc_Pos) /*!< MVFR2: FPMisc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DCB Debug Control Block + \brief Type definitions for the Debug Control Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Control Block Registers (DCB). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} DCB_Type; + +/* DHCSR, Debug Halting Control and Status Register Definitions */ +#define DCB_DHCSR_DBGKEY_Pos 16U /*!< DCB DHCSR: Debug key Position */ +#define DCB_DHCSR_DBGKEY_Msk (0xFFFFUL << DCB_DHCSR_DBGKEY_Pos) /*!< DCB DHCSR: Debug key Mask */ + +#define DCB_DHCSR_S_RESTART_ST_Pos 26U /*!< DCB DHCSR: Restart sticky status Position */ +#define DCB_DHCSR_S_RESTART_ST_Msk (0x1UL << DCB_DHCSR_S_RESTART_ST_Pos) /*!< DCB DHCSR: Restart sticky status Mask */ + +#define DCB_DHCSR_S_RESET_ST_Pos 25U /*!< DCB DHCSR: Reset sticky status Position */ +#define DCB_DHCSR_S_RESET_ST_Msk (0x1UL << DCB_DHCSR_S_RESET_ST_Pos) /*!< DCB DHCSR: Reset sticky status Mask */ + +#define DCB_DHCSR_S_RETIRE_ST_Pos 24U /*!< DCB DHCSR: Retire sticky status Position */ +#define DCB_DHCSR_S_RETIRE_ST_Msk (0x1UL << DCB_DHCSR_S_RETIRE_ST_Pos) /*!< DCB DHCSR: Retire sticky status Mask */ + +#define DCB_DHCSR_S_SDE_Pos 20U /*!< DCB DHCSR: Secure debug enabled Position */ +#define DCB_DHCSR_S_SDE_Msk (0x1UL << DCB_DHCSR_S_SDE_Pos) /*!< DCB DHCSR: Secure debug enabled Mask */ + +#define DCB_DHCSR_S_LOCKUP_Pos 19U /*!< DCB DHCSR: Lockup status Position */ +#define DCB_DHCSR_S_LOCKUP_Msk (0x1UL << DCB_DHCSR_S_LOCKUP_Pos) /*!< DCB DHCSR: Lockup status Mask */ + +#define DCB_DHCSR_S_SLEEP_Pos 18U /*!< DCB DHCSR: Sleeping status Position */ +#define DCB_DHCSR_S_SLEEP_Msk (0x1UL << DCB_DHCSR_S_SLEEP_Pos) /*!< DCB DHCSR: Sleeping status Mask */ + +#define DCB_DHCSR_S_HALT_Pos 17U /*!< DCB DHCSR: Halted status Position */ +#define DCB_DHCSR_S_HALT_Msk (0x1UL << DCB_DHCSR_S_HALT_Pos) /*!< DCB DHCSR: Halted status Mask */ + +#define DCB_DHCSR_S_REGRDY_Pos 16U /*!< DCB DHCSR: Register ready status Position */ +#define DCB_DHCSR_S_REGRDY_Msk (0x1UL << DCB_DHCSR_S_REGRDY_Pos) /*!< DCB DHCSR: Register ready status Mask */ + +#define DCB_DHCSR_C_SNAPSTALL_Pos 5U /*!< DCB DHCSR: Snap stall control Position */ +#define DCB_DHCSR_C_SNAPSTALL_Msk (0x1UL << DCB_DHCSR_C_SNAPSTALL_Pos) /*!< DCB DHCSR: Snap stall control Mask */ + +#define DCB_DHCSR_C_MASKINTS_Pos 3U /*!< DCB DHCSR: Mask interrupts control Position */ +#define DCB_DHCSR_C_MASKINTS_Msk (0x1UL << DCB_DHCSR_C_MASKINTS_Pos) /*!< DCB DHCSR: Mask interrupts control Mask */ + +#define DCB_DHCSR_C_STEP_Pos 2U /*!< DCB DHCSR: Step control Position */ +#define DCB_DHCSR_C_STEP_Msk (0x1UL << DCB_DHCSR_C_STEP_Pos) /*!< DCB DHCSR: Step control Mask */ + +#define DCB_DHCSR_C_HALT_Pos 1U /*!< DCB DHCSR: Halt control Position */ +#define DCB_DHCSR_C_HALT_Msk (0x1UL << DCB_DHCSR_C_HALT_Pos) /*!< DCB DHCSR: Halt control Mask */ + +#define DCB_DHCSR_C_DEBUGEN_Pos 0U /*!< DCB DHCSR: Debug enable control Position */ +#define DCB_DHCSR_C_DEBUGEN_Msk (0x1UL /*<< DCB_DHCSR_C_DEBUGEN_Pos*/) /*!< DCB DHCSR: Debug enable control Mask */ + +/* DCRSR, Debug Core Register Select Register Definitions */ +#define DCB_DCRSR_REGWnR_Pos 16U /*!< DCB DCRSR: Register write/not-read Position */ +#define DCB_DCRSR_REGWnR_Msk (0x1UL << DCB_DCRSR_REGWnR_Pos) /*!< DCB DCRSR: Register write/not-read Mask */ + +#define DCB_DCRSR_REGSEL_Pos 0U /*!< DCB DCRSR: Register selector Position */ +#define DCB_DCRSR_REGSEL_Msk (0x7FUL /*<< DCB_DCRSR_REGSEL_Pos*/) /*!< DCB DCRSR: Register selector Mask */ + +/* DCRDR, Debug Core Register Data Register Definitions */ +#define DCB_DCRDR_DBGTMP_Pos 0U /*!< DCB DCRDR: Data temporary buffer Position */ +#define DCB_DCRDR_DBGTMP_Msk (0xFFFFFFFFUL /*<< DCB_DCRDR_DBGTMP_Pos*/) /*!< DCB DCRDR: Data temporary buffer Mask */ + +/* DEMCR, Debug Exception and Monitor Control Register Definitions */ +#define DCB_DEMCR_TRCENA_Pos 24U /*!< DCB DEMCR: Trace enable Position */ +#define DCB_DEMCR_TRCENA_Msk (0x1UL << DCB_DEMCR_TRCENA_Pos) /*!< DCB DEMCR: Trace enable Mask */ + +#define DCB_DEMCR_MONPRKEY_Pos 23U /*!< DCB DEMCR: Monitor pend req key Position */ +#define DCB_DEMCR_MONPRKEY_Msk (0x1UL << DCB_DEMCR_MONPRKEY_Pos) /*!< DCB DEMCR: Monitor pend req key Mask */ + +#define DCB_DEMCR_UMON_EN_Pos 21U /*!< DCB DEMCR: Unprivileged monitor enable Position */ +#define DCB_DEMCR_UMON_EN_Msk (0x1UL << DCB_DEMCR_UMON_EN_Pos) /*!< DCB DEMCR: Unprivileged monitor enable Mask */ + +#define DCB_DEMCR_SDME_Pos 20U /*!< DCB DEMCR: Secure DebugMonitor enable Position */ +#define DCB_DEMCR_SDME_Msk (0x1UL << DCB_DEMCR_SDME_Pos) /*!< DCB DEMCR: Secure DebugMonitor enable Mask */ + +#define DCB_DEMCR_MON_REQ_Pos 19U /*!< DCB DEMCR: Monitor request Position */ +#define DCB_DEMCR_MON_REQ_Msk (0x1UL << DCB_DEMCR_MON_REQ_Pos) /*!< DCB DEMCR: Monitor request Mask */ + +#define DCB_DEMCR_MON_STEP_Pos 18U /*!< DCB DEMCR: Monitor step Position */ +#define DCB_DEMCR_MON_STEP_Msk (0x1UL << DCB_DEMCR_MON_STEP_Pos) /*!< DCB DEMCR: Monitor step Mask */ + +#define DCB_DEMCR_MON_PEND_Pos 17U /*!< DCB DEMCR: Monitor pend Position */ +#define DCB_DEMCR_MON_PEND_Msk (0x1UL << DCB_DEMCR_MON_PEND_Pos) /*!< DCB DEMCR: Monitor pend Mask */ + +#define DCB_DEMCR_MON_EN_Pos 16U /*!< DCB DEMCR: Monitor enable Position */ +#define DCB_DEMCR_MON_EN_Msk (0x1UL << DCB_DEMCR_MON_EN_Pos) /*!< DCB DEMCR: Monitor enable Mask */ + +#define DCB_DEMCR_VC_SFERR_Pos 11U /*!< DCB DEMCR: Vector Catch SecureFault Position */ +#define DCB_DEMCR_VC_SFERR_Msk (0x1UL << DCB_DEMCR_VC_SFERR_Pos) /*!< DCB DEMCR: Vector Catch SecureFault Mask */ + +#define DCB_DEMCR_VC_HARDERR_Pos 10U /*!< DCB DEMCR: Vector Catch HardFault errors Position */ +#define DCB_DEMCR_VC_HARDERR_Msk (0x1UL << DCB_DEMCR_VC_HARDERR_Pos) /*!< DCB DEMCR: Vector Catch HardFault errors Mask */ + +#define DCB_DEMCR_VC_INTERR_Pos 9U /*!< DCB DEMCR: Vector Catch interrupt errors Position */ +#define DCB_DEMCR_VC_INTERR_Msk (0x1UL << DCB_DEMCR_VC_INTERR_Pos) /*!< DCB DEMCR: Vector Catch interrupt errors Mask */ + +#define DCB_DEMCR_VC_BUSERR_Pos 8U /*!< DCB DEMCR: Vector Catch BusFault errors Position */ +#define DCB_DEMCR_VC_BUSERR_Msk (0x1UL << DCB_DEMCR_VC_BUSERR_Pos) /*!< DCB DEMCR: Vector Catch BusFault errors Mask */ + +#define DCB_DEMCR_VC_STATERR_Pos 7U /*!< DCB DEMCR: Vector Catch state errors Position */ +#define DCB_DEMCR_VC_STATERR_Msk (0x1UL << DCB_DEMCR_VC_STATERR_Pos) /*!< DCB DEMCR: Vector Catch state errors Mask */ + +#define DCB_DEMCR_VC_CHKERR_Pos 6U /*!< DCB DEMCR: Vector Catch check errors Position */ +#define DCB_DEMCR_VC_CHKERR_Msk (0x1UL << DCB_DEMCR_VC_CHKERR_Pos) /*!< DCB DEMCR: Vector Catch check errors Mask */ + +#define DCB_DEMCR_VC_NOCPERR_Pos 5U /*!< DCB DEMCR: Vector Catch NOCP errors Position */ +#define DCB_DEMCR_VC_NOCPERR_Msk (0x1UL << DCB_DEMCR_VC_NOCPERR_Pos) /*!< DCB DEMCR: Vector Catch NOCP errors Mask */ + +#define DCB_DEMCR_VC_MMERR_Pos 4U /*!< DCB DEMCR: Vector Catch MemManage errors Position */ +#define DCB_DEMCR_VC_MMERR_Msk (0x1UL << DCB_DEMCR_VC_MMERR_Pos) /*!< DCB DEMCR: Vector Catch MemManage errors Mask */ + +#define DCB_DEMCR_VC_CORERESET_Pos 0U /*!< DCB DEMCR: Vector Catch Core reset Position */ +#define DCB_DEMCR_VC_CORERESET_Msk (0x1UL /*<< DCB_DEMCR_VC_CORERESET_Pos*/) /*!< DCB DEMCR: Vector Catch Core reset Mask */ + +/* DAUTHCTRL, Debug Authentication Control Register Definitions */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPNIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPNIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure non-invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPNIDENSEL_Msk (0x1UL << DCB_DAUTHCTRL_SPNIDENSEL_Pos) /*!< DCB DAUTHCTRL: Secure non-invasive debug enable select Mask */ + +#define DCB_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Position */ +#define DCB_DAUTHCTRL_INTSPIDEN_Msk (0x1UL << DCB_DAUTHCTRL_INTSPIDEN_Pos) /*!< DCB DAUTHCTRL: Internal Secure invasive debug enable Mask */ + +#define DCB_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< DCB DAUTHCTRL: Secure invasive debug enable select Position */ +#define DCB_DAUTHCTRL_SPIDENSEL_Msk (0x1UL /*<< DCB_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< DCB DAUTHCTRL: Secure invasive debug enable select Mask */ + +/* DSCSR, Debug Security Control and Status Register Definitions */ +#define DCB_DSCSR_CDSKEY_Pos 17U /*!< DCB DSCSR: CDS write-enable key Position */ +#define DCB_DSCSR_CDSKEY_Msk (0x1UL << DCB_DSCSR_CDSKEY_Pos) /*!< DCB DSCSR: CDS write-enable key Mask */ + +#define DCB_DSCSR_CDS_Pos 16U /*!< DCB DSCSR: Current domain Secure Position */ +#define DCB_DSCSR_CDS_Msk (0x1UL << DCB_DSCSR_CDS_Pos) /*!< DCB DSCSR: Current domain Secure Mask */ + +#define DCB_DSCSR_SBRSEL_Pos 1U /*!< DCB DSCSR: Secure banked register select Position */ +#define DCB_DSCSR_SBRSEL_Msk (0x1UL << DCB_DSCSR_SBRSEL_Pos) /*!< DCB DSCSR: Secure banked register select Mask */ + +#define DCB_DSCSR_SBRSELEN_Pos 0U /*!< DCB DSCSR: Secure banked register select enable Position */ +#define DCB_DSCSR_SBRSELEN_Msk (0x1UL /*<< DCB_DSCSR_SBRSELEN_Pos*/) /*!< DCB DSCSR: Secure banked register select enable Mask */ + +/*@} end of group CMSIS_DCB */ + + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DIB Debug Identification Block + \brief Type definitions for the Debug Identification Block Registers + @{ + */ + +/** + \brief Structure type to access the Debug Identification Block Registers (DIB). + */ +typedef struct +{ + __OM uint32_t DLAR; /*!< Offset: 0x000 ( /W) SCS Software Lock Access Register */ + __IM uint32_t DLSR; /*!< Offset: 0x004 (R/ ) SCS Software Lock Status Register */ + __IM uint32_t DAUTHSTATUS; /*!< Offset: 0x008 (R/ ) Debug Authentication Status Register */ + __IM uint32_t DDEVARCH; /*!< Offset: 0x00C (R/ ) SCS Device Architecture Register */ + __IM uint32_t DDEVTYPE; /*!< Offset: 0x010 (R/ ) SCS Device Type Register */ +} DIB_Type; + +/* DLAR, SCS Software Lock Access Register Definitions */ +#define DIB_DLAR_KEY_Pos 0U /*!< DIB DLAR: KEY Position */ +#define DIB_DLAR_KEY_Msk (0xFFFFFFFFUL /*<< DIB_DLAR_KEY_Pos */) /*!< DIB DLAR: KEY Mask */ + +/* DLSR, SCS Software Lock Status Register Definitions */ +#define DIB_DLSR_nTT_Pos 2U /*!< DIB DLSR: Not thirty-two bit Position */ +#define DIB_DLSR_nTT_Msk (0x1UL << DIB_DLSR_nTT_Pos ) /*!< DIB DLSR: Not thirty-two bit Mask */ + +#define DIB_DLSR_SLK_Pos 1U /*!< DIB DLSR: Software Lock status Position */ +#define DIB_DLSR_SLK_Msk (0x1UL << DIB_DLSR_SLK_Pos ) /*!< DIB DLSR: Software Lock status Mask */ + +#define DIB_DLSR_SLI_Pos 0U /*!< DIB DLSR: Software Lock implemented Position */ +#define DIB_DLSR_SLI_Msk (0x1UL /*<< DIB_DLSR_SLI_Pos*/) /*!< DIB DLSR: Software Lock implemented Mask */ + +/* DAUTHSTATUS, Debug Authentication Status Register Definitions */ +#define DIB_DAUTHSTATUS_SNID_Pos 6U /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_SNID_Msk (0x3UL << DIB_DAUTHSTATUS_SNID_Pos ) /*!< DIB DAUTHSTATUS: Secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_SID_Pos 4U /*!< DIB DAUTHSTATUS: Secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_SID_Msk (0x3UL << DIB_DAUTHSTATUS_SID_Pos ) /*!< DIB DAUTHSTATUS: Secure Invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSNID_Pos 2U /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSNID_Msk (0x3UL << DIB_DAUTHSTATUS_NSNID_Pos ) /*!< DIB DAUTHSTATUS: Non-secure Non-invasive Debug Mask */ + +#define DIB_DAUTHSTATUS_NSID_Pos 0U /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Position */ +#define DIB_DAUTHSTATUS_NSID_Msk (0x3UL /*<< DIB_DAUTHSTATUS_NSID_Pos*/) /*!< DIB DAUTHSTATUS: Non-secure Invasive Debug Mask */ + +/* DDEVARCH, SCS Device Architecture Register Definitions */ +#define DIB_DDEVARCH_ARCHITECT_Pos 21U /*!< DIB DDEVARCH: Architect Position */ +#define DIB_DDEVARCH_ARCHITECT_Msk (0x7FFUL << DIB_DDEVARCH_ARCHITECT_Pos ) /*!< DIB DDEVARCH: Architect Mask */ + +#define DIB_DDEVARCH_PRESENT_Pos 20U /*!< DIB DDEVARCH: DEVARCH Present Position */ +#define DIB_DDEVARCH_PRESENT_Msk (0x1FUL << DIB_DDEVARCH_PRESENT_Pos ) /*!< DIB DDEVARCH: DEVARCH Present Mask */ + +#define DIB_DDEVARCH_REVISION_Pos 16U /*!< DIB DDEVARCH: Revision Position */ +#define DIB_DDEVARCH_REVISION_Msk (0xFUL << DIB_DDEVARCH_REVISION_Pos ) /*!< DIB DDEVARCH: Revision Mask */ + +#define DIB_DDEVARCH_ARCHVER_Pos 12U /*!< DIB DDEVARCH: Architecture Version Position */ +#define DIB_DDEVARCH_ARCHVER_Msk (0xFUL << DIB_DDEVARCH_ARCHVER_Pos ) /*!< DIB DDEVARCH: Architecture Version Mask */ + +#define DIB_DDEVARCH_ARCHPART_Pos 0U /*!< DIB DDEVARCH: Architecture Part Position */ +#define DIB_DDEVARCH_ARCHPART_Msk (0xFFFUL /*<< DIB_DDEVARCH_ARCHPART_Pos*/) /*!< DIB DDEVARCH: Architecture Part Mask */ + +/* DDEVTYPE, SCS Device Type Register Definitions */ +#define DIB_DDEVTYPE_SUB_Pos 4U /*!< DIB DDEVTYPE: Sub-type Position */ +#define DIB_DDEVTYPE_SUB_Msk (0xFUL << DIB_DDEVTYPE_SUB_Pos ) /*!< DIB DDEVTYPE: Sub-type Mask */ + +#define DIB_DDEVTYPE_MAJOR_Pos 0U /*!< DIB DDEVTYPE: Major type Position */ +#define DIB_DDEVTYPE_MAJOR_Msk (0xFUL /*<< DIB_DDEVTYPE_MAJOR_Pos*/) /*!< DIB DDEVTYPE: Major type Mask */ + + +/*@} end of group CMSIS_DIB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define DCB_BASE (0xE000EDF0UL) /*!< DCB Base Address */ + #define DIB_BASE (0xE000EFB0UL) /*!< DIB Base Address */ + #define EMSS_BASE (0xE001E000UL) /*!AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses including + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/** + \brief Software Reset + \details Initiates a system reset request to reset the CPU. + */ +__NO_RETURN __STATIC_INLINE void __SW_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses including + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_BFHFNMINS_Msk) | /* Keep BFHFNMINS unchanged. Use this Reset function in case your case need to keep it */ + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | /* Keep priority group unchanged */ + SCB_AIRCR_SYSRESETREQ_Msk ); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + +/* ################################## Debug Control function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DCBFunctions Debug Control Functions + \brief Functions that access the Debug Control Block. + @{ + */ + + +/** + \brief Set Debug Authentication Control Register + \details writes to Debug Authentication Control register. + \param [in] value value to be writen. + */ +__STATIC_INLINE void DCB_SetAuthCtrl(uint32_t value) +{ + __DSB(); + __ISB(); + DCB->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register + \details Reads Debug Authentication Control register. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t DCB_GetAuthCtrl(void) +{ + return (DCB->DAUTHCTRL); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Debug Authentication Control Register (non-secure) + \details writes to non-secure Debug Authentication Control register when in secure state. + \param [in] value value to be writen + */ +__STATIC_INLINE void TZ_DCB_SetAuthCtrl_NS(uint32_t value) +{ + __DSB(); + __ISB(); + DCB_NS->DAUTHCTRL = value; + __DSB(); + __ISB(); +} + + +/** + \brief Get Debug Authentication Control Register (non-secure) + \details Reads non-secure Debug Authentication Control register when in secure state. + \return Debug Authentication Control Register. + */ +__STATIC_INLINE uint32_t TZ_DCB_GetAuthCtrl_NS(void) +{ + return (DCB_NS->DAUTHCTRL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + + + +/* ################################## Debug Identification function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_DIBFunctions Debug Identification Functions + \brief Functions that access the Debug Identification Block. + @{ + */ + + +/** + \brief Get Debug Authentication Status Register + \details Reads Debug Authentication Status register. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t DIB_GetAuthStatus(void) +{ + return (DIB->DAUTHSTATUS); +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Debug Authentication Status Register (non-secure) + \details Reads non-secure Debug Authentication Status register when in secure state. + \return Debug Authentication Status Register. + */ +__STATIC_INLINE uint32_t TZ_DIB_GetAuthStatus_NS(void) +{ + return (DIB_NS->DAUTHSTATUS); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_DCBFunctions */ + + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#define __SCB_DCACHE_LINE_SIZE 32U /*!< STAR-MC1 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#define __SCB_ICACHE_LINE_SIZE 32U /*!< STAR-MC1 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief I-Cache Invalidate by address + \details Invalidates I-Cache for the given address. + I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + I-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] isize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (void *addr, int32_t isize) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if ( isize > 0 ) { + int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_ICACHE_LINE_SIZE; + op_size -= __SCB_ICACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ +#endif + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_STAR_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Drivers/CMSIS/Include/mpu_armv7.h b/Drivers/CMSIS/Include/mpu_armv7.h new file mode 100644 index 0000000..d9eedf8 --- /dev/null +++ b/Drivers/CMSIS/Include/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.2 + * @date 25. May 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rasr Value for RASR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_Load(). +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/Drivers/CMSIS/Include/mpu_armv8.h b/Drivers/CMSIS/Include/mpu_armv8.h new file mode 100644 index 0000000..3de16ef --- /dev/null +++ b/Drivers/CMSIS/Include/mpu_armv8.h @@ -0,0 +1,352 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU + * @version V5.1.3 + * @date 03. February 2021 + ******************************************************************************/ +/* + * Copyright (c) 2017-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + ((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + (((BASE) & MPU_RBAR_BASE_Msk) | \ + (((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + (((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \ + (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#if defined(MPU_RLAR_PXN_Pos) + +/** \brief Region Limit Address Register with PXN value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ + (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \ + (((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ + (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#endif + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DMB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_LoadEx() +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/Drivers/CMSIS/Include/pac_armv81.h b/Drivers/CMSIS/Include/pac_armv81.h new file mode 100644 index 0000000..854b60a --- /dev/null +++ b/Drivers/CMSIS/Include/pac_armv81.h @@ -0,0 +1,206 @@ +/****************************************************************************** + * @file pac_armv81.h + * @brief CMSIS PAC key functions for Armv8.1-M PAC extension + * @version V1.0.0 + * @date 23. March 2022 + ******************************************************************************/ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef PAC_ARMV81_H +#define PAC_ARMV81_H + + +/* ################### PAC Key functions ########################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_PacKeyFunctions PAC Key functions + \brief Functions that access the PAC keys. + @{ + */ + +#if (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) + +/** + \brief read the PAC key used for privileged mode + \details Reads the PAC key stored in the PAC_KEY_P registers. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __get_PAC_KEY_P (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_p_0\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_p_1\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_p_2\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_p_3\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for privileged mode + \details writes the given PAC key to the PAC_KEY_P registers. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __set_PAC_KEY_P (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_p_0, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_p_1, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_p_2, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_p_3, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief read the PAC key used for unprivileged mode + \details Reads the PAC key stored in the PAC_KEY_U registers. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __get_PAC_KEY_U (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_u_0\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_u_1\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_u_2\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_u_3\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for unprivileged mode + \details writes the given PAC key to the PAC_KEY_U registers. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __set_PAC_KEY_U (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_u_0, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_u_1, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_u_2, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_u_3, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) + +/** + \brief read the PAC key used for privileged mode (non-secure) + \details Reads the PAC key stored in the non-secure PAC_KEY_P registers when in secure mode. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_get_PAC_KEY_P_NS (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_p_0_ns\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_p_1_ns\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_p_2_ns\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_p_3_ns\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for privileged mode (non-secure) + \details writes the given PAC key to the non-secure PAC_KEY_P registers when in secure mode. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_set_PAC_KEY_P_NS (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_p_0_ns, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_p_1_ns, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_p_2_ns, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_p_3_ns, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief read the PAC key used for unprivileged mode (non-secure) + \details Reads the PAC key stored in the non-secure PAC_KEY_U registers when in secure mode. + \param [out] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_get_PAC_KEY_U_NS (uint32_t* pPacKey) { + __ASM volatile ( + "mrs r1, pac_key_u_0_ns\n" + "str r1,[%0,#0]\n" + "mrs r1, pac_key_u_1_ns\n" + "str r1,[%0,#4]\n" + "mrs r1, pac_key_u_2_ns\n" + "str r1,[%0,#8]\n" + "mrs r1, pac_key_u_3_ns\n" + "str r1,[%0,#12]\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +/** + \brief write the PAC key used for unprivileged mode (non-secure) + \details writes the given PAC key to the non-secure PAC_KEY_U registers when in secure mode. + \param [in] pPacKey 128bit PAC key + */ +__STATIC_FORCEINLINE void __TZ_set_PAC_KEY_U_NS (uint32_t* pPacKey) { + __ASM volatile ( + "ldr r1,[%0,#0]\n" + "msr pac_key_u_0_ns, r1\n" + "ldr r1,[%0,#4]\n" + "msr pac_key_u_1_ns, r1\n" + "ldr r1,[%0,#8]\n" + "msr pac_key_u_2_ns, r1\n" + "ldr r1,[%0,#12]\n" + "msr pac_key_u_3_ns, r1\n" + : : "r" (pPacKey) : "memory", "r1" + ); +} + +#endif /* (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) */ + +#endif /* (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) */ + +/*@} end of CMSIS_Core_PacKeyFunctions */ + + +#endif /* PAC_ARMV81_H */ diff --git a/Drivers/CMSIS/Include/pmu_armv8.h b/Drivers/CMSIS/Include/pmu_armv8.h new file mode 100644 index 0000000..f8f3d89 --- /dev/null +++ b/Drivers/CMSIS/Include/pmu_armv8.h @@ -0,0 +1,337 @@ +/****************************************************************************** + * @file pmu_armv8.h + * @brief CMSIS PMU API for Armv8.1-M PMU + * @version V1.0.1 + * @date 15. April 2020 + ******************************************************************************/ +/* + * Copyright (c) 2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_PMU_ARMV8_H +#define ARM_PMU_ARMV8_H + +/** + * \brief PMU Events + * \note See the Armv8.1-M Architecture Reference Manual for full details on these PMU events. + * */ + +#define ARM_PMU_SW_INCR 0x0000 /*!< Software update to the PMU_SWINC register, architecturally executed and condition code check pass */ +#define ARM_PMU_L1I_CACHE_REFILL 0x0001 /*!< L1 I-Cache refill */ +#define ARM_PMU_L1D_CACHE_REFILL 0x0003 /*!< L1 D-Cache refill */ +#define ARM_PMU_L1D_CACHE 0x0004 /*!< L1 D-Cache access */ +#define ARM_PMU_LD_RETIRED 0x0006 /*!< Memory-reading instruction architecturally executed and condition code check pass */ +#define ARM_PMU_ST_RETIRED 0x0007 /*!< Memory-writing instruction architecturally executed and condition code check pass */ +#define ARM_PMU_INST_RETIRED 0x0008 /*!< Instruction architecturally executed */ +#define ARM_PMU_EXC_TAKEN 0x0009 /*!< Exception entry */ +#define ARM_PMU_EXC_RETURN 0x000A /*!< Exception return instruction architecturally executed and the condition code check pass */ +#define ARM_PMU_PC_WRITE_RETIRED 0x000C /*!< Software change to the Program Counter (PC). Instruction is architecturally executed and condition code check pass */ +#define ARM_PMU_BR_IMMED_RETIRED 0x000D /*!< Immediate branch architecturally executed */ +#define ARM_PMU_BR_RETURN_RETIRED 0x000E /*!< Function return instruction architecturally executed and the condition code check pass */ +#define ARM_PMU_UNALIGNED_LDST_RETIRED 0x000F /*!< Unaligned memory memory-reading or memory-writing instruction architecturally executed and condition code check pass */ +#define ARM_PMU_BR_MIS_PRED 0x0010 /*!< Mispredicted or not predicted branch speculatively executed */ +#define ARM_PMU_CPU_CYCLES 0x0011 /*!< Cycle */ +#define ARM_PMU_BR_PRED 0x0012 /*!< Predictable branch speculatively executed */ +#define ARM_PMU_MEM_ACCESS 0x0013 /*!< Data memory access */ +#define ARM_PMU_L1I_CACHE 0x0014 /*!< Level 1 instruction cache access */ +#define ARM_PMU_L1D_CACHE_WB 0x0015 /*!< Level 1 data cache write-back */ +#define ARM_PMU_L2D_CACHE 0x0016 /*!< Level 2 data cache access */ +#define ARM_PMU_L2D_CACHE_REFILL 0x0017 /*!< Level 2 data cache refill */ +#define ARM_PMU_L2D_CACHE_WB 0x0018 /*!< Level 2 data cache write-back */ +#define ARM_PMU_BUS_ACCESS 0x0019 /*!< Bus access */ +#define ARM_PMU_MEMORY_ERROR 0x001A /*!< Local memory error */ +#define ARM_PMU_INST_SPEC 0x001B /*!< Instruction speculatively executed */ +#define ARM_PMU_BUS_CYCLES 0x001D /*!< Bus cycles */ +#define ARM_PMU_CHAIN 0x001E /*!< For an odd numbered counter, increment when an overflow occurs on the preceding even-numbered counter on the same PE */ +#define ARM_PMU_L1D_CACHE_ALLOCATE 0x001F /*!< Level 1 data cache allocation without refill */ +#define ARM_PMU_L2D_CACHE_ALLOCATE 0x0020 /*!< Level 2 data cache allocation without refill */ +#define ARM_PMU_BR_RETIRED 0x0021 /*!< Branch instruction architecturally executed */ +#define ARM_PMU_BR_MIS_PRED_RETIRED 0x0022 /*!< Mispredicted branch instruction architecturally executed */ +#define ARM_PMU_STALL_FRONTEND 0x0023 /*!< No operation issued because of the frontend */ +#define ARM_PMU_STALL_BACKEND 0x0024 /*!< No operation issued because of the backend */ +#define ARM_PMU_L2I_CACHE 0x0027 /*!< Level 2 instruction cache access */ +#define ARM_PMU_L2I_CACHE_REFILL 0x0028 /*!< Level 2 instruction cache refill */ +#define ARM_PMU_L3D_CACHE_ALLOCATE 0x0029 /*!< Level 3 data cache allocation without refill */ +#define ARM_PMU_L3D_CACHE_REFILL 0x002A /*!< Level 3 data cache refill */ +#define ARM_PMU_L3D_CACHE 0x002B /*!< Level 3 data cache access */ +#define ARM_PMU_L3D_CACHE_WB 0x002C /*!< Level 3 data cache write-back */ +#define ARM_PMU_LL_CACHE_RD 0x0036 /*!< Last level data cache read */ +#define ARM_PMU_LL_CACHE_MISS_RD 0x0037 /*!< Last level data cache read miss */ +#define ARM_PMU_L1D_CACHE_MISS_RD 0x0039 /*!< Level 1 data cache read miss */ +#define ARM_PMU_OP_COMPLETE 0x003A /*!< Operation retired */ +#define ARM_PMU_OP_SPEC 0x003B /*!< Operation speculatively executed */ +#define ARM_PMU_STALL 0x003C /*!< Stall cycle for instruction or operation not sent for execution */ +#define ARM_PMU_STALL_OP_BACKEND 0x003D /*!< Stall cycle for instruction or operation not sent for execution due to pipeline backend */ +#define ARM_PMU_STALL_OP_FRONTEND 0x003E /*!< Stall cycle for instruction or operation not sent for execution due to pipeline frontend */ +#define ARM_PMU_STALL_OP 0x003F /*!< Instruction or operation slots not occupied each cycle */ +#define ARM_PMU_L1D_CACHE_RD 0x0040 /*!< Level 1 data cache read */ +#define ARM_PMU_LE_RETIRED 0x0100 /*!< Loop end instruction executed */ +#define ARM_PMU_LE_SPEC 0x0101 /*!< Loop end instruction speculatively executed */ +#define ARM_PMU_BF_RETIRED 0x0104 /*!< Branch future instruction architecturally executed and condition code check pass */ +#define ARM_PMU_BF_SPEC 0x0105 /*!< Branch future instruction speculatively executed and condition code check pass */ +#define ARM_PMU_LE_CANCEL 0x0108 /*!< Loop end instruction not taken */ +#define ARM_PMU_BF_CANCEL 0x0109 /*!< Branch future instruction not taken */ +#define ARM_PMU_SE_CALL_S 0x0114 /*!< Call to secure function, resulting in Security state change */ +#define ARM_PMU_SE_CALL_NS 0x0115 /*!< Call to non-secure function, resulting in Security state change */ +#define ARM_PMU_DWT_CMPMATCH0 0x0118 /*!< DWT comparator 0 match */ +#define ARM_PMU_DWT_CMPMATCH1 0x0119 /*!< DWT comparator 1 match */ +#define ARM_PMU_DWT_CMPMATCH2 0x011A /*!< DWT comparator 2 match */ +#define ARM_PMU_DWT_CMPMATCH3 0x011B /*!< DWT comparator 3 match */ +#define ARM_PMU_MVE_INST_RETIRED 0x0200 /*!< MVE instruction architecturally executed */ +#define ARM_PMU_MVE_INST_SPEC 0x0201 /*!< MVE instruction speculatively executed */ +#define ARM_PMU_MVE_FP_RETIRED 0x0204 /*!< MVE floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_SPEC 0x0205 /*!< MVE floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_HP_RETIRED 0x0208 /*!< MVE half-precision floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_HP_SPEC 0x0209 /*!< MVE half-precision floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_SP_RETIRED 0x020C /*!< MVE single-precision floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_SP_SPEC 0x020D /*!< MVE single-precision floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_MAC_RETIRED 0x0214 /*!< MVE floating-point multiply or multiply-accumulate instruction architecturally executed */ +#define ARM_PMU_MVE_FP_MAC_SPEC 0x0215 /*!< MVE floating-point multiply or multiply-accumulate instruction speculatively executed */ +#define ARM_PMU_MVE_INT_RETIRED 0x0224 /*!< MVE integer instruction architecturally executed */ +#define ARM_PMU_MVE_INT_SPEC 0x0225 /*!< MVE integer instruction speculatively executed */ +#define ARM_PMU_MVE_INT_MAC_RETIRED 0x0228 /*!< MVE multiply or multiply-accumulate instruction architecturally executed */ +#define ARM_PMU_MVE_INT_MAC_SPEC 0x0229 /*!< MVE multiply or multiply-accumulate instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_RETIRED 0x0238 /*!< MVE load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_SPEC 0x0239 /*!< MVE load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_RETIRED 0x023C /*!< MVE load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_SPEC 0x023D /*!< MVE load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_RETIRED 0x0240 /*!< MVE store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_SPEC 0x0241 /*!< MVE store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_CONTIG_RETIRED 0x0244 /*!< MVE contiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_CONTIG_SPEC 0x0245 /*!< MVE contiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_CONTIG_RETIRED 0x0248 /*!< MVE contiguous load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_CONTIG_SPEC 0x0249 /*!< MVE contiguous load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_CONTIG_RETIRED 0x024C /*!< MVE contiguous store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_CONTIG_SPEC 0x024D /*!< MVE contiguous store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_NONCONTIG_RETIRED 0x0250 /*!< MVE non-contiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_NONCONTIG_SPEC 0x0251 /*!< MVE non-contiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_NONCONTIG_RETIRED 0x0254 /*!< MVE non-contiguous load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_NONCONTIG_SPEC 0x0255 /*!< MVE non-contiguous load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_NONCONTIG_RETIRED 0x0258 /*!< MVE non-contiguous store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_NONCONTIG_SPEC 0x0259 /*!< MVE non-contiguous store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_MULTI_RETIRED 0x025C /*!< MVE memory instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_LDST_MULTI_SPEC 0x025D /*!< MVE memory instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_LD_MULTI_RETIRED 0x0260 /*!< MVE memory load instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_LD_MULTI_SPEC 0x0261 /*!< MVE memory load instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_ST_MULTI_RETIRED 0x0261 /*!< MVE memory store instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_ST_MULTI_SPEC 0x0265 /*!< MVE memory store instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_RETIRED 0x028C /*!< MVE unaligned memory load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_SPEC 0x028D /*!< MVE unaligned memory load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_UNALIGNED_RETIRED 0x0290 /*!< MVE unaligned load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_UNALIGNED_SPEC 0x0291 /*!< MVE unaligned load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_UNALIGNED_RETIRED 0x0294 /*!< MVE unaligned store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_UNALIGNED_SPEC 0x0295 /*!< MVE unaligned store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_RETIRED 0x0298 /*!< MVE unaligned noncontiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_SPEC 0x0299 /*!< MVE unaligned noncontiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_RETIRED 0x02A0 /*!< MVE vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_SPEC 0x02A1 /*!< MVE vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_FP_RETIRED 0x02A4 /*!< MVE floating-point vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_FP_SPEC 0x02A5 /*!< MVE floating-point vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_INT_RETIRED 0x02A8 /*!< MVE integer vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_INT_SPEC 0x02A9 /*!< MVE integer vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_PRED 0x02B8 /*!< Cycles where one or more predicated beats architecturally executed */ +#define ARM_PMU_MVE_STALL 0x02CC /*!< Stall cycles caused by an MVE instruction */ +#define ARM_PMU_MVE_STALL_RESOURCE 0x02CD /*!< Stall cycles caused by an MVE instruction because of resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_MEM 0x02CE /*!< Stall cycles caused by an MVE instruction because of memory resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_FP 0x02CF /*!< Stall cycles caused by an MVE instruction because of floating-point resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_INT 0x02D0 /*!< Stall cycles caused by an MVE instruction because of integer resource conflicts */ +#define ARM_PMU_MVE_STALL_BREAK 0x02D3 /*!< Stall cycles caused by an MVE chain break */ +#define ARM_PMU_MVE_STALL_DEPENDENCY 0x02D4 /*!< Stall cycles caused by MVE register dependency */ +#define ARM_PMU_ITCM_ACCESS 0x4007 /*!< Instruction TCM access */ +#define ARM_PMU_DTCM_ACCESS 0x4008 /*!< Data TCM access */ +#define ARM_PMU_TRCEXTOUT0 0x4010 /*!< ETM external output 0 */ +#define ARM_PMU_TRCEXTOUT1 0x4011 /*!< ETM external output 1 */ +#define ARM_PMU_TRCEXTOUT2 0x4012 /*!< ETM external output 2 */ +#define ARM_PMU_TRCEXTOUT3 0x4013 /*!< ETM external output 3 */ +#define ARM_PMU_CTI_TRIGOUT4 0x4018 /*!< Cross-trigger Interface output trigger 4 */ +#define ARM_PMU_CTI_TRIGOUT5 0x4019 /*!< Cross-trigger Interface output trigger 5 */ +#define ARM_PMU_CTI_TRIGOUT6 0x401A /*!< Cross-trigger Interface output trigger 6 */ +#define ARM_PMU_CTI_TRIGOUT7 0x401B /*!< Cross-trigger Interface output trigger 7 */ + +/** \brief PMU Functions */ + +__STATIC_INLINE void ARM_PMU_Enable(void); +__STATIC_INLINE void ARM_PMU_Disable(void); + +__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type); + +__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void); +__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void); + +__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask); +__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask); + +__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void); +__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num); + +__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void); +__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask); + +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask); +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask); + +__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask); + +/** + \brief Enable the PMU +*/ +__STATIC_INLINE void ARM_PMU_Enable(void) +{ + PMU->CTRL |= PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Disable the PMU +*/ +__STATIC_INLINE void ARM_PMU_Disable(void) +{ + PMU->CTRL &= ~PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Set event to count for PMU eventer counter + \param [in] num Event counter (0-30) to configure + \param [in] type Event to count +*/ +__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type) +{ + PMU->EVTYPER[num] = type; +} + +/** + \brief Reset cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void) +{ + PMU->CTRL |= PMU_CTRL_CYCCNT_RESET_Msk; +} + +/** + \brief Reset all event counters +*/ +__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void) +{ + PMU->CTRL |= PMU_CTRL_EVENTCNT_RESET_Msk; +} + +/** + \brief Enable counters + \param [in] mask Counters to enable + \note Enables one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask) +{ + PMU->CNTENSET = mask; +} + +/** + \brief Disable counters + \param [in] mask Counters to enable + \note Disables one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask) +{ + PMU->CNTENCLR = mask; +} + +/** + \brief Read cycle counter + \return Cycle count +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void) +{ + return PMU->CCNTR; +} + +/** + \brief Read event counter + \param [in] num Event counter (0-30) to read + \return Event count +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num) +{ + return PMU_EVCNTR_CNT_Msk & PMU->EVCNTR[num]; +} + +/** + \brief Read counter overflow status + \return Counter overflow status bits for the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void) +{ + return PMU->OVSSET; +} + +/** + \brief Clear counter overflow status + \param [in] mask Counter overflow status bits to clear + \note Clears overflow status bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask) +{ + PMU->OVSCLR = mask; +} + +/** + \brief Enable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to set + \note Sets overflow interrupt request bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask) +{ + PMU->INTENSET = mask; +} + +/** + \brief Disable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to clear + \note Clears overflow interrupt request bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask) +{ + PMU->INTENCLR = mask; +} + +/** + \brief Software increment event counter + \param [in] mask Counters to increment + \note Software increment bits for one or more event counters (0-30) +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask) +{ + PMU->SWINC = mask; +} + +#endif diff --git a/Drivers/CMSIS/Include/tz_context.h b/Drivers/CMSIS/Include/tz_context.h new file mode 100644 index 0000000..0d09749 --- /dev/null +++ b/Drivers/CMSIS/Include/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/Drivers/CMSIS/LICENSE.txt b/Drivers/CMSIS/LICENSE.txt new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/Drivers/CMSIS/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/Drivers/CMSIS/RTOS/Template/cmsis_os.h b/Drivers/CMSIS/RTOS/Template/cmsis_os.h new file mode 100644 index 0000000..85e24a4 --- /dev/null +++ b/Drivers/CMSIS/RTOS/Template/cmsis_os.h @@ -0,0 +1,698 @@ +/* ---------------------------------------------------------------------- + * $Date: 5. February 2013 + * $Revision: V1.02 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h template header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + *---------------------------------------------------------------------------- + * + * Copyright (c) 2013-2017 ARM LIMITED + * + * SPDX-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 + * + * 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. + *---------------------------------------------------------------------------*/ + + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value. +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value. +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + +#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter +/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS. +/// \return RTOS kernel system timer as 32-bit value +uint32_t osKernelSysTick (void); + +/// The RTOS kernel system timer frequency in Hz +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#define osKernelSysTickFrequency 100000000 + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) + +#endif // System Timer available + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = \ +{ (function) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = { 0 } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = { 0 } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), sizeof (type) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof (type) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H diff --git a/Drivers/CMSIS/RTOS2/Include/cmsis_os2.h b/Drivers/CMSIS/RTOS2/Include/cmsis_os2.h new file mode 100644 index 0000000..76612e2 --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Include/cmsis_os2.h @@ -0,0 +1,756 @@ +/* + * Copyright (c) 2013-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 12. June 2020 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS2 API + * Title: cmsis_os2.h header file + * + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.0.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS2_H_ +#define CMSIS_OS2_H_ + +#ifndef __NO_RETURN +#if defined(__CC_ARM) +#define __NO_RETURN __declspec(noreturn) +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__GNUC__) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__ICCARM__) +#define __NO_RETURN __noreturn +#else +#define __NO_RETURN +#endif +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Version information. +typedef struct { + uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). + uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). +} osVersion_t; + +/// Kernel state. +typedef enum { + osKernelInactive = 0, ///< Inactive. + osKernelReady = 1, ///< Ready. + osKernelRunning = 2, ///< Running. + osKernelLocked = 3, ///< Locked. + osKernelSuspended = 4, ///< Suspended. + osKernelError = -1, ///< Error. + osKernelReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osKernelState_t; + +/// Thread state. +typedef enum { + osThreadInactive = 0, ///< Inactive. + osThreadReady = 1, ///< Ready. + osThreadRunning = 2, ///< Running. + osThreadBlocked = 3, ///< Blocked. + osThreadTerminated = 4, ///< Terminated. + osThreadError = -1, ///< Error. + osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osThreadState_t; + +/// Priority values. +typedef enum { + osPriorityNone = 0, ///< No priority (not initialized). + osPriorityIdle = 1, ///< Reserved for Idle thread. + osPriorityLow = 8, ///< Priority: low + osPriorityLow1 = 8+1, ///< Priority: low + 1 + osPriorityLow2 = 8+2, ///< Priority: low + 2 + osPriorityLow3 = 8+3, ///< Priority: low + 3 + osPriorityLow4 = 8+4, ///< Priority: low + 4 + osPriorityLow5 = 8+5, ///< Priority: low + 5 + osPriorityLow6 = 8+6, ///< Priority: low + 6 + osPriorityLow7 = 8+7, ///< Priority: low + 7 + osPriorityBelowNormal = 16, ///< Priority: below normal + osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 + osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 + osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 + osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 + osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 + osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 + osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 + osPriorityNormal = 24, ///< Priority: normal + osPriorityNormal1 = 24+1, ///< Priority: normal + 1 + osPriorityNormal2 = 24+2, ///< Priority: normal + 2 + osPriorityNormal3 = 24+3, ///< Priority: normal + 3 + osPriorityNormal4 = 24+4, ///< Priority: normal + 4 + osPriorityNormal5 = 24+5, ///< Priority: normal + 5 + osPriorityNormal6 = 24+6, ///< Priority: normal + 6 + osPriorityNormal7 = 24+7, ///< Priority: normal + 7 + osPriorityAboveNormal = 32, ///< Priority: above normal + osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 + osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 + osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 + osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 + osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 + osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 + osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 + osPriorityHigh = 40, ///< Priority: high + osPriorityHigh1 = 40+1, ///< Priority: high + 1 + osPriorityHigh2 = 40+2, ///< Priority: high + 2 + osPriorityHigh3 = 40+3, ///< Priority: high + 3 + osPriorityHigh4 = 40+4, ///< Priority: high + 4 + osPriorityHigh5 = 40+5, ///< Priority: high + 5 + osPriorityHigh6 = 40+6, ///< Priority: high + 6 + osPriorityHigh7 = 40+7, ///< Priority: high + 7 + osPriorityRealtime = 48, ///< Priority: realtime + osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 + osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 + osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 + osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 + osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 + osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 + osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 + osPriorityISR = 56, ///< Reserved for ISR deferred thread. + osPriorityError = -1, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority_t; + +/// Entry point of a thread. +typedef void (*osThreadFunc_t) (void *argument); + +/// Timer callback function. +typedef void (*osTimerFunc_t) (void *argument); + +/// Timer type. +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} osTimerType_t; + +// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). +#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. +#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. + +// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +#define osFlagsError 0x80000000U ///< Error indicator. +#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). +#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). +#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). +#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). +#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). + +// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode + +// Mutex attributes (attr_bits in \ref osMutexAttr_t). +#define osMutexRecursive 0x00000001U ///< Recursive mutex. +#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. +#define osMutexRobust 0x00000008U ///< Robust mutex. + +/// Status code values returned by CMSIS-RTOS functions. +typedef enum { + osOK = 0, ///< Operation completed successfully. + osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + osErrorTimeout = -2, ///< Operation not completed within the timeout period. + osErrorResource = -3, ///< Resource not available. + osErrorParameter = -4, ///< Parameter error. + osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus_t; + + +/// \details Thread ID identifies the thread. +typedef void *osThreadId_t; + +/// \details Timer ID identifies the timer. +typedef void *osTimerId_t; + +/// \details Event Flags ID identifies the event flags. +typedef void *osEventFlagsId_t; + +/// \details Mutex ID identifies the mutex. +typedef void *osMutexId_t; + +/// \details Semaphore ID identifies the semaphore. +typedef void *osSemaphoreId_t; + +/// \details Memory Pool ID identifies the memory pool. +typedef void *osMemoryPoolId_t; + +/// \details Message Queue ID identifies the message queue. +typedef void *osMessageQueueId_t; + + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + + +/// Attributes structure for thread. +typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) +} osThreadAttr_t; + +/// Attributes structure for timer. +typedef struct { + const char *name; ///< name of the timer + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osTimerAttr_t; + +/// Attributes structure for event flags. +typedef struct { + const char *name; ///< name of the event flags + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osEventFlagsAttr_t; + +/// Attributes structure for mutex. +typedef struct { + const char *name; ///< name of the mutex + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osMutexAttr_t; + +/// Attributes structure for semaphore. +typedef struct { + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osSemaphoreAttr_t; + +/// Attributes structure for memory pool. +typedef struct { + const char *name; ///< name of the memory pool + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mp_mem; ///< memory for data storage + uint32_t mp_size; ///< size of provided memory for data storage +} osMemoryPoolAttr_t; + +/// Attributes structure for message queue. +typedef struct { + const char *name; ///< name of the message queue + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mq_mem; ///< memory for data storage + uint32_t mq_size; ///< size of provided memory for data storage +} osMessageQueueAttr_t; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelInitialize (void); + +/// Get RTOS Kernel Information. +/// \param[out] version pointer to buffer for retrieving version information. +/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. +/// \param[in] id_size size of buffer for kernel identification string. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); + +/// Get the current RTOS Kernel state. +/// \return current RTOS Kernel state. +osKernelState_t osKernelGetState (void); + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelStart (void); + +/// Lock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelLock (void); + +/// Unlock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelUnlock (void); + +/// Restore the RTOS Kernel scheduler lock state. +/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +/// \return new lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelRestoreLock (int32_t lock); + +/// Suspend the RTOS Kernel scheduler. +/// \return time in ticks, for how long the system can sleep or power-down. +uint32_t osKernelSuspend (void); + +/// Resume the RTOS Kernel scheduler. +/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. +void osKernelResume (uint32_t sleep_ticks); + +/// Get the RTOS kernel tick count. +/// \return RTOS kernel current tick count. +uint32_t osKernelGetTickCount (void); + +/// Get the RTOS kernel tick frequency. +/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. +uint32_t osKernelGetTickFreq (void); + +/// Get the RTOS kernel system timer count. +/// \return RTOS kernel current system timer count as 32-bit value. +uint32_t osKernelGetSysTimerCount (void); + +/// Get the RTOS kernel system timer frequency. +/// \return frequency of the system timer in hertz, i.e. timer ticks per second. +uint32_t osKernelGetSysTimerFreq (void); + + +// ==== Thread Management Functions ==== + +/// Create a thread and add it to Active Threads. +/// \param[in] func thread function. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \param[in] attr thread attributes; NULL: default values. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + +/// Get name of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return name as null-terminated string. +const char *osThreadGetName (osThreadId_t thread_id); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadGetId (void); + +/// Get current thread state of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current thread state of the specified thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id); + +/// Get stack size of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return stack size in bytes. +uint32_t osThreadGetStackSize (osThreadId_t thread_id); + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return remaining stack space in bytes. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id); + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current priority value of the specified thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadYield (void); + +/// Suspend execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSuspend (osThreadId_t thread_id); + +/// Resume execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadResume (osThreadId_t thread_id); + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadDetach (osThreadId_t thread_id); + +/// Wait for specified thread to terminate. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadJoin (osThreadId_t thread_id); + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void); + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadTerminate (osThreadId_t thread_id); + +/// Get number of active threads. +/// \return number of active threads. +uint32_t osThreadGetCount (void); + +/// Enumerate active threads. +/// \param[out] thread_array pointer to array for retrieving thread IDs. +/// \param[in] array_items maximum number of items in array for retrieving thread IDs. +/// \return number of enumerated threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); + + +// ==== Thread Flags Functions ==== + +/// Set the specified Thread Flags of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] flags specifies the flags of the thread that shall be set. +/// \return thread flags after setting or error code if highest bit set. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); + +/// Clear the specified Thread Flags of current running thread. +/// \param[in] flags specifies the flags of the thread that shall be cleared. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsClear (uint32_t flags); + +/// Get the current Thread Flags of current running thread. +/// \return current thread flags. +uint32_t osThreadFlagsGet (void); + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +/// \return status code that indicates the execution status of the function. +osStatus_t osDelay (uint32_t ticks); + +/// Wait until specified time. +/// \param[in] ticks absolute time in ticks +/// \return status code that indicates the execution status of the function. +osStatus_t osDelayUntil (uint32_t ticks); + + +// ==== Timer Management Functions ==== + +/// Create and Initialize a timer. +/// \param[in] func function pointer to callback function. +/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer callback function. +/// \param[in] attr timer attributes; NULL: default values. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); + +/// Get name of a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return name as null-terminated string. +const char *osTimerGetName (osTimerId_t timer_id); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStop (osTimerId_t timer_id); + +/// Check if a timer is running. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return 0 not running, 1 running. +uint32_t osTimerIsRunning (osTimerId_t timer_id); + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerDelete (osTimerId_t timer_id); + + +// ==== Event Flags Management Functions ==== + +/// Create and Initialize an Event Flags object. +/// \param[in] attr event flags attributes; NULL: default values. +/// \return event flags ID for reference by other functions or NULL in case of error. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); + +/// Get name of an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return name as null-terminated string. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id); + +/// Set the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be set. +/// \return event flags after setting or error code if highest bit set. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); + +/// Clear the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be cleared. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); + +/// Get the current Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return current event flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); + +/// Wait for one or more Event Flags to become signaled. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); + +/// Delete an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); + + +// ==== Mutex Management Functions ==== + +/// Create and Initialize a Mutex object. +/// \param[in] attr mutex attributes; NULL: default values. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId_t osMutexNew (const osMutexAttr_t *attr); + +/// Get name of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return name as null-terminated string. +const char *osMutexGetName (osMutexId_t mutex_id); + +/// Acquire a Mutex or timeout if it is locked. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexRelease (osMutexId_t mutex_id); + +/// Get Thread which owns a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return thread ID of owner thread or NULL when mutex was not acquired. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexDelete (osMutexId_t mutex_id); + + +// ==== Semaphore Management Functions ==== + +/// Create and Initialize a Semaphore object. +/// \param[in] max_count maximum number of available tokens. +/// \param[in] initial_count initial number of available tokens. +/// \param[in] attr semaphore attributes; NULL: default values. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); + +/// Get name of a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return name as null-terminated string. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); + +/// Release a Semaphore token up to the initial maximum count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); + +/// Get current Semaphore token count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return number of tokens available. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); + + +// ==== Memory Pool Management Functions ==== + +/// Create and Initialize a Memory Pool object. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size memory block size in bytes. +/// \param[in] attr memory pool attributes; NULL: default values. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); + +/// Get name of a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return name as null-terminated string. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); + +/// Get maximum number of memory blocks in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return maximum number of memory blocks. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); + +/// Get memory block size in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return memory block size in bytes. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks used in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks used. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks available in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks available. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); + +/// Delete a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); + + +// ==== Message Queue Management Functions ==== + +/// Create and Initialize a Message Queue object. +/// \param[in] msg_count maximum number of messages in queue. +/// \param[in] msg_size maximum message size in bytes. +/// \param[in] attr message queue attributes; NULL: default values. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); + +/// Get name of a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return name as null-terminated string. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id); + +/// Put a Message into a Queue or timeout if Queue is full. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[in] msg_ptr pointer to buffer with message to put into a queue. +/// \param[in] msg_prio message priority. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[out] msg_ptr pointer to buffer for message to get from a queue. +/// \param[out] msg_prio pointer to buffer for message priority or NULL. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); + +/// Get maximum number of messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum number of messages. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); + +/// Get maximum message size in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum message size in bytes. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); + +/// Get number of queued messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of queued messages. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); + +/// Get number of available slots for messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of available slots for messages. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); + +/// Reset a Message Queue to initial empty state. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); + +/// Delete a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS2_H_ diff --git a/Drivers/CMSIS/RTOS2/Include/os_tick.h b/Drivers/CMSIS/RTOS2/Include/os_tick.h new file mode 100644 index 0000000..3cfd895 --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Include/os_tick.h @@ -0,0 +1,80 @@ +/**************************************************************************//** + * @file os_tick.h + * @brief CMSIS OS Tick header file + * @version V1.0.2 + * @date 19. March 2021 + ******************************************************************************/ +/* + * Copyright (c) 2017-2021 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#ifndef OS_TICK_H +#define OS_TICK_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/// IRQ Handler. +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +typedef void (*IRQHandler_t) (void); +#endif + +/// Setup OS Tick timer to generate periodic RTOS Kernel Ticks +/// \param[in] freq tick frequency in Hz +/// \param[in] handler tick IRQ handler +/// \return 0 on success, -1 on error. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler); + +/// Enable OS Tick timer interrupt +void OS_Tick_Enable (void); + +/// Disable OS Tick timer interrupt +void OS_Tick_Disable (void); + +/// Acknowledge execution of OS Tick timer interrupt +void OS_Tick_AcknowledgeIRQ (void); + +/// Get OS Tick timer IRQ number +/// \return OS Tick IRQ number +int32_t OS_Tick_GetIRQn (void); + +/// Get OS Tick timer clock frequency +/// \return OS Tick timer clock frequency in Hz +uint32_t OS_Tick_GetClock (void); + +/// Get OS Tick timer interval reload value +/// \return OS Tick timer interval reload value +uint32_t OS_Tick_GetInterval (void); + +/// Get OS Tick timer counter value +/// \return OS Tick timer counter value +uint32_t OS_Tick_GetCount (void); + +/// Get OS Tick timer overflow status +/// \return OS Tick overflow status (1 - overflow, 0 - no overflow). +uint32_t OS_Tick_GetOverflow (void); + +#ifdef __cplusplus +} +#endif + +#endif /* OS_TICK_H */ diff --git a/Drivers/CMSIS/RTOS2/Source/os_systick.c b/Drivers/CMSIS/RTOS2/Source/os_systick.c new file mode 100644 index 0000000..ad13bec --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Source/os_systick.c @@ -0,0 +1,133 @@ +/**************************************************************************//** + * @file os_systick.c + * @brief CMSIS OS Tick SysTick implementation + * @version V1.0.3 + * @date 19. March 2021 + ******************************************************************************/ +/* + * Copyright (c) 2017-2021 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#include "os_tick.h" + +//lint -emacro((923,9078),SCB,SysTick) "cast from unsigned long to pointer" +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifdef SysTick + +#ifndef SYSTICK_IRQ_PRIORITY +#define SYSTICK_IRQ_PRIORITY 0xFFU +#endif + +static uint8_t PendST __attribute__((section(".bss.os"))); + +// Setup OS Tick. +__WEAK int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t load; + (void)handler; + + if (freq == 0U) { + //lint -e{904} "Return statement before end of function" + return (-1); + } + + load = (SystemCoreClock / freq) - 1U; + if (load > 0x00FFFFFFU) { + //lint -e{904} "Return statement before end of function" + return (-1); + } + + // Set SysTick Interrupt Priority +#if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)) || \ + (defined(__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ != 0)) || \ + (defined(__CORTEX_M) && (__CORTEX_M == 7U))) + SCB->SHPR[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) + SCB->SHPR[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); +#elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ + (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0))) + SCB->SHP[11] = SYSTICK_IRQ_PRIORITY; +#elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) + SCB->SHP[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); +#else +#error "Unknown ARM Core!" +#endif + + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; + SysTick->LOAD = load; + SysTick->VAL = 0U; + + PendST = 0U; + + return (0); +} + +/// Enable OS Tick. +__WEAK void OS_Tick_Enable (void) { + + if (PendST != 0U) { + PendST = 0U; + SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; + } + + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +/// Disable OS Tick. +__WEAK void OS_Tick_Disable (void) { + + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + + if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) { + SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; + PendST = 1U; + } +} + +// Acknowledge OS Tick IRQ. +__WEAK void OS_Tick_AcknowledgeIRQ (void) { + (void)SysTick->CTRL; +} + +// Get OS Tick IRQ number. +__WEAK int32_t OS_Tick_GetIRQn (void) { + return ((int32_t)SysTick_IRQn); +} + +// Get OS Tick clock. +__WEAK uint32_t OS_Tick_GetClock (void) { + return (SystemCoreClock); +} + +// Get OS Tick interval. +__WEAK uint32_t OS_Tick_GetInterval (void) { + return (SysTick->LOAD + 1U); +} + +// Get OS Tick count value. +__WEAK uint32_t OS_Tick_GetCount (void) { + uint32_t load = SysTick->LOAD; + return (load - SysTick->VAL); +} + +// Get OS Tick overflow status. +__WEAK uint32_t OS_Tick_GetOverflow (void) { + return ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) >> SCB_ICSR_PENDSTSET_Pos); +} + +#endif // SysTick diff --git a/Drivers/CMSIS/RTOS2/Source/os_tick_gtim.c b/Drivers/CMSIS/RTOS2/Source/os_tick_gtim.c new file mode 100644 index 0000000..1778ab7 --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Source/os_tick_gtim.c @@ -0,0 +1,187 @@ +/**************************************************************************//** + * @file os_tick_gtim.c + * @brief CMSIS OS Tick implementation for Generic Timer + * @version V1.0.1 + * @date 24. November 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#include "os_tick.h" +#include "irq_ctrl.h" + +#include "RTE_Components.h" +#include CMSIS_device_header + +#ifndef GTIM_IRQ_PRIORITY +#define GTIM_IRQ_PRIORITY 0xFFU +#endif + +#ifndef GTIM_IRQ_NUM +#define GTIM_IRQ_NUM SecurePhyTimer_IRQn +#endif + +// Timer interrupt pending flag +static uint8_t GTIM_PendIRQ; + +// Timer tick frequency +static uint32_t GTIM_Clock; + +// Timer load value +static uint32_t GTIM_Load; + +// Setup OS Tick. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t prio, bits; + + if (freq == 0U) { + return (-1); + } + + GTIM_PendIRQ = 0U; + + // Get timer clock +#ifdef SCTR_BASE + GTIM_Clock = *(uint32_t*)(SCTR_BASE+0x20); +#else + // FVP REFCLK CNTControl 100MHz + GTIM_Clock = 100000000UL; +#endif + + PL1_SetCounterFrequency(GTIM_Clock); + + // Calculate load value + GTIM_Load = (GTIM_Clock / freq) - 1U; + + // Disable Generic Timer and set load value + PL1_SetControl(0U); + PL1_SetLoadValue(GTIM_Load); + + // Disable corresponding IRQ + IRQ_Disable(GTIM_IRQ_NUM); + IRQ_ClearPending(GTIM_IRQ_NUM); + + // Determine number of implemented priority bits + IRQ_SetPriority(GTIM_IRQ_NUM, 0xFFU); + + prio = IRQ_GetPriority(GTIM_IRQ_NUM); + + // At least bits [7:4] must be implemented + if ((prio & 0xF0U) == 0U) { + return (-1); + } + + for (bits = 0; bits < 4; bits++) { + if ((prio & 0x01) != 0) { + break; + } + prio >>= 1; + } + + // Adjust configured priority to the number of implemented priority bits + prio = (GTIM_IRQ_PRIORITY << bits) & 0xFFUL; + + // Set Private Timer interrupt priority + IRQ_SetPriority(GTIM_IRQ_NUM, prio-1U); + + // Set edge-triggered IRQ + IRQ_SetMode(GTIM_IRQ_NUM, IRQ_MODE_TRIG_EDGE); + + // Register tick interrupt handler function + IRQ_SetHandler(GTIM_IRQ_NUM, handler); + + // Enable corresponding interrupt + IRQ_Enable(GTIM_IRQ_NUM); + + // Enable system counter and timer control +#ifdef SCTR_BASE + *(uint32_t*)SCTR_BASE |= 3U; +#endif + + // Enable timer control + PL1_SetControl(1U); + + return (0); +} + +/// Enable OS Tick. +void OS_Tick_Enable (void) { + uint32_t ctrl; + + // Set pending interrupt if flag set + if (GTIM_PendIRQ != 0U) { + GTIM_PendIRQ = 0U; + IRQ_SetPending (GTIM_IRQ_NUM); + } + + // Start the Private Timer + ctrl = PL1_GetControl(); + // Set bit: Timer enable + ctrl |= 1U; + PL1_SetControl(ctrl); +} + +/// Disable OS Tick. +void OS_Tick_Disable (void) { + uint32_t ctrl; + + // Stop the Private Timer + ctrl = PL1_GetControl(); + // Clear bit: Timer enable + ctrl &= ~1U; + PL1_SetControl(ctrl); + + // Remember pending interrupt flag + if (IRQ_GetPending(GTIM_IRQ_NUM) != 0) { + IRQ_ClearPending(GTIM_IRQ_NUM); + GTIM_PendIRQ = 1U; + } +} + +// Acknowledge OS Tick IRQ. +void OS_Tick_AcknowledgeIRQ (void) { + IRQ_ClearPending (GTIM_IRQ_NUM); + PL1_SetLoadValue(GTIM_Load); +} + +// Get OS Tick IRQ number. +int32_t OS_Tick_GetIRQn (void) { + return (GTIM_IRQ_NUM); +} + +// Get OS Tick clock. +uint32_t OS_Tick_GetClock (void) { + return (GTIM_Clock); +} + +// Get OS Tick interval. +uint32_t OS_Tick_GetInterval (void) { + return (GTIM_Load + 1U); +} + +// Get OS Tick count value. +uint32_t OS_Tick_GetCount (void) { + return (GTIM_Load - PL1_GetCurrentValue()); +} + +// Get OS Tick overflow status. +uint32_t OS_Tick_GetOverflow (void) { + CNTP_CTL_Type cntp_ctl; + cntp_ctl.w = PL1_GetControl(); + return (cntp_ctl.b.ISTATUS); +} diff --git a/Drivers/CMSIS/RTOS2/Source/os_tick_ptim.c b/Drivers/CMSIS/RTOS2/Source/os_tick_ptim.c new file mode 100644 index 0000000..ccd9cb6 --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Source/os_tick_ptim.c @@ -0,0 +1,165 @@ +/**************************************************************************//** + * @file os_tick_ptim.c + * @brief CMSIS OS Tick implementation for Private Timer + * @version V1.0.2 + * @date 02. March 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + */ + +#include "RTE_Components.h" +#include CMSIS_device_header + +#if defined(PTIM) + +#include "os_tick.h" +#include "irq_ctrl.h" + +#ifndef PTIM_IRQ_PRIORITY +#define PTIM_IRQ_PRIORITY 0xFFU +#endif + +static uint8_t PTIM_PendIRQ; // Timer interrupt pending flag + +// Setup OS Tick. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { + uint32_t load; + uint32_t prio; + uint32_t bits; + + if (freq == 0U) { + return (-1); + } + + PTIM_PendIRQ = 0U; + + // Private Timer runs with the system frequency + load = (SystemCoreClock / freq) - 1U; + + // Disable Private Timer and set load value + PTIM_SetControl (0U); + PTIM_SetLoadValue (load); + + // Disable corresponding IRQ + IRQ_Disable (PrivTimer_IRQn); + IRQ_ClearPending(PrivTimer_IRQn); + + // Determine number of implemented priority bits + IRQ_SetPriority (PrivTimer_IRQn, 0xFFU); + + prio = IRQ_GetPriority (PrivTimer_IRQn); + + // At least bits [7:4] must be implemented + if ((prio & 0xF0U) == 0U) { + return (-1); + } + + for (bits = 0; bits < 4; bits++) { + if ((prio & 0x01) != 0) { + break; + } + prio >>= 1; + } + + // Adjust configured priority to the number of implemented priority bits + prio = (PTIM_IRQ_PRIORITY << bits) & 0xFFUL; + + // Set Private Timer interrupt priority + IRQ_SetPriority(PrivTimer_IRQn, prio-1U); + + // Set edge-triggered IRQ + IRQ_SetMode(PrivTimer_IRQn, IRQ_MODE_TRIG_EDGE); + + // Register tick interrupt handler function + IRQ_SetHandler(PrivTimer_IRQn, handler); + + // Enable corresponding interrupt + IRQ_Enable (PrivTimer_IRQn); + + // Set bits: IRQ enable and Auto reload + PTIM_SetControl (0x06U); + + return (0); +} + +/// Enable OS Tick. +void OS_Tick_Enable (void) { + uint32_t ctrl; + + // Set pending interrupt if flag set + if (PTIM_PendIRQ != 0U) { + PTIM_PendIRQ = 0U; + IRQ_SetPending (PrivTimer_IRQn); + } + + // Start the Private Timer + ctrl = PTIM_GetControl(); + // Set bit: Timer enable + ctrl |= 1U; + PTIM_SetControl (ctrl); +} + +/// Disable OS Tick. +void OS_Tick_Disable (void) { + uint32_t ctrl; + + // Stop the Private Timer + ctrl = PTIM_GetControl(); + // Clear bit: Timer enable + ctrl &= ~1U; + PTIM_SetControl (ctrl); + + // Remember pending interrupt flag + if (IRQ_GetPending(PrivTimer_IRQn) != 0) { + IRQ_ClearPending (PrivTimer_IRQn); + PTIM_PendIRQ = 1U; + } +} + +// Acknowledge OS Tick IRQ. +void OS_Tick_AcknowledgeIRQ (void) { + PTIM_ClearEventFlag(); +} + +// Get OS Tick IRQ number. +int32_t OS_Tick_GetIRQn (void) { + return (PrivTimer_IRQn); +} + +// Get OS Tick clock. +uint32_t OS_Tick_GetClock (void) { + return (SystemCoreClock); +} + +// Get OS Tick interval. +uint32_t OS_Tick_GetInterval (void) { + return (PTIM_GetLoadValue() + 1U); +} + +// Get OS Tick count value. +uint32_t OS_Tick_GetCount (void) { + uint32_t load = PTIM_GetLoadValue(); + return (load - PTIM_GetCurrentValue()); +} + +// Get OS Tick overflow status. +uint32_t OS_Tick_GetOverflow (void) { + return (PTIM->ISR & 1); +} + +#endif // PTIM diff --git a/Drivers/CMSIS/RTOS2/Template/cmsis_os.h b/Drivers/CMSIS/RTOS2/Template/cmsis_os.h new file mode 100644 index 0000000..5447842 --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Template/cmsis_os.h @@ -0,0 +1,922 @@ +/* + * Copyright (c) 2013-2018 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 18. June 2018 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h template header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedefs + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + * Version 2.0.0 + * OS objects creation without macros (dynamic creation and resource allocation): + * - added: osXxxxNew functions which replace osXxxxCreate + * - added: osXxxxAttr_t structures + * - deprecated: osXxxxCreate functions, osXxxxDef_t structures + * - deprecated: osXxxxDef and osXxxx macros + * osStatus codes simplified and renamed to osStatus_t + * osEvent return structure deprecated + * Kernel: + * - added: osKernelInfo_t and osKernelGetInfo + * - added: osKernelState_t and osKernelGetState (replaces osKernelRunning) + * - added: osKernelLock, osKernelUnlock + * - added: osKernelSuspend, osKernelResume + * - added: osKernelGetTickCount, osKernelGetTickFreq + * - renamed osKernelSysTick to osKernelGetSysTimerCount + * - replaced osKernelSysTickFrequency with osKernelGetSysTimerFreq + * - deprecated osKernelSysTickMicroSec + * Thread: + * - extended number of thread priorities + * - renamed osPrioriry to osPrioriry_t + * - replaced osThreadCreate with osThreadNew + * - added: osThreadGetName + * - added: osThreadState_t and osThreadGetState + * - added: osThreadGetStackSize, osThreadGetStackSpace + * - added: osThreadSuspend, osThreadResume + * - added: osThreadJoin, osThreadDetach, osThreadExit + * - added: osThreadGetCount, osThreadEnumerate + * - added: Thread Flags (moved from Signals) + * Signals: + * - renamed osSignals to osThreadFlags (moved to Thread Flags) + * - changed return value of Set/Clear/Wait functions + * - Clear function limited to current running thread + * - extended Wait function (options) + * - added: osThreadFlagsGet + * Event Flags: + * - added new independent object for handling Event Flags + * Delay and Wait functions: + * - added: osDelayUntil + * - deprecated: osWait + * Timer: + * - replaced osTimerCreate with osTimerNew + * - added: osTimerGetName, osTimerIsRunning + * Mutex: + * - extended: attributes (Recursive, Priority Inherit, Robust) + * - replaced osMutexCreate with osMutexNew + * - renamed osMutexWait to osMutexAcquire + * - added: osMutexGetName, osMutexGetOwner + * Semaphore: + * - extended: maximum and initial token count + * - replaced osSemaphoreCreate with osSemaphoreNew + * - renamed osSemaphoreWait to osSemaphoreAcquire (changed return value) + * - added: osSemaphoreGetName, osSemaphoreGetCount + * Memory Pool: + * - using osMemoryPool prefix instead of osPool + * - replaced osPoolCreate with osMemoryPoolNew + * - extended osMemoryPoolAlloc (timeout) + * - added: osMemoryPoolGetName + * - added: osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize + * - added: osMemoryPoolGetCount, osMemoryPoolGetSpace + * - added: osMemoryPoolDelete + * - deprecated: osPoolCAlloc + * Message Queue: + * - extended: fixed size message instead of a single 32-bit value + * - using osMessageQueue prefix instead of osMessage + * - replaced osMessageCreate with osMessageQueueNew + * - updated: osMessageQueuePut, osMessageQueueGet + * - added: osMessageQueueGetName + * - added: osMessageQueueGetCapacity, osMessageQueueGetMsgSize + * - added: osMessageQueueGetCount, osMessageQueueGetSpace + * - added: osMessageQueueReset, osMessageQueueDelete + * Mail Queue: + * - deprecated (superseded by extended Message Queue functionality) + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS_H_ +#define CMSIS_OS_H_ + +/// \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_KERNEL 0x10000U ///< RTOS identification and version (main[31:16].sub[15:0]) + +/// \note CAN BE CHANGED: \b osKernelSystemId identifies the underlying RTOS kernel. +#define osKernelSystemId "KERNEL V1.0" ///< RTOS identification string + +/// \note CAN BE CHANGED: \b osFeature_xxx identifies RTOS features. +#define osFeature_MainThread 0 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Signals 16U ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 65535U ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available + +#if (osCMSIS >= 0x20000U) +#include "cmsis_os2.h" +#else +#include +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Priority values. +#if (osCMSIS < 0x20000U) +typedef enum { + osPriorityIdle = -3, ///< Priority: idle (lowest) + osPriorityLow = -2, ///< Priority: low + osPriorityBelowNormal = -1, ///< Priority: below normal + osPriorityNormal = 0, ///< Priority: normal (default) + osPriorityAboveNormal = +1, ///< Priority: above normal + osPriorityHigh = +2, ///< Priority: high + osPriorityRealtime = +3, ///< Priority: realtime (highest) + osPriorityError = 0x84, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority; +#else +#define osPriority osPriority_t +#endif + +/// Entry point of a thread. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +typedef void (*os_ptimer) (void const *argument); + +/// Timer type. +#if (osCMSIS < 0x20000U) +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} os_timer_type; +#else +#define os_timer_type osTimerType_t +#endif + +/// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +/// Status code values returned by CMSIS-RTOS functions. +#if (osCMSIS < 0x20000U) +typedef enum { + osOK = 0, ///< Function completed; no error or event occurred. + osEventSignal = 0x08, ///< Function completed; signal event occurred. + osEventMessage = 0x10, ///< Function completed; message event occurred. + osEventMail = 0x20, ///< Function completed; mail event occurred. + osEventTimeout = 0x40, ///< Function completed; timeout occurred. + osErrorParameter = 0x80, ///< Parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< Resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< Resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< Function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< System cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< Value of a parameter is out of range. + osErrorOS = 0xFF, ///< Unspecified RTOS error: run-time error but no other error message fits. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus; +#else +typedef int32_t osStatus; +#define osEventSignal (0x08) +#define osEventMessage (0x10) +#define osEventMail (0x20) +#define osEventTimeout (0x40) +#define osErrorOS osError +#define osErrorTimeoutResource osErrorTimeout +#define osErrorISRRecursive (-126) +#define osErrorValue (-127) +#define osErrorPriority (-128) +#endif + + +// >>> the following data type definitions may be adapted towards a specific RTOS + +/// Thread ID identifies the thread. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osThreadId; +#else +#define osThreadId osThreadId_t +#endif + +/// Timer ID identifies the timer. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osTimerId; +#else +#define osTimerId osTimerId_t +#endif + +/// Mutex ID identifies the mutex. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osMutexId; +#else +#define osMutexId osMutexId_t +#endif + +/// Semaphore ID identifies the semaphore. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef void *osSemaphoreId; +#else +#define osSemaphoreId osSemaphoreId_t +#endif + +/// Pool ID identifies the memory pool. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +typedef void *osPoolId; + +/// Message ID identifies the message queue. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +typedef void *osMessageQId; + +/// Mail ID identifies the mail queue. +/// \note CAN BE CHANGED: \b implementation specific in every CMSIS-RTOS. +typedef void *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; +#else +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osThreadAttr_t attr; ///< thread attributes +} osThreadDef_t; +#endif + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function +} osTimerDef_t; +#else +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + osTimerAttr_t attr; ///< timer attributes +} osTimerDef_t; +#endif + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value +} osMutexDef_t; +#else +#define osMutexDef_t osMutexAttr_t +#endif + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value +} osSemaphoreDef_t; +#else +#define osSemaphoreDef_t osSemaphoreAttr_t +#endif + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; +#else +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + osMemoryPoolAttr_t attr; ///< memory pool attributes +} osPoolDef_t; +#endif + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + void *pool; ///< memory array for messages +} osMessageQDef_t; +#else +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + osMessageQueueAttr_t attr; ///< message queue attributes +} osMessageQDef_t; +#endif + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +#if (osCMSIS < 0x20000U) +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; +#else +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *mail; ///< pointer to mail + osMemoryPoolAttr_t mp_attr; ///< memory pool attributes + osMessageQueueAttr_t mq_attr; ///< message queue attributes +} osMailQDef_t; +#endif + + +/// Event structure contains detailed information about an event. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelInitialize (void); +#endif + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osKernelStart (void); +#endif + +/// Check if the RTOS kernel is already started. +/// \return 0 RTOS is not started, 1 RTOS is started. +#if (osCMSIS < 0x20000U) +int32_t osKernelRunning(void); +#endif + +#if (defined(osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter. +/// \return RTOS kernel system timer as 32-bit value +#if (osCMSIS < 0x20000U) +uint32_t osKernelSysTick (void); +#else +#define osKernelSysTick osKernelGetSysTimerCount +#endif + +/// The RTOS kernel system timer frequency in Hz. +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#if (osCMSIS < 0x20000U) +#define osKernelSysTickFrequency 100000000 +#endif + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#if (osCMSIS < 0x20000U) +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) +#else +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * osKernelGetSysTimerFreq()) / 1000000) +#endif + +#endif // System Timer available + + +// ==== Thread Management Functions ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#else +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), \ + { NULL, osThreadDetached, NULL, 0U, NULL, 8*((stacksz+7)/8), (priority), 0U, 0U } } +#endif +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +#if (osCMSIS < 0x20000U) +osThreadId osThreadGetId (void); +#endif + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); +#endif + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the specified thread. +#if (osCMSIS < 0x20000U) +osPriority osThreadGetPriority (osThreadId thread_id); +#endif + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadYield (void); +#endif + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osThreadTerminate (osThreadId thread_id); +#endif + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flag information or error code. +osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osDelay (uint32_t millisec); +#endif + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== + +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = { (function) } +#else +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), { NULL, 0U, NULL, 0U } } +#endif +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create and Initialize a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "time delay" value of the timer. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); +#endif + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerStop (osTimerId timer_id); +#endif + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osTimerDelete (osTimerId timer_id); +#endif + + +// ==== Mutex Management Functions ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = { 0 } +#else +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = \ +{ NULL, osMutexRecursive | osMutexPrioInherit | osMutexRobust, NULL, 0U } +#endif +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); +#else +#define osMutexWait osMutexAcquire +#endif + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexRelease (osMutexId mutex_id); +#endif + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osMutexDelete (osMutexId mutex_id); +#endif + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = { 0 } +#else +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = \ +{ NULL, 0U, NULL, 0U } +#endif +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count maximum and initial number of available tokens. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); +#endif + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +#if (osCMSIS < 0x20000U) +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); +#endif + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL } +#else +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), { NULL, 0U, NULL, 0U, NULL, 0U } } +#endif +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a Memory Pool object. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a Memory Pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool available + + +// ==== Message Queue Management Functions ==== + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queue available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), NULL } +#else +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), { NULL, 0U, NULL, 0U, NULL, 0U } } +#endif +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue object. +/// \param[in] queue_def message queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queue available + + +// ==== Mail Queue Management Functions ==== + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queue available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of mails in the queue. +/// \param type data type of a single mail element. +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#if (osCMSIS < 0x20000U) +#define osMailQDef(name, queue_sz, type) \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), NULL } +#else +#define osMailQDef(name, queue_sz, type) \ +static void *os_mail_p_##name[2]; \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof(type), (&os_mail_p_##name), \ + { NULL, 0U, NULL, 0U, NULL, 0U }, \ + { NULL, 0U, NULL, 0U, NULL, 0U } } +#endif +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize a Mail Queue object. +/// \param[in] queue_def mail queue definition referenced with \ref osMailQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block for mail from a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block for mail from a mail memory pool and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a Mail into a Queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory with mail to put into a queue. +/// \return status code that indicates the execution status of the function. +osStatus osMailPut (osMailQId queue_id, const void *mail); + +/// Get a Mail from a Queue or timeout if Queue is empty. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event information that includes status code. +osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block by returning it to a mail memory pool. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queue available + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS_H_ diff --git a/Drivers/CMSIS/RTOS2/Template/cmsis_os1.c b/Drivers/CMSIS/RTOS2/Template/cmsis_os1.c new file mode 100644 index 0000000..effe4a1 --- /dev/null +++ b/Drivers/CMSIS/RTOS2/Template/cmsis_os1.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V1.2 + * + * Project: CMSIS-RTOS API V1 + * Title: cmsis_os_v1.c V1 module file + *---------------------------------------------------------------------------*/ + +#include +#include "cmsis_os.h" + +#if (osCMSIS >= 0x20000U) + + +// Thread +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { + + if (thread_def == NULL) { + return (osThreadId)NULL; + } + return osThreadNew((osThreadFunc_t)thread_def->pthread, argument, &thread_def->attr); +} + + +// Signals + +#define SignalMask ((1U< 0U) && (flags < 0x80000000U)) { + event.status = osEventSignal; + event.value.signals = (int32_t)flags; + } else { + switch ((int32_t)flags) { + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + case osErrorParameter: + event.status = osErrorValue; + break; + default: + event.status = (osStatus)flags; + break; + } + } + return event; +} + + +// Timer +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + + if (timer_def == NULL) { + return (osTimerId)NULL; + } + return osTimerNew((osTimerFunc_t)timer_def->ptimer, type, argument, &timer_def->attr); +} + + +// Mutex +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + + if (mutex_def == NULL) { + return (osMutexId)NULL; + } + return osMutexNew(mutex_def); +} + + +// Semaphore + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0U)) + +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + + if (semaphore_def == NULL) { + return (osSemaphoreId)NULL; + } + return osSemaphoreNew((uint32_t)count, (uint32_t)count, semaphore_def); +} + +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { + osStatus_t status; + uint32_t count; + + status = osSemaphoreAcquire(semaphore_id, millisec); + switch (status) { + case osOK: + count = osSemaphoreGetCount(semaphore_id); + return ((int32_t)count + 1); + case osErrorResource: + case osErrorTimeout: + return 0; + default: + break; + } + return -1; +} + +#endif // Semaphore + + +// Memory Pool + +#if (defined(osFeature_Pool) && (osFeature_Pool != 0)) + +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + + if (pool_def == NULL) { + return (osPoolId)NULL; + } + return ((osPoolId)(osMemoryPoolNew(pool_def->pool_sz, pool_def->item_sz, &pool_def->attr))); +} + +void *osPoolAlloc (osPoolId pool_id) { + return osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0U); +} + +void *osPoolCAlloc (osPoolId pool_id) { + void *block; + uint32_t block_size; + + block_size = osMemoryPoolGetBlockSize((osMemoryPoolId_t)pool_id); + if (block_size == 0U) { + return NULL; + } + block = osMemoryPoolAlloc((osMemoryPoolId_t)pool_id, 0U); + if (block != NULL) { + memset(block, 0, block_size); + } + return block; +} + +osStatus osPoolFree (osPoolId pool_id, void *block) { + return osMemoryPoolFree((osMemoryPoolId_t)pool_id, block); +} + +#endif // Memory Pool + + +// Message Queue + +#if (defined(osFeature_MessageQ) && (osFeature_MessageQ != 0)) + +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + (void)thread_id; + + if (queue_def == NULL) { + return (osMessageQId)NULL; + } + return ((osMessageQId)(osMessageQueueNew(queue_def->queue_sz, sizeof(uint32_t), &queue_def->attr))); +} + +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { + return osMessageQueuePut((osMessageQueueId_t)queue_id, &info, 0U, millisec); +} + +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { + osStatus_t status; + osEvent event; + uint32_t message; + + status = osMessageQueueGet((osMessageQueueId_t)queue_id, &message, NULL, millisec); + switch (status) { + case osOK: + event.status = osEventMessage; + event.value.v = message; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + default: + event.status = status; + break; + } + return event; +} + +#endif // Message Queue + + +// Mail Queue + +#if (defined(osFeature_MailQ) && (osFeature_MailQ != 0)) + +typedef struct os_mail_queue_s { + osMemoryPoolId_t mp_id; + osMessageQueueId_t mq_id; +} os_mail_queue_t; + +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + os_mail_queue_t *ptr; + (void)thread_id; + + if (queue_def == NULL) { + return (osMailQId)NULL; + } + + ptr = queue_def->mail; + if (ptr == NULL) { + return (osMailQId)NULL; + } + + ptr->mp_id = osMemoryPoolNew (queue_def->queue_sz, queue_def->item_sz, &queue_def->mp_attr); + ptr->mq_id = osMessageQueueNew(queue_def->queue_sz, sizeof(void *), &queue_def->mq_attr); + if ((ptr->mp_id == (osMemoryPoolId_t)NULL) || (ptr->mq_id == (osMessageQueueId_t)NULL)) { + if (ptr->mp_id != (osMemoryPoolId_t)NULL) { + osMemoryPoolDelete(ptr->mp_id); + } + if (ptr->mq_id != (osMessageQueueId_t)NULL) { + osMessageQueueDelete(ptr->mq_id); + } + return (osMailQId)NULL; + } + + return (osMailQId)ptr; +} + +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return NULL; + } + return osMemoryPoolAlloc(ptr->mp_id, millisec); +} + +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + void *block; + uint32_t block_size; + + if (ptr == NULL) { + return NULL; + } + block_size = osMemoryPoolGetBlockSize(ptr->mp_id); + if (block_size == 0U) { + return NULL; + } + block = osMemoryPoolAlloc(ptr->mp_id, millisec); + if (block != NULL) { + memset(block, 0, block_size); + } + + return block; + +} + +osStatus osMailPut (osMailQId queue_id, const void *mail) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMessageQueuePut(ptr->mq_id, &mail, 0U, 0U); +} + +osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + osStatus_t status; + osEvent event; + void *mail; + + if (ptr == NULL) { + event.status = osErrorParameter; + return event; + } + + status = osMessageQueueGet(ptr->mq_id, &mail, NULL, millisec); + switch (status) { + case osOK: + event.status = osEventMail; + event.value.p = mail; + break; + case osErrorResource: + event.status = osOK; + break; + case osErrorTimeout: + event.status = osEventTimeout; + break; + default: + event.status = status; + break; + } + return event; +} + +osStatus osMailFree (osMailQId queue_id, void *mail) { + os_mail_queue_t *ptr = (os_mail_queue_t *)queue_id; + + if (ptr == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMemoryPoolFree(ptr->mp_id, mail); +} + +#endif // Mail Queue + + +#endif // osCMSIS diff --git a/Drivers/STM32H7RSxx_BSP/.DS_Store b/Drivers/STM32H7RSxx_BSP/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..06595e061a1df19ff47b1d596197290305527488 GIT binary patch literal 6148 zcmeH~F;Bxl427SeLj^+W$asH%0T{{{l^`J@rt$+2l&uh?!k&%4&9i+}sZv%3^eovg z=h!*r8{!-QTYRq0ff;})-4$OR#^(3kM|My%t`^Ve@P-%q2R5VX{R!_q!ZkX);+=8Z zzuG*npSo`CZ6{db0r$AX1#U6tYK|+Mp~c;>Z2u0*ihu}+fCz|y2n-2uX1h&~Qx!!( z1VmshS+XY{# z&eqY(`K&GUNBWPkHp&@d6jNgqbK#@-bWm6Pn)jQkeQLBbAMI5A2sjs+2>b+s2okT;Kaz7zN1d(n<$QR@X@<5^qxkw0c<#qY(jJ-bT(2+Jpu#tCe zy`Eimit`zOtPYzQFa=Q274faZ&~#mWU{@X)5yken#{vzS&HnvkkbOR&+zPMw!X9_% z@!#s&_88+4HFo^f_|%QNg$Y9q&s*StBWBoQPX4x^GUmb#OFZBf^KOCvG%OSd1ww&P zAQZS@1-ueglMB`$t{w`60_PRb_d}v9X2-Umy*fBp3qaJ*cr!j*FF{NiAZEw5AR{y> zRAQluw-{3Bj3>{_j%~q0hj{ZLezJInB6d3WPnHhJ1!D{aLV;5SuFG_)_5X?fOaFgL zidiTS3j8YtWVC)>uXrV|t%J*Htxfb7dS}eFbPiUEiB^g^(NcWV%S-yq_3YRdG&>Jk-s>lW0<=++W}iR#Er@J^+*ii2@XfKz|kA#iucT2oc>OrAdRvl0Ca# z&z^3I^BI7xKlZo462L%r#HWX;`MLYVt}0_hI`4SH6OP#JkGq#i^?bs)10L{0pQvfVf~f zjO&;sh|LqkUN|N)L$jn3lWH|$SkjqqRo4s0#H7P&_^^7i)r4a4bl%^h9M%&RrGOMT zRp2_eOYi@8^grhRQ<8R4KnnaT1#Gdo->msc)mtYo=e@SkAL(B6MR(&mC=Ah#iP4U^ g@pin5qO5Da=6Nq16NAot(24pPa9w0l;L-|w1NsCNkN^Mx literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.md b/Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.md new file mode 100644 index 0000000..dcc5e4a --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2014-2021 STMicroelectronics. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.txt b/Drivers/STM32H7RSxx_BSP/Components/Common/LICENSE.txt new file mode 100644 index 0000000..b40364c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/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/Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.html b/Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.html new file mode 100644 index 0000000..d0e93d2 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.html @@ -0,0 +1,252 @@ + + + + + + + Release Notes for BSP Common Components Drivers + + + + + + +
+ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.md b/Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.md new file mode 100644 index 0000000..8ae6faf --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/Release_Notes.md @@ -0,0 +1,337 @@ +--- +pagetitle: Release Notes for BSP Common Components Drivers +lang: en +header-includes: +--- + +::: {.row} +::: {.col-sm-12 .col-lg-4} + +
+# Release Notes for BSP Common Components Drivers +Copyright © 2014-2023 STMicroelectronics\ + +[![ST logo](_htmresc/st_logo.png)](https://www.st.com){.logo} +
+ +# Purpose + +This directory contains the BSP Common components drivers. + +::: + +::: {.col-sm-12 .col-lg-8} +# Update History + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +- Add Frequency, Exposure and Gain configuration function pointers in camera.h + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +- Update licensing + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +- Add hybrid_sensor.h to support hybrid (env and motion) sensors + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +- Add ranging_sensor.h to support ranging sensors +- Add light_sensor.h to support ambient light sensors +- Rename UTILS_LCD_Drv_t structure into LCD_UTILS_Drv_t +- Code spelling and formatting + +## Backward Compatibility + +- This release breaks compatibility with previous versions. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +- Rename GUI_Drv_t structure into UTILS_LCD_Drv_t + +## Backward Compatibility + +- This release breaks compatibility with previous versions. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +- Update st_logo.png inclusion path in Release notes. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +### Component release + +Official release of BSP Common components drivers in line with STM32Cube BSP drivers development guidelines (UM2298). + +## Backward Compatibility + +This release breaks compatibility with previous versions. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +Reformat the BSD 3-Clause license declaration in the files header (replace license terms by a web reference to OSI website where those terms lie) +Correct sensor names in headers files hsensor.h and psensor.h + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +Add dpredriver.h: support of DP redriver class +Add pwrmon.h: support of power monitor class +Add usbtypecswitch.h: support of USB type C switch class + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +Add hsensor.h: support of humidity class +Add psensor.h: support of pressure class +Update tsensor.h: Temperature can be negative +Update accelero.h: LowPower API can enable or disable the low power mode +Update magneto.h: LowPower API can enable or disable the low power mode + +## Backward Compatibility + +This release breaks compatibility with previous versions. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +tsensor.h: Fix compilation issue on *TSENSOR_InitTypeDef* + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +accelero.h: add *DeInit* field in *ACCELERO_DrvTypeDef* structure +audio.h: add *DeInit* field in *AUDIO_DrvTypeDef* structure +idd.h: + + - add *Shunt0StabDelay*, *Shunt1StabDelay*, *Shunt2StabDelay*, *Shunt3StabDelay*, *Shunt4StabDelay* and *ShuntNbOnBoard* fields in *IDD_ConfigTypeDef* structure + - rename *ShuntNumber* field to *ShuntNbUsed* in *IDD_ConfigTypeDef* structure + +magneto.h: add *DeInit* field in *MAGNETO_DrvTypeDef* structure + +## Backward Compatibility + +This release breaks compatibility with previous versions. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +accelero.h: add *LowPower* field in *ACCELERO_DrvTypeDef* structure +magneto.h: add *LowPower* field in *MAGNETO_DrvTypeDef* structure +gyro.h: add *DeInit* and *LowPower* fields in *GYRO_DrvTypeDef* structure +camera.h: add CAMERA_COLOR_EFFECT_NONE define +idd.h: + +- add *MeasureNb*, *DeltaDelayUnit* and *DeltaDelayValue* fields in *IDD_ConfigTypeDef* structure +- rename *PreDelay* field to *PreDelayUnit* in *IDD_ConfigTypeDef* structure + +## Backward Compatibility + +This release breaks compatibility with previous versions. + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +Magnetometer driver function prototypes added (magneto.h file) +Update "idd.h" file to provide DeInit() and WakeUp() services in IDD current measurement driver + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +IDD current measurement driver function prototypes added (idd.h file) +io.h: add new typedef enum IO_PinState with IO_PIN_RESET and IO_PIN_SET values + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +Update "io.h" file to support MFX (Multi Function eXpander) device available on some STM32 boards + +- add new entries for *IO_ModeTypedef* enumeration structure +- update the *IO_DrvTypeDef* structure + - Update all return values and function parameters to uint32_t + - Add a return value for *Config* field + +## Backward Compatibility + +This release breaks compatibility with previous versions. + +
+::: + + +::: {.collapse} + + +
+ +## Main Changes +gyro.h: change “__GIRO_H” by “__GYRO_H” to fix compilation issue under Mac OS + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +EPD (E Paper Display) driver function prototype added (epd.h file) + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +Temperature Sensor driver function prototype added + +
+::: + +::: {.collapse} + + +
+ +## Main Changes +First official release with Accelerometer, Audio, Camera, Gyroscope, IO, LCD and Touch Screen drivers function prototypes + +
+::: + +::: +::: + +
+For complete documentation on STM32 Microcontrollers , +visit: [http://www.st.com/STM32](http://www.st.com/STM32) +
diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Add button.svg b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Add button.svg new file mode 100644 index 0000000..dc4a222 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Add button.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Update.svg b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Update.svg new file mode 100644 index 0000000..75b3194 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/Update.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/favicon.png b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/mini-st.css b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/mini-st.css new file mode 100644 index 0000000..1b12ad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/mini-st.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/st_logo.png b/Drivers/STM32H7RSxx_BSP/Components/Common/_htmresc/st_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/audio.h b/Drivers/STM32H7RSxx_BSP/Components/Common/audio.h new file mode 100644 index 0000000..e64712c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/audio.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * @file audio.h + * @author MCD Application Team + * @brief This header file contains the common defines and functions prototypes + * for the Audio driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef AUDIO_H +#define AUDIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup AUDIO + * @{ + */ + +/** @defgroup AUDIO_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @defgroup AUDIO_Exported_Types + * @{ + */ + + + +/** @defgroup AUDIO_Driver_structure Audio Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *, void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*Play)(void *); + int32_t (*Pause)(void *); + int32_t (*Resume)(void *); + int32_t (*Stop)(void *, uint32_t); + int32_t (*SetFrequency)(void *, uint32_t); + int32_t (*GetFrequency)(void *); + int32_t (*SetVolume)(void *, uint32_t, uint8_t); + int32_t (*GetVolume)(void *, uint32_t, uint8_t *); + int32_t (*SetMute)(void *, uint32_t); + int32_t (*SetOutputMode)(void *, uint32_t); + int32_t (*SetResolution)(void *, uint32_t); + int32_t (*GetResolution)(void *, uint32_t *); + int32_t (*SetProtocol)(void *, uint32_t); + int32_t (*GetProtocol)(void *, uint32_t *); + int32_t (*Reset)(void *); +} AUDIO_Drv_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* AUDIO_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/camera.h b/Drivers/STM32H7RSxx_BSP/Components/Common/camera.h new file mode 100644 index 0000000..8e665ee --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/camera.h @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * @file camera.h + * @author MCD Application Team + * @brief This header file contains the common defines and functions prototypes + * for the camera driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef CAMERA_H +#define CAMERA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup CAMERA + * @{ + */ + + +/** @defgroup CAMERA_Exported_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup CAMERA_Driver_structure Camera Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *, uint32_t, uint32_t); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*GetCapabilities)(void *, void *); + int32_t (*SetLightMode)(void *, uint32_t); + int32_t (*SetColorEffect)(void *, uint32_t); + int32_t (*SetBrightness)(void *, int32_t); + int32_t (*SetSaturation)(void *, int32_t); + int32_t (*SetContrast)(void *, int32_t); + int32_t (*SetHueDegree)(void *, int32_t); + int32_t (*MirrorFlipConfig)(void *, uint32_t); + int32_t (*ZoomConfig)(void *, uint32_t); + int32_t (*SetResolution)(void *, uint32_t); + int32_t (*GetResolution)(void *, uint32_t *); + int32_t (*SetPixelFormat)(void *, uint32_t); + int32_t (*GetPixelFormat)(void *, uint32_t *); + int32_t (*NightModeConfig)(void *, uint32_t); + int32_t (*SetFrequency)(void *, int32_t); + int32_t (*SetGain)(void *, int32_t); + int32_t (*SetExposure)(void *, int32_t); +} CAMERA_Drv_t; + +/** + * @} + */ + +/** @defgroup CAMERA_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* CAMERA_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/dpredriver.h b/Drivers/STM32H7RSxx_BSP/Components/Common/dpredriver.h new file mode 100644 index 0000000..0bfa217 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/dpredriver.h @@ -0,0 +1,102 @@ +/** + ****************************************************************************** + * @file dpredriver.h + * @author MCD Application Team + * @brief This header file contains the functions prototypes for the + * DisplayPort Linear Redriver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DPREDRIVER_H +#define __DPREDRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup DPREDRIVER + * @{ + */ + +/** @defgroup DPREDRIVER_Exported_Types + * @{ + */ + +/** @defgroup DPREDRIVER_Channel_Identifier Channel Identifier + * @{ + */ +typedef enum +{ + CHANNEL_DP0 = 0, + CHANNEL_DP1, + CHANNEL_DP2, + CHANNEL_DP3, + CHANNEL_RX1, + CHANNEL_RX2, + CHANNEL_SSTX +} DPREDRIVER_ChannelId_t; +/** + * @} + */ + +/** @defgroup DPREDRIVER_Driver_structure DisplayPort Linear Redriver Driver structure + * @{ + */ +typedef struct +{ + uint32_t (*Init)(uint16_t); + void (*DeInit)(uint16_t); + uint32_t (*PowerOn)(uint16_t); + uint32_t (*PowerOff)(uint16_t); + uint32_t (*SetEQGain)(uint16_t, DPREDRIVER_ChannelId_t, uint8_t); + uint32_t (*EnableChannel)(uint16_t, DPREDRIVER_ChannelId_t); + uint32_t (*DisableChannel)(uint16_t, DPREDRIVER_ChannelId_t); +} DPREDRIVER_Drv_t; +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DPREDRIVER_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/env_sensor.h b/Drivers/STM32H7RSxx_BSP/Components/Common/env_sensor.h new file mode 100644 index 0000000..311dadc --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/env_sensor.h @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * @file env_sensor.h + * @author MCD Application Team + * @brief This header file contains the functions prototypes for the + * environmental sensor driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef ENV_SENSOR_H +#define ENV_SENSOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP BSP + * @{ + */ + +/** @addtogroup COMPONENTS COMPONENTS + * @{ + */ + +/** @addtogroup COMMON COMMON + * @{ + */ + +/** @addtogroup ENV_SENSOR ENV SENSOR + * @{ + */ + +/** @addtogroup ENV_SENSOR_Public_Types ENV SENSOR Public types + * @{ + */ + +/** + * @brief ENV SENSOR driver structure definition + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint8_t *); + int32_t (*GetCapabilities)(void *, void *); +} ENV_SENSOR_CommonDrv_t; + +typedef struct +{ + int32_t (*Enable)(void *); + int32_t (*Disable)(void *); + int32_t (*GetOutputDataRate)(void *, float *); + int32_t (*SetOutputDataRate)(void *, float); + int32_t (*GetValue)(void *, float *); +} ENV_SENSOR_FuncDrv_t; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ENV_SENSOR_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/epd.h b/Drivers/STM32H7RSxx_BSP/Components/Common/epd.h new file mode 100644 index 0000000..a863804 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/epd.h @@ -0,0 +1,94 @@ +/** + ****************************************************************************** + * @file epd.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the + * EPD (E Paper Display) driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 __EPD_H +#define __EPD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup Common + * @{ + */ + +/** @addtogroup EPD + * @{ + */ + +/** @defgroup EPD_Exported_Types + * @{ + */ + +/** @defgroup EPD_Driver_structure E Paper Display Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(void); + void (*WritePixel)(uint8_t); + + /* Optimized operation */ + void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t); + void (*RefreshDisplay)(void); + void (*CloseChargePump)(void); + + uint16_t (*GetEpdPixelWidth)(void); + uint16_t (*GetEpdPixelHeight)(void); + void (*DrawImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint8_t *); +} +EPD_DrvTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* EPD_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/hybrid_sensor.h b/Drivers/STM32H7RSxx_BSP/Components/Common/hybrid_sensor.h new file mode 100644 index 0000000..df35cfb --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/hybrid_sensor.h @@ -0,0 +1,108 @@ +/** + ****************************************************************************** + * @file hybrid_sensor.h + * @author MCD Application Team + * @brief This header file contains the functions prototypes for the + * hybrid sensor driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 HYBRID_SENSOR_H +#define HYBRID_SENSOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP BSP + * @{ + */ + +/** @addtogroup COMPONENTS COMPONENTS + * @{ + */ + +/** @addtogroup COMMON COMMON + * @{ + */ + +/** @addtogroup HYBRID_SENSOR HYBRID SENSOR + * @{ + */ + +/** @addtogroup HYBRID_SENSOR_Public_Types HYBRID SENSOR Public types + * @{ + */ + +/** + * @brief HYBRID SENSOR driver structure definition + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint8_t *); + int32_t (*GetCapabilities)(void *, void *); +} HYBRID_SENSOR_CommonDrv_t; + +typedef struct +{ + int32_t (*Enable)(void *); + int32_t (*Disable)(void *); + int32_t (*GetOutputDataRate)(void *, float *); + int32_t (*SetOutputDataRate)(void *, float); + int32_t (*GetValue)(void *, float *); +} HYBRID_ENV_SENSOR_FuncDrv_t; + +typedef struct +{ + int32_t (*Enable)(void *); + int32_t (*Disable)(void *); + int32_t (*GetSensitivity)(void *, float *); + int32_t (*GetOutputDataRate)(void *, float *); + int32_t (*SetOutputDataRate)(void *, float); + int32_t (*GetFullScale)(void *, int32_t *); + int32_t (*SetFullScale)(void *, int32_t); + int32_t (*GetAxes)(void *, void *); + int32_t (*GetAxesRaw)(void *, void *); +} HYBRID_MOTION_SENSOR_FuncDrv_t; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* HYBRID_SENSOR_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/idd.h b/Drivers/STM32H7RSxx_BSP/Components/Common/idd.h new file mode 100644 index 0000000..2b21aa4 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/idd.h @@ -0,0 +1,95 @@ +/** + ****************************************************************************** + * @file idd.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the IDD driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef IDD_H +#define IDD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup IDD + * @{ + */ + +/** @defgroup IDD_Exported_Types IDD Exported Types + * @{ + */ + +/** @defgroup IDD_Driver_structure IDD Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*Reset)(void *); + int32_t (*LowPower)(void *); + int32_t (*WakeUp)(void *); + int32_t (*Start)(void *); + int32_t (*Config)(void *, void *); + int32_t (*GetValue)(void *, uint32_t *); + int32_t (*EnableIT)(void *); + int32_t (*DisableIT)(void *); + int32_t (*ITStatus)(void *); + int32_t (*ClearIT)(void *); + int32_t (*ErrorEnableIT)(void *); + int32_t (*ErrorClearIT)(void *); + int32_t (*ErrorGetITStatus)(void *); + int32_t (*ErrorDisableIT)(void *); + int32_t (*ErrorGetSrc)(void *); + int32_t (*ErrorGetCode)(void *); +} IDD_Drv_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IDD_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/io.h b/Drivers/STM32H7RSxx_BSP/Components/Common/io.h new file mode 100644 index 0000000..51e8072 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/io.h @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * @file io.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the IO driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef IO_H +#define IO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup IO + * @{ + */ + +/** @defgroup IO_Exported_Types IO Exported Types + * @{ + */ + +/** @defgroup IO_Driver_structure IO Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *, void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*Reset)(void *); + int32_t (*Start)(void *, uint32_t); + int32_t (*WritePin)(void *, uint32_t, uint8_t); + int32_t (*ReadPin)(void *, uint32_t); + int32_t (*EnableIT)(void *); + int32_t (*DisableIT)(void *); + int32_t (*ITStatus)(void *, uint32_t); + int32_t (*ClearIT)(void *, uint32_t); +} IO_Drv_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IO_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/lcd.h b/Drivers/STM32H7RSxx_BSP/Components/Common/lcd.h new file mode 100644 index 0000000..aa9c485 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/lcd.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file lcd.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the LCD driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef LCD_H +#define LCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup LCD + * @{ + */ + +/** @defgroup LCD_Exported_Constants LCD Exported Constants + * @{ + */ +#define LCD_PIXEL_FORMAT_ARGB8888 0x00000000U /*!< ARGB8888 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_RGB888 0x00000001U /*!< RGB888 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_RGB565 0x00000002U /*!< RGB565 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_ARGB1555 0x00000003U /*!< ARGB1555 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_ARGB4444 0x00000004U /*!< ARGB4444 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_L8 0x00000005U /*!< L8 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_AL44 0x00000006U /*!< AL44 LTDC pixel format */ +#define LCD_PIXEL_FORMAT_AL88 0x00000007U /*!< AL88 LTDC pixel format */ +/** + * @} + */ + +/** @defgroup LCD_Exported_Types + * @{ + */ + +/** @defgroup LCD_Driver_structure LCD Driver structure + * @{ + */ +typedef struct +{ + int32_t (*DrawBitmap)(uint32_t, uint32_t, uint32_t, uint8_t *); + int32_t (*FillRGBRect)(uint32_t, uint32_t, uint32_t, uint8_t *, uint32_t, uint32_t); + int32_t (*DrawHLine)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*DrawVLine)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*FillRect)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*GetPixel)(uint32_t, uint32_t, uint32_t, uint32_t *); + int32_t (*SetPixel)(uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*GetXSize)(uint32_t, uint32_t *); + int32_t (*GetYSize)(uint32_t, uint32_t *); + int32_t (*SetLayer)(uint32_t, uint32_t); + int32_t (*GetFormat)(uint32_t, uint32_t *); +} LCD_UTILS_Drv_t; + +typedef struct +{ + /* Control functions */ + int32_t (*Init)(void *, uint32_t, uint32_t); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*DisplayOn)(void *); + int32_t (*DisplayOff)(void *); + int32_t (*SetBrightness)(void *, uint32_t); + int32_t (*GetBrightness)(void *, uint32_t *); + int32_t (*SetOrientation)(void *, uint32_t); + int32_t (*GetOrientation)(void *, uint32_t *); + + /* Drawing functions*/ + int32_t (*SetCursor)(void *, uint32_t, uint32_t); + int32_t (*DrawBitmap)(void *, uint32_t, uint32_t, uint8_t *); + int32_t (*FillRGBRect)(void *, uint32_t, uint32_t, uint8_t *, uint32_t, uint32_t); + int32_t (*DrawHLine)(void *, uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*DrawVLine)(void *, uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*FillRect)(void *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + int32_t (*GetPixel)(void *, uint32_t, uint32_t, uint32_t *); + int32_t (*SetPixel)(void *, uint32_t, uint32_t, uint32_t); + int32_t (*GetXSize)(void *, uint32_t *); + int32_t (*GetYSize)(void *, uint32_t *); +} LCD_Drv_t; + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LCD_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/light_sensor.h b/Drivers/STM32H7RSxx_BSP/Components/Common/light_sensor.h new file mode 100644 index 0000000..b94cd77 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/light_sensor.h @@ -0,0 +1,85 @@ +/** + ****************************************************************************** + * @file light_sensor.h + * @author IMG SW Application Team + * @brief This header file contains the common defines and functions prototypes + * for the light sensor driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 LIGHT_SENSOR_H +#define LIGHT_SENSOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup LIGHT_SENSOR + * @{ + */ + +/** @defgroup LIGHT_SENSOR_Driver_structure Ranging sensor Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*GetCapabilities)(void *, void *); + int32_t (*SetExposureTime)(void *, uint32_t); + int32_t (*GetExposureTime)(void *, uint32_t *); + int32_t (*SetGain)(void *, uint8_t, uint32_t); + int32_t (*GetGain)(void *, uint8_t, uint32_t *); + int32_t (*SetInterMeasurementTime)(void *, uint32_t); + int32_t (*GetInterMeasurementTime)(void *, uint32_t *); + int32_t (*Start)(void *, uint32_t); + int32_t (*Stop)(void *); + int32_t (*StartFlicker)(void *, uint8_t, uint8_t); + int32_t (*StopFlicker)(void *); + int32_t (*GetValues)(void *, uint32_t *); + int32_t (*SetControlMode)(void *, uint32_t, uint32_t); +} LIGHT_SENSOR_Drv_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LIGHT_SENSOR_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/motion_sensor.h b/Drivers/STM32H7RSxx_BSP/Components/Common/motion_sensor.h new file mode 100644 index 0000000..299f4ea --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/motion_sensor.h @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @file motion_sensor.h + * @author MCD Application Team + * @brief This header file contains the functions prototypes for the + * motion sensor driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MOTION_SENSOR_H +#define MOTION_SENSOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP BSP + * @{ + */ + +/** @addtogroup COMPONENTS COMPONENTS + * @{ + */ + +/** @addtogroup COMMON COMMON + * @{ + */ + +/** @addtogroup MOTION_SENSOR MOTION SENSOR + * @{ + */ + +/** @addtogroup MOTION_SENSOR_Public_Types MOTION SENSOR Public types + * @{ + */ + +/** + * @brief MOTION SENSOR driver structure definition + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint8_t *); + int32_t (*GetCapabilities)(void *, void *); +} MOTION_SENSOR_CommonDrv_t; + +typedef struct +{ + int32_t (*Enable)(void *); + int32_t (*Disable)(void *); + int32_t (*GetSensitivity)(void *, float *); + int32_t (*GetOutputDataRate)(void *, float *); + int32_t (*SetOutputDataRate)(void *, float); + int32_t (*GetFullScale)(void *, int32_t *); + int32_t (*SetFullScale)(void *, int32_t); + int32_t (*GetAxes)(void *, void *); + int32_t (*GetAxesRaw)(void *, void *); +} MOTION_SENSOR_FuncDrv_t; + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* MOTION_SENSOR_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/pwrmon.h b/Drivers/STM32H7RSxx_BSP/Components/Common/pwrmon.h new file mode 100644 index 0000000..a60a0b1 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/pwrmon.h @@ -0,0 +1,251 @@ +/** + ****************************************************************************** + * @file pwrmon.h + * @author MCD Application Team + * @brief This header file contains the functions prototypes for the + * Current/Power Monitor device driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __PWRMON_H +#define __PWRMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup PWRMON + * @{ + */ + +/** @defgroup PWRMON_Exported_Types + * @{ + */ + +/** @defgroup PWRMON_Operating_Mode_enum Power Monitor Operating Mode enums + * @{ + */ +typedef enum +{ + OPERATING_MODE_TRIGGERED = 0, + OPERATING_MODE_CONTINUOUS, + OPERATING_MODE_NB +} PWRMON_OperatingMode_t; +/** + * @} + */ + +/** @defgroup PWRMON_Conversion_Time_enum Power Monitor Conversion_Time enums + * @{ + */ +typedef enum +{ + CONVERT_TIME_140 = 0, + CONVERT_TIME_204, + CONVERT_TIME_332, + CONVERT_TIME_588, + CONVERT_TIME_1100, + CONVERT_TIME_2116, + CONVERT_TIME_4156, + CONVERT_TIME_8244, + CONVERT_TIME_NB +} PWRMON_ConvertTime_t; +/** + * @} + */ + +/** @defgroup PWRMON_Conversion_Time_enum Power Monitor Conversion_Time enums + * @{ + */ +typedef enum +{ + AVERAGING_MODE_1 = 0, + AVERAGING_MODE_4, + AVERAGING_MODE_16, + AVERAGING_MODE_64, + AVERAGING_MODE_128, + AVERAGING_MODE_256, + AVERAGING_MODE_512, + AVERAGING_MODE_1024, + AVERAGING_MODE_NB +} PWRMON_AveragingMode_t; +/** + * @} + */ + +/** @defgroup PWRMON_Device_Configuration_structure Power Monitor Device Configuration structure + * @{ + */ +typedef struct +{ + PWRMON_ConvertTime_t ShuntConvertTime; + PWRMON_ConvertTime_t BusConvertTime; + PWRMON_AveragingMode_t AveragingMode; +} PWRMON_Config_t; +/** + * @} + */ + +/** @defgroup PWRMON_Alert_Polarity_enum Power Monitor Alert Polarity enums + * @{ + */ +typedef enum +{ + ALERT_POLARITY_NORMAL = 0, + ALERT_POLARITY_INVERTED, + ALERT_POLARITY_NB +} PWRMON_AlertPolarity_t; +/** + * @} + */ + +/** @defgroup PWRMON_Alert_Latch_Enable_enum Power Monitor Alert Latch Enable enums + * @{ + */ +typedef enum +{ + ALERT_LATCH_DISABLE = 0, + ALERT_LATCH_ENABLE, + ALERT_LATCH_NB +} PWRMON_AlertLatchEnable_t; +/** + * @} + */ + +/** @defgroup PWRMON_Alert_Function_enum Power Monitor Alert Function enums + * @{ + */ +typedef enum +{ + ALERT_FUNCTION_NONE = 0, + ALERT_FUNCTION_SOL, + ALERT_FUNCTION_SUL, + ALERT_FUNCTION_BOL, + ALERT_FUNCTION_BUL, + ALERT_FUNCTION_POL, + ALERT_FUNCTION_NB, +} PWRMON_AlertFunction_t; +/** + * @} + */ + +/** @defgroup PWRMON_Alert_Configuration_structure Power Monitor Alert Configuration structure + * @{ + */ +typedef struct +{ + PWRMON_AlertPolarity_t Polarity; + PWRMON_AlertLatchEnable_t LatchEnable; +} PWRMON_AlertPinConfig_t; +/** + * @} + */ + +/** @defgroup PWRMON_Voltage_Input_enum Power Monitor Voltage Input enums + * @{ + */ +typedef enum +{ + VOLTAGE_INPUT_SHUNT = 0, + VOLTAGE_INPUT_BUS, + VOLTAGE_INPUT_ALL, + VOLTAGE_INPUT_NB +} PWRMON_InputSignal_t; +/** + * @} + */ + +/** @defgroup PWRMON_Flag_enum Power Monitor Flag enums + * @{ + */ +typedef enum +{ + FLAG_ALERT_FUNCTION = 0, + FLAG_CONVERSION_READY, + FLAG_MATH_OVERFLOW, + FLAG_NB +} PWRMON_Flag_t; +/** + * @} + */ + +/** @defgroup PWRMON_Driver_structure Power Monitor Driver structure + * @{ + */ +typedef struct +{ + void (*Init)(uint16_t, PWRMON_Config_t *); + void (*DeInit)(uint16_t); + uint16_t (*ReadId)(uint16_t); + void (*Reset)(uint16_t); + void (*SetCalibration)(uint16_t, uint16_t); + uint16_t (*GetCalibration)(uint16_t); + void (*SetAlertFunction)(uint16_t, PWRMON_AlertFunction_t); + PWRMON_AlertFunction_t (*GetAlertFunction)(uint16_t); + void (*AlertPinConfig)(uint16_t, PWRMON_AlertPinConfig_t *); + void (*SetVBusThreshold)(uint16_t, uint16_t); + uint16_t (*GetVBusThreshold)(uint16_t); + void (*SetVShuntThreshold)(uint16_t, int16_t); + int16_t (*GetVShuntThreshold)(uint16_t); + void (*SetPowerThreshold)(uint16_t, uint32_t); + uint32_t (*GetPowerThreshold)(uint16_t); + void (*AlertThresholdEnableIT)(uint16_t); + void (*AlertThresholdDisableIT)(uint16_t); + void (*ConversionReadyEnableIT)(uint16_t); + void (*ConversionReadyDisableIT)(uint16_t); + void (*StartConversion)(uint16_t, PWRMON_InputSignal_t, PWRMON_OperatingMode_t); + void (*StopConversion)(uint16_t); + uint16_t (*GetVBus)(uint16_t); + int16_t (*GetVShunt)(uint16_t); + uint16_t (*GetPower)(uint16_t); + int16_t (*GetCurrent)(uint16_t); + uint8_t (*GetFlag)(uint16_t, PWRMON_Flag_t); +} PWRMON_Drv_t; +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PWRMON_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/ranging_sensor.h b/Drivers/STM32H7RSxx_BSP/Components/Common/ranging_sensor.h new file mode 100644 index 0000000..8b5f5e0 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/ranging_sensor.h @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * @file ranging_sensor.h + * @author IMG SW Application Team + * @brief This header file contains the common defines and functions prototypes + * for the ranging sensor driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 RANGING_SENSOR_H +#define RANGING_SENSOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup RANGING_SENSOR + * @{ + */ + +/** @defgroup RANGING_SENSOR_Driver_structure Ranging sensor Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*GetCapabilities)(void *, void *); + int32_t (*ConfigProfile)(void *, void *); + int32_t (*ConfigROI)(void *, void *); + int32_t (*ConfigIT)(void *, void *); + int32_t (*GetDistance)(void *, void *); + int32_t (*Start)(void *, uint32_t); + int32_t (*Stop)(void *); + int32_t (*SetAddress)(void *, uint32_t); + int32_t (*GetAddress)(void *, uint32_t *); + int32_t (*SetPowerMode)(void *, uint32_t); + int32_t (*GetPowerMode)(void *, uint32_t *); +} RANGING_SENSOR_Drv_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* RANGING_SENSOR_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/ts.h b/Drivers/STM32H7RSxx_BSP/Components/Common/ts.h new file mode 100644 index 0000000..faddb6f --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/ts.h @@ -0,0 +1,90 @@ +/** + ****************************************************************************** + * @file ts.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the Touch Screen driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef TS_H +#define TS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup TS + * @{ + */ + +/** @defgroup TS_Exported_Types + * @{ + */ + +/** @defgroup TS_Driver_structure Touch Sensor Driver structure + * @{ + */ +typedef struct +{ + int32_t (*Init)(void *); + int32_t (*DeInit)(void *); + int32_t (*GestureConfig)(void *, void *); + int32_t (*ReadID)(void *, uint32_t *); + int32_t (*GetState)(void *, void *); + int32_t (*GetMultiTouchState)(void *, void *); + int32_t (*GetGesture)(void *, void *); + int32_t (*GetCapabilities)(void *, void *); + int32_t (*EnableIT)(void *); + int32_t (*DisableIT)(void *); + int32_t (*ClearIT)(void *); + int32_t (*ITStatus)(void *); +} TS_Drv_t; + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* TS_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/Common/usbtypecswitch.h b/Drivers/STM32H7RSxx_BSP/Components/Common/usbtypecswitch.h new file mode 100644 index 0000000..ef624a9 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/Common/usbtypecswitch.h @@ -0,0 +1,112 @@ +/** + ****************************************************************************** + * @file usbtypecswitch.h + * @author MCD Application Team + * @brief This header file contains the functions prototypes for the + * crossbar switch device for USB Type-C systems. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBTYPECSWITCH_H +#define __USBTYPECSWITCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup TYPECSWITCH + * @{ + */ + +/** @defgroup TYPECSWITCH_Exported_Types + * @{ + */ +typedef enum +{ + USB_NORMAL = 0, + USB_FLIPPED, + DFP_D_PIN_ASSIGNMENT_A_NORMAL, + DFP_D_PIN_ASSIGNMENT_A_FLIPPED, + DFP_D_PIN_ASSIGNMENT_B_NORMAL, + DFP_D_PIN_ASSIGNMENT_B_FLIPPED, + DFP_D_PIN_ASSIGNMENT_C_NORMAL, + DFP_D_PIN_ASSIGNMENT_C_FLIPPED, + DFP_D_PIN_ASSIGNMENT_D_NORMAL, + DFP_D_PIN_ASSIGNMENT_D_FLIPPED, + DFP_D_PIN_ASSIGNMENT_E_NORMAL, + DFP_D_PIN_ASSIGNMENT_E_FLIPPED, + DFP_D_PIN_ASSIGNMENT_F_NORMAL, + DFP_D_PIN_ASSIGNMENT_F_FLIPPED, + UFP_D_PIN_ASSIGNMENT_A_NORMAL, + UFP_D_PIN_ASSIGNMENT_A_FLIPPED, + UFP_D_PIN_ASSIGNMENT_B_NORMAL, + UFP_D_PIN_ASSIGNMENT_B_FLIPPED, + UFP_D_PIN_ASSIGNMENT_C_NORMAL, + UFP_D_PIN_ASSIGNMENT_C_FLIPPED, + UFP_D_PIN_ASSIGNMENT_D_NORMAL, + UFP_D_PIN_ASSIGNMENT_D_FLIPPED, + UFP_D_PIN_ASSIGNMENT_E_NORMAL, + UFP_D_PIN_ASSIGNMENT_E_FLIPPED, + UFP_D_PIN_ASSIGNMENT_F_NORMAL, + UFP_D_PIN_ASSIGNMENT_F_FLIPPED +} TYPECSWITCH_Mode_t; + +/** @defgroup TYPECSWITCH_Driver_structure USB Type-C Crossbar Switch Driver structure + * @{ + */ +typedef struct +{ + uint32_t (*Init)(uint16_t); + void (*DeInit)(uint16_t); + uint32_t (*PowerOn)(uint16_t); + uint32_t (*PowerOff)(uint16_t); + uint32_t (*SetMode)(uint16_t, TYPECSWITCH_Mode_t); + uint32_t (*IsSupportedMode)(TYPECSWITCH_Mode_t); +} TYPECSWITCH_Drv_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBTYPECSWITCH_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.md b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.md new file mode 100644 index 0000000..b9d1eee --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2020(-2023) STMicroelectronics. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.txt b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/LICENSE.txt new file mode 100644 index 0000000..b40364c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/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/Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.html b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.html new file mode 100644 index 0000000..51bb243 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.html @@ -0,0 +1,110 @@ + + + + + + + Release Notes for APS256XX 16-Bits OCTOSPI Component Driver + + + + + + +
+
+
+

Release Notes for APS256XX Component Driver

+

Copyright © 2020 STMicroelectronics
+

+ +
+

Purpose

+

This driver provides a set of functions offered by APS256XX 16-Bits OCTOSPI component

+
+
+

Update History

+
+ +
+

Main Changes

+
    +
  • Set correct bit in MR6 register to enter power down
  • +
  • Correct MISRA-C 2012 warning
  • +
+
+
+
+ +
+

Main Changes

+
    +
  • Add XSPI_CCR_SIOO macro
  • +
+
+
+
+ +
+

Main Changes

+
    +
  • Update license
  • +
+
+
+
+ +
+

Main Changes

+
    +
  • Initialize sCommand structure as 0 in “Enable Memory mapped” API to avoid Issues related to non-filled sCommand field
  • +
+
+
+
+ +
+

Main Changes

+
    +
  • Code formatting and spelling
  • +
+
+
+
+ +
+

Main Changes

+
    +
  • Code formatting and spelling
  • +
  • Update memory Command configuration values
  • +
+
+
+
+ +
+

Main Changes

+
    +
  • First Official Release of APS256XX 16-bits SPI Component drivers in line with STM32Cube BSP drivers development guidelines (UM2298)
  • +
  • The component drivers are composed of +
      +
    • component core drivers files: aps256xx.h/.c
    • +
    • component configuration file: aps256xx_conf_template.h
    • +
  • +
+
+
+
+
+
+For complete documentation on STM32 Microcontrollers , visit: www.st.com +
+ + diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.md b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.md new file mode 100644 index 0000000..6212ade --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/Release_Notes.md @@ -0,0 +1,120 @@ +--- +pagetitle: Release Notes for APS256XX 16-Bits OCTOSPI Component Driver +lang: en +header-includes: +--- +::: {.row} +::: {.col-sm-12 .col-lg-4} + +
+# Release Notes for APS256XX Component Driver +Copyright © 2020 STMicroelectronics\ + +[![ST logo](_htmresc/st_logo_2020.png)](https://www.st.com){.logo} +
+ +# Purpose + +This driver provides a set of functions offered by APS256XX 16-Bits OCTOSPI component + +::: + +::: {.col-sm-12 .col-lg-8} +# Update History + +::: {.collapse} + + +
+ +## Main Changes + +- Set correct bit in MR6 register to enter power down +- Correct MISRA-C 2012 warning + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- Add XSPI_CCR_SIOO macro + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- Update license + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- Initialize sCommand structure as 0 in “Enable Memory mapped” API to avoid Issues related to non-filled sCommand field + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- Code formatting and spelling + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- Code formatting and spelling +- Update memory Command configuration values + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- First Official Release of APS256XX 16-bits SPI Component drivers in line with STM32Cube BSP drivers development guidelines (UM2298) +- The component drivers are composed of + - component core drivers files: aps256xx.h/.c + - component configuration file: aps256xx_conf_template.h + +
+::: + +::: +::: + +
+For complete documentation on STM32 Microcontrollers , +visit: [[www.st.com](http://www.st.com/STM32)]{style="font-color: blue;"} +
diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Add button.svg b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Add button.svg new file mode 100644 index 0000000..dc4a222 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Add button.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Update.svg b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Update.svg new file mode 100644 index 0000000..75b3194 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/Update.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/favicon.png b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st.css b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st.css new file mode 100644 index 0000000..1b12ad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st_2020.css b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st_2020.css new file mode 100644 index 0000000..1b12ad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/st_logo.png b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/st_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8b80057fd3a454a97de1c9d732b7fede82c83227 GIT binary patch literal 18616 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 literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/st_logo_2020.png b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/_htmresc/st_logo_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.c b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.c new file mode 100644 index 0000000..f6b9ae3 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.c @@ -0,0 +1,536 @@ +/** + ****************************************************************************** + * @file aps256xx.c + * @modify MCD Application Team + * @brief This file provides the APS256XX HSPI drivers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 "aps256xx.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup APS256XX APS256XX + * @{ + */ + +/** @defgroup APS256XX_Exported_Functions APS256XX Exported Functions + * @{ + */ + +/* Read/Write Array Commands *********************/ +/** + * @brief Reads an amount of data from the memory. + * @param Ctx Component object pointer + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @param LatencyCode Latency used for the access + * @param IOMode I/O Mode used for the access + * @param BurstType Type of burst used for the access + * @retval Memory status + */ +int32_t APS256XX_Read(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size, uint32_t LatencyCode, + uint32_t IOMode, uint32_t BurstType) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the read command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = ((BurstType == 0U) ? APS256XX_READ_LINEAR_BURST_CMD : APS256XX_READ_CMD); + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.Address = ReadAddr; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = ((IOMode == 0U) ? HAL_XSPI_DATA_8_LINES : HAL_XSPI_DATA_16_LINES); + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DataLength = Size; + sCommand.DummyCycles = (LatencyCode - 1U); + sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/** + * @brief Reads an amount of data in DMA mode from the memory. + * @param Ctx Component object pointer + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @param LatencyCode Latency used for the access + * @param IOMode I/O Mode used for the access + * @param BurstType Type of burst used for the access + * @retval Memory status + */ +int32_t APS256XX_Read_DMA(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size, + uint32_t LatencyCode, uint32_t IOMode, uint32_t BurstType) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the read command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = ((BurstType == 0U) ? APS256XX_READ_LINEAR_BURST_CMD : APS256XX_READ_CMD); + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.Address = ReadAddr; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = ((IOMode == 0U) ? HAL_XSPI_DATA_8_LINES : HAL_XSPI_DATA_16_LINES); + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DataLength = Size; + sCommand.DummyCycles = (LatencyCode - 1U); + sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive_DMA(Ctx, pData) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/** + * @brief Writes an amount of data to the memory. + * @param Ctx Component object pointer + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @param LatencyCode Latency used for the access + * @param IOMode I/O Mode used for the access + * @param BurstType Type of burst used for the access + * @retval Memory status + */ +int32_t APS256XX_Write(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size, uint32_t LatencyCode, + uint32_t IOMode, uint32_t BurstType) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the write command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = ((BurstType == 0U) ? APS256XX_WRITE_LINEAR_BURST_CMD : APS256XX_WRITE_CMD); + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.Address = WriteAddr; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = ((IOMode == 0U) ? HAL_XSPI_DATA_8_LINES : HAL_XSPI_DATA_16_LINES); + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DataLength = Size; + sCommand.DummyCycles = (LatencyCode - 1U); + sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Transmission of the data */ + if (HAL_XSPI_Transmit(Ctx, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/** + * @brief Writes an amount of data in DMA mode to the memory. + * @param Ctx Component object pointer + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @param LatencyCode Latency used for the access + * @param IOMode I/O Mode used for the access + * @param BurstType Type of burst used for the access + * @retval Memory status + */ +int32_t APS256XX_Write_DMA(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size, + uint32_t LatencyCode, uint32_t IOMode, uint32_t BurstType) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the write command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = ((BurstType == 0U) ? APS256XX_WRITE_LINEAR_BURST_CMD : APS256XX_WRITE_CMD); + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.Address = WriteAddr; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = ((IOMode == 0U) ? HAL_XSPI_DATA_8_LINES : HAL_XSPI_DATA_16_LINES); + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DataLength = Size; + sCommand.DummyCycles = (LatencyCode - 1U); + sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Transmission of the data */ + if (HAL_XSPI_Transmit_DMA(Ctx, pData) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/** + * @brief Enable memory mapped mode for the memory. + * @param Ctx Component object pointer + * @param ReadLatencyCode Latency used for the read access + * @param WriteLatencyCode Latency used for the write access + * @param IOMode I/O Mode used for the access + * @param BurstType Type of burst used for the access + * @retval Memory status + */ +int32_t APS256XX_EnableMemoryMappedMode(XSPI_HandleTypeDef *Ctx, uint32_t ReadLatencyCode, uint32_t WriteLatencyCode, + uint32_t IOMode, uint32_t BurstType) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + XSPI_MemoryMappedTypeDef sMemMappedCfg = {0}; + + /* Initialize the write command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = ((BurstType == 0U) ? APS256XX_WRITE_LINEAR_BURST_CMD : APS256XX_WRITE_CMD); + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = ((IOMode == 0U) ? HAL_XSPI_DATA_8_LINES : HAL_XSPI_DATA_16_LINES); + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DummyCycles = (WriteLatencyCode - 1U); + sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Initialize the read command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_READ_CFG; + sCommand.Instruction = ((BurstType == 0U) ? APS256XX_READ_LINEAR_BURST_CMD : APS256XX_READ_CMD); + sCommand.DummyCycles = (ReadLatencyCode - 1U); + + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Activation of memory-mapped mode */ + sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE; + + if (HAL_XSPI_MemoryMapped(Ctx, &sMemMappedCfg) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/* Register/Setting Commands **************************************************/ +/** + * @brief Read mode register value + * @param Ctx Component object pointer + * @param Address Register address + * @param Value Register value pointer + * @param LatencyCode Latency used for the access + * @retval error status + */ +int32_t APS256XX_ReadReg(XSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t *Value, uint32_t LatencyCode) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the read register command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = APS256XX_READ_REG_CMD; + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.Address = Address; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = HAL_XSPI_DATA_8_LINES; + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DataLength = 2; + sCommand.DummyCycles = (LatencyCode - 1U); + sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, (uint8_t *)Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/** + * @brief Write mode register + * @param Ctx Component object pointer + * @param Address Register address + * @param Value Value to write to register + * @retval error status + */ +int32_t APS256XX_WriteReg(XSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t Value) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the write register command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = APS256XX_WRITE_REG_CMD; + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + sCommand.Address = Address; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = HAL_XSPI_DATA_8_LINES; + sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + sCommand.DataLength = 2; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Transmission of the data */ + if (HAL_XSPI_Transmit(Ctx, (uint8_t *)(&Value), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/* ID Commands ****************************************************************/ +/** + * @brief Read Flash IDs. + * Vendor ID, Device ID, Device Density + * @param Ctx Component object pointer + * @param ID IDs pointer (2 * 8-bits value) + * @param LatencyCode Latency used for the access + * @retval error status + */ +int32_t APS256XX_ReadID(XSPI_HandleTypeDef *Ctx, uint8_t *ID, uint32_t LatencyCode) +{ + /* Read the Mode Register 1 and 2 */ + if (APS256XX_ReadReg(Ctx, APS256XX_MR1_ADDRESS, ID, LatencyCode) != APS256XX_OK) + { + return APS256XX_ERROR; + } + + /* Keep only Vendor ID from Mode Register 1 */ + *ID &= (APS256XX_MR1_VENDOR_ID); + + /* Keep only Device ID and Device Density from Mode Register 2 */ + *(ID + 1) &= (APS256XX_MR2_DEVICE_ID | APS256XX_MR2_DENSITY); + + return APS256XX_OK; +} + +/* Power down Commands ********************************************************/ +/** + * @brief Memory enter deep power-down command + * @param Ctx Component object pointer + * @retval error status + */ +int32_t APS256XX_EnterPowerDown(XSPI_HandleTypeDef *Ctx) +{ + /* Update the deep power down value of the MR6 register */ + if (APS256XX_WriteReg(Ctx, APS256XX_MR6_ADDRESS, APS256XX_MR6_HS_HALF_SPEED_MODE) != APS256XX_OK) + { + return APS256XX_ERROR; + } + + /* --- Memory enter deep power down as soon nCS goes high --- */ + /* --- At least 500us should be respected before leaving deep power down --- */ + + return APS256XX_OK; +} + +/** + * @brief Flash leave deep power-down command + * @param Ctx Component object pointer + * @param LatencyCode Latency used for the access + * @retval error status + */ +int32_t APS256XX_LeavePowerDown(XSPI_HandleTypeDef *Ctx) +{ + /* --- A dummy command is sent to the memory, as the nCS should be low for at least 60 ns --- */ + /* --- Memory takes 150us max to leave deep power down --- */ + + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = APS256XX_READ_CMD; + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + sCommand.Address = 0; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = HAL_XSPI_DATA_NONE; + sCommand.DataLength = 0; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + return APS256XX_OK; +} + +/* Reset Command **************************************************************/ +/** + * @brief Reset the memory + * @param Ctx Component object pointer + * @retval error status + */ +int32_t APS256XX_Reset(XSPI_HandleTypeDef *Ctx) +{ + XSPI_RegularCmdTypeDef sCommand = {0}; + + /* Initialize the command */ + sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + sCommand.Instruction = APS256XX_RESET_CMD; + sCommand.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS; + sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + sCommand.Address = 0; + sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + sCommand.DataMode = HAL_XSPI_DATA_NONE; + sCommand.DataLength = 0; + sCommand.DummyCycles = 0; + sCommand.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return APS256XX_ERROR; + } + + /* Need to wait tRST */ + HAL_Delay(1); + return 0/*APS256XX_OK*/; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.h b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.h new file mode 100644 index 0000000..ed5574a --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx.h @@ -0,0 +1,287 @@ +/** + ****************************************************************************** + * @file aps256xx.h + * @author MCD Application Team + * @brief This file contains all the description of the APS256XX 16bits-HSPI PSRAM memory. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 APS256XX_H +#define APS256XX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "aps256xx_conf.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup APS256XX + * @{ + */ + +/** @defgroup APS256XX_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup APS256XX_Exported_Constants + * @{ + */ + +/** + * @brief APS256XX Configuration + */ +#define APS256XX_RAM_SIZE 0x2000000U /* 256 MBits => 32 MBytes */ + +/** + * @brief APS256XX Error codes + */ +#define APS256XX_OK (0) +#define APS256XX_ERROR (-1) + +/****************************************************************************** + * @brief APS256XX Registers + ****************************************************************************/ +/* Mode Register 0 */ +#define APS256XX_MR0_ADDRESS 0x00000000U + +#define APS256XX_MR0_DRIVE_STRENGTH 0x03U /*!< Drive Strength */ +#define APS256XX_MR0_DS_FULL 0x00U /*!< Drive Strength : Full (25 Ohm) */ +#define APS256XX_MR0_DS_HALF 0x01U /*!< Drive Strength : Half (50 Ohm) */ +#define APS256XX_MR0_DS_QUART 0x02U /*!< Drive Strength : 1/4 (100 Ohm) */ +#define APS256XX_MR0_DS_EIGHT 0x03U /*!< Drive Strength : 1/8 (200 Ohm) */ + +#define APS256XX_MR0_READ_LATENCY_CODE 0x1CU /*!< Read Latency Code */ +#define APS256XX_MR0_RLC_3 0x00U /*!< Read Latency Code : 3 */ +#define APS256XX_MR0_RLC_4 0x04U /*!< Read Latency Code : 4 */ +#define APS256XX_MR0_RLC_5 0x08U /*!< Read Latency Code : 5 */ +#define APS256XX_MR0_RLC_6 0x0CU /*!< Read Latency Code : 6 */ +#define APS256XX_MR0_RLC_7 0x10U /*!< Read Latency Code : 7 */ + +#define APS256XX_MR0_LATENCY_TYPE 0x20U /*!< Latency Type */ + +/* Mode Register 1 */ +#define APS256XX_MR1_ADDRESS 0x00000001U + +#define APS256XX_MR1_VENDOR_ID 0x1FU /*!< Vendor Identifier */ +#define APS256XX_MR1_VENDOR_ID_APM 0x0DU /*!< Vendor Identifier : APM */ + +#define APS256XX_MR1_ULP 0x80U /*!< Ultra Low Power Device */ + +/* Mode Register 2 */ +#define APS256XX_MR2_ADDRESS 0x00000002U + +#define APS256XX_MR2_DENSITY 0x07U /*!< Device Density */ +#define APS256XX_MR2_DENSITY_128_MB 0x05U /*!< Device Density : 128 Mb */ +#define APS256XX_MR2_DENSITY_256_MB 0x07U /*!< Device Density : 256 Mb */ +#define APS256XX_MR2_DENSITY_512_MB 0x06U /*!< Device Density : 512 Mb */ + +#define APS256XX_MR2_DEVICE_ID 0x18U /*!< Device Identifier */ +#define APS256XX_MR2_DEVID_GEN_1 0x00U /*!< Device Identifier : Generation 1 */ +#define APS256XX_MR2_DEVID_GEN_2 0x08U /*!< Device Identifier : Generation 2 */ +#define APS256XX_MR2_DEVID_GEN_3 0x10U /*!< Device Identifier : Generation 3 */ +#define APS256XX_MR2_DEVID_GEN_4 0x18U /*!< Device Identifier : Generation 4 */ + +#define APS256XX_MR2_KGD 0xE0U /*!< Good-Die Identifier */ +#define APS256XX_MR2_KGD_GOOD_DIE_ID 0xC0U /*!< Good-Die Identifier : PASS */ + +/* Mode Register 3 */ +#define APS256XX_MR3_ADDRESS 0x00000003U + +#define APS256XX_MR3_SRF 0x30U /*!< Self Refresh Flag */ +#define APS256XX_MR3_SRF_0_5X 0x10U /*!< Self Refresh Flag : 0.5x Refresh */ +#define APS256XX_MR3_SRF_1X 0x00U /*!< Self Refresh Flag : 1x Refresh */ +#define APS256XX_MR3_SRF_4X 0x20U /*!< Self Refresh Flag : 4x Refresh */ + +#define APS256XX_MR3_RBXEN 0x80U /*!< Row Boundary Crossing Enable */ + +/* Mode Register 4 */ +#define APS256XX_MR4_ADDRESS 0x00000004U + +#define APS256XX_MR4_PASR 0x07U /*!< Partially Address Space Refresh */ +#define APS256XX_MR4_PASR_FULL 0x00U /*!< PASR : Full Array */ +#define APS256XX_MR4_PASR_BOTTOM_HALF 0x01U /*!< PASR : Bottom 1/2 Array */ +#define APS256XX_MR4_PASR_BOTTOM_QUART 0x02U /*!< PASR : Bottom 1/4 Array */ +#define APS256XX_MR4_PASR_BOTTOM_EIGHT 0x03U /*!< PASR : Bottom 1/8 Array */ +#define APS256XX_MR4_PASR_NONE 0x04U /*!< PASR : None */ +#define APS256XX_MR4_PASR_TOP_HALF 0x05U /*!< PASR : Top 1/2 Array */ +#define APS256XX_MR4_PASR_TOP_QUART 0x06U /*!< PASR : Top 1/4 Array */ +#define APS256XX_MR4_PASR_TOP_EIGHT 0x07U /*!< PASR : Top 1/8 Array */ + +#define APS256XX_MR4_RF_RATE 0x18U /*!< Refresh Frequency Setting */ +#define APS256XX_MR4_RF_4X 0x00U /*!< RF : Always 4x Refresh */ +#define APS256XX_MR4_RF_1X 0x08U /*!< RF : Enables 1x Refresh */ +#define APS256XX_MR4_RF_0_5X 0x18U /*!< RF : Enables 0.5x Refresh */ + +#define APS256XX_MR4_WRITE_LATENCY_CODE 0xE0U /*!< Write Latency Code */ +#define APS256XX_MR4_WLC_3 0x00U /*!< Write Latency Code : 3 */ +#define APS256XX_MR4_WLC_4 0x80U /*!< Write Latency Code : 4 */ +#define APS256XX_MR4_WLC_5 0x40U /*!< Write Latency Code : 5 */ +#define APS256XX_MR4_WLC_6 0xC0U /*!< Write Latency Code : 6 */ +#define APS256XX_MR4_WLC_7 0x20U /*!< Write Latency Code : 7 */ + +/* Mode Register 6 */ +#define APS256XX_MR6_ADDRESS 0x00000006U + +#define APS256XX_MR6_HALF_SLEEP 0xF0U /*!< Half Sleep */ +#define APS256XX_MR6_HS_HALF_SPEED_MODE 0xF0U /*!< Half Sleep : Half Speed Mode */ +#define APS256XX_MR6_HS_DEEP_POWER_DOWN 0xC0U /*!< Half Sleep : Deep Power Down Mode */ + +/* Mode Register 8 */ +#define APS256XX_MR8_ADDRESS 0x00000008U + +#define APS256XX_MR8_BL 0x03U /*!< Burst Length */ +#define APS256XX_MR8_BL_16_BYTES 0x00U /*!< Burst Length : 16 Byte/Word Wrap */ +#define APS256XX_MR8_BL_32_BYTES 0x01U /*!< Burst Length : 32 Byte/Word Wrap */ +#define APS256XX_MR8_BL_64_BYTES 0x02U /*!< Burst Length : 64 Byte/Word Wrap */ +#define APS256XX_MR8_BL_2K_BYTES 0x03U /*!< Burst Length : 2K Byte/1K Word Wrap */ + +#define APS256XX_MR8_BT 0x04U /*!< Burst Type */ + +#define APS256XX_MR8_RBX 0x08U /*!< Row Boundary Crossing Read Enable */ + +#define APS256XX_MR8_X8_X16 0x40U /*!< IO X8/X16 Mode */ + +/****************************************************************************** + * @brief APS256XX Commands + ****************************************************************************/ +/* Read Operations */ +#define APS256XX_READ_CMD 0x00U /*!< Synchronous Read */ +#define APS256XX_READ_LINEAR_BURST_CMD 0x20U /*!< Linear Burst Read */ + +/* Write Operations */ +#define APS256XX_WRITE_CMD 0x80U /*!< Synchronous Write */ +#define APS256XX_WRITE_LINEAR_BURST_CMD 0xA0U /*!< Linear Burst Write */ + +/* Reset Operations */ +#define APS256XX_RESET_CMD 0xFFU /*!< Global Reset */ + +/* Register Operations */ +#define APS256XX_READ_REG_CMD 0x40U /*!< Mode Register Read */ +#define APS256XX_WRITE_REG_CMD 0xC0U /*!< Mode Register Write */ + +/** + * @} + */ +/** @defgroup APS256XX_Exported_Types APS256XX Exported Types + * @{ + */ +typedef enum +{ + APS256XX_BURST_16_BYTES = APS256XX_MR8_BL_16_BYTES, + APS256XX_BURST_32_BYTES = APS256XX_MR8_BL_32_BYTES, + APS256XX_BURST_64_BYTES = APS256XX_MR8_BL_64_BYTES, + APS256XX_BURST_2_KBYTES = APS256XX_MR8_BL_2K_BYTES +} APS256XX_BurstLength_t; + +typedef enum +{ + APS256XX_READ_LATENCY_3 = APS256XX_MR0_RLC_3, + APS256XX_READ_LATENCY_4 = APS256XX_MR0_RLC_4, + APS256XX_READ_LATENCY_5 = APS256XX_MR0_RLC_5, + APS256XX_READ_LATENCY_6 = APS256XX_MR0_RLC_6, + APS256XX_READ_LATENCY_7 = APS256XX_MR0_RLC_7 +} APS256XX_ReadLatencyCode_t; + +typedef enum +{ + APS256XX_WRITE_LATENCY_3 = APS256XX_MR4_WLC_3, + APS256XX_WRITE_LATENCY_4 = APS256XX_MR4_WLC_4, + APS256XX_WRITE_LATENCY_5 = APS256XX_MR4_WLC_5, + APS256XX_WRITE_LATENCY_6 = APS256XX_MR4_WLC_6, + APS256XX_WRITE_LATENCY_7 = APS256XX_MR4_WLC_7 +} APS256XX_WriteLatencyCode_t; +/** + * @} + */ + +/** @defgroup APS256XX_Exported_Macros APS256XX Exported Macros + * @{ + */ +#define APS256XX_READ_REG_LATENCY(rlc) ((((rlc) & APS256XX_MR0_READ_LATENCY_CODE) >> 2U) + 3U) + +#define APS256XX_READ_LATENCY(rlc, type) ((((type) & APS256XX_MR0_LATENCY_TYPE) == 0U) ? \ + ((((rlc) & APS256XX_MR0_READ_LATENCY_CODE) >> 2U) + 3U) : \ + (((((rlc) & APS256XX_MR0_READ_LATENCY_CODE) >> 2U) + 3U)*2U)) + +#define APS256XX_WRITE_LATENCY(wlc) ((((wlc) & APS256XX_MR4_WRITE_LATENCY_CODE) == 0U) ? 3U : \ + ((((wlc) & APS256XX_MR4_WLC_7) != 0U) ? 7U : \ + ((((wlc) & APS256XX_MR4_WLC_5) == 0U) ? 4U : \ + ((((wlc) & APS256XX_MR4_WLC_4) == 0U) ? 5U : 6U)))) +/** + * @} + */ + +/** @defgroup APS256XX_Exported_Functions APS256XX Exported Functions + * @{ + */ +/* Read/Write Array Commands **************************************************/ +int32_t APS256XX_Read(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size, uint32_t LatencyCode, + uint32_t IOMode, uint32_t BurstType); +int32_t APS256XX_Read_DMA(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size, + uint32_t LatencyCode, uint32_t IOMode, uint32_t BurstType); +int32_t APS256XX_Write(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size, uint32_t LatencyCode, + uint32_t IOMode, uint32_t BurstType); +int32_t APS256XX_Write_DMA(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size, + uint32_t LatencyCode, uint32_t IOMode, uint32_t BurstType); +int32_t APS256XX_EnableMemoryMappedMode(XSPI_HandleTypeDef *Ctx, uint32_t ReadLatencyCode, uint32_t WriteLatencyCode, + uint32_t IOMode, uint32_t BurstType); + +/* Register/Setting Commands **************************************************/ +int32_t APS256XX_ReadReg(XSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t *Value, uint32_t LatencyCode); +int32_t APS256XX_WriteReg(XSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t Value); + +/* ID Commands ****************************************************************/ +int32_t APS256XX_ReadID(XSPI_HandleTypeDef *Ctx, uint8_t *ID, uint32_t LatencyCode); + +/* Power down Commands ********************************************************/ +int32_t APS256XX_EnterPowerDown(XSPI_HandleTypeDef *Ctx); +int32_t APS256XX_LeavePowerDown(XSPI_HandleTypeDef *Ctx); + +/* Reset Command **************************************************************/ +int32_t APS256XX_Reset(XSPI_HandleTypeDef *Ctx); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* APS256XX_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx_conf_template.h b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx_conf_template.h new file mode 100644 index 0000000..eef7b72 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/aps256xx/aps256xx_conf_template.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file aps256xx_conf.h + * @author MCD Application Team + * @brief APS256XX 16bits-OSPI PSRAM memory configuration template file. + * This file should be copied to the application folder and renamed + * to aps256xx_conf.h + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 APS256XX_CONF_H +#define APS256XX_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32xxxx_hal.h" + +/** @addtogroup BSP + * @{ + */ +#define CONF_HSPI_DS APS256XX_MR0_DS_HALF +#define CONF_HSPI_PASR APS256XX_MR4_PASR_FULL +#define CONF_HSPI_RF APS256XX_MR4_RF_4X + +#define DEFAULT_READ_LATENCY_CODE APS256XX_READ_LATENCY_5 +#define DEFAULT_WRITE_LATENCY_CODE APS256XX_WRITE_LATENCY_5 +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* APS256XX_CONF_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.md b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.md new file mode 100644 index 0000000..62c0e40 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2023 STMicroelectronics. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.txt b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/LICENSE.txt new file mode 100644 index 0000000..b40364c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/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/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.html b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.html new file mode 100644 index 0000000..754b3cc --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.html @@ -0,0 +1,61 @@ + + + + + + + Release Notes for MX66UW1G45G OCTOSPI Component Driver + + + + + + +
+
+
+

Release Notes for MX66UW1G45G Component Driver

+

Copyright © 2023 STMicroelectronics
+

+ +
+

Purpose

+

This driver provides a set of functions offered by MX66UW1G45G OCTOSPI component

+
+
+

Update History

+
+ +
+

Main Changes

+
    +
  • Add implementation of release power-down command
  • +
  • Correct DataLength in case of MX66UW1G45G_DTR_TRANSFER
  • +
+

+
+
+
+ +
+

Main Changes

+
    +
  • First official release of MX66UW1G45G octal SPI driver
  • +
+

+
+
+
+
+
+For complete documentation on STM32 Microcontrollers , visit: www.st.com +
+ + diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.md b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.md new file mode 100644 index 0000000..c4e0071 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/Release_Notes.md @@ -0,0 +1,58 @@ +--- +pagetitle: Release Notes for MX66UW1G45G OCTOSPI Component Driver +lang: en +header-includes: +--- +::: {.row} +::: {.col-sm-12 .col-lg-4} + +
+# Release Notes for MX66UW1G45G Component Driver +Copyright © 2023 STMicroelectronics\ + +[![ST logo](_htmresc/st_logo_2020.png)](https://www.st.com){.logo} +
+ +# Purpose + +This driver provides a set of functions offered by MX66UW1G45G OCTOSPI component + +::: + +::: {.col-sm-12 .col-lg-8} +# Update History + +::: {.collapse} + + +
+ +## Main Changes + +- Add implementation of release power-down command +- Correct DataLength in case of MX66UW1G45G_DTR_TRANSFER + +## +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- First official release of **MX66UW1G45G** octal SPI driver + +## +
+::: + +::: +::: + +
+For complete documentation on STM32 Microcontrollers , +visit: [[www.st.com](http://www.st.com/STM32)]{style="font-color: blue;"} +
diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Add button.svg b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Add button.svg new file mode 100644 index 0000000..dc4a222 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Add button.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Update.svg b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Update.svg new file mode 100644 index 0000000..75b3194 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/Update.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/favicon.png b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/mini-st_2020.css b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/mini-st_2020.css new file mode 100644 index 0000000..1b12ad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/st_logo_2020.png b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/_htmresc/st_logo_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.c b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.c new file mode 100644 index 0000000..8c279bf --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.c @@ -0,0 +1,1815 @@ +/** + ****************************************************************************** + * @file mx66uw1g45g.c + * @modify MCD Application Team + * @brief This file provides the MX66UW1G45G XSPI drivers. + ****************************************************************************** + * @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. + * + ****************************************************************************** + * MX66UW1G45G action : + * STR Octal IO protocol (SOPI) and DTR Octal IO protocol (DOPI) bits of + * Configuration Register 2 : + * DOPI = 1 and SOPI = 0: Operates in DTR Octal IO protocol (accepts 8-8-8 commands) + * DOPI = 0 and SOPI = 1: Operates in STR Octal IO protocol (accepts 8-8-8 commands) + * DOPI = 0 and SOPI = 0: Operates in Single IO protocol (accepts 1-1-1 commands) + * Enter SOPI mode by configuring DOPI = 0 and SOPI = 1 in CR2-Addr0 + * Exit SOPI mode by configuring DOPI = 0 and SOPI = 0 in CR2-Addr0 + * Enter DOPI mode by configuring DOPI = 1 and SOPI = 0 in CR2-Addr0 + * Exit DOPI mode by configuring DOPI = 0 and SOPI = 0 in CR2-Addr0 + * + * Memory commands support STR(Single Transfer Rate) & + * DTR(Double Transfer Rate) modes in OPI + * + * Memory commands support STR(Single Transfer Rate) & + * DTR(Double Transfer Rate) modes in SPI + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "mx66uw1g45g.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup MX66UW1G45G MX66UW1G45G + * @{ + */ + +/** @defgroup MX66UW1G45G_Exported_Functions MX66UW1G45G Exported Functions + * @{ + */ + +/** + * @brief Get Flash information + * @param pInfo pointer to information structure + * @retval error status + */ +int32_t MX66UW1G45G_GetFlashInfo(MX66UW1G45G_Info_t *pInfo) +{ + /* Configure the structure with the memory configuration */ + pInfo->FlashSize = MX66UW1G45G_FLASH_SIZE; + pInfo->EraseSectorSize = MX66UW1G45G_BLOCK_64K; + pInfo->EraseSectorsNumber = (MX66UW1G45G_FLASH_SIZE / MX66UW1G45G_BLOCK_64K); + pInfo->EraseSubSectorSize = MX66UW1G45G_BLOCK_4K; + pInfo->EraseSubSectorNumber = (MX66UW1G45G_FLASH_SIZE / MX66UW1G45G_BLOCK_4K); + pInfo->EraseSubSector1Size = MX66UW1G45G_BLOCK_4K; + pInfo->EraseSubSector1Number = (MX66UW1G45G_FLASH_SIZE / MX66UW1G45G_BLOCK_4K); + pInfo->ProgPageSize = MX66UW1G45G_PAGE_SIZE; + pInfo->ProgPagesNumber = (MX66UW1G45G_FLASH_SIZE / MX66UW1G45G_PAGE_SIZE); + + return MX66UW1G45G_OK; +}; + +/** + * @brief Polling WIP(Write In Progress) bit become to 0 + * SPI/OPI; + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate + * @retval error status + */ +int32_t MX66UW1G45G_AutoPollingMemReady(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + XSPI_AutoPollingTypeDef s_config = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Configure automatic polling mode to wait for memory ready */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_STATUS_REG_CMD + : MX66UW1G45G_OCTA_READ_STATUS_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 0U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : ((Rate == MX66UW1G45G_DTR_TRANSFER) + ? DUMMY_CYCLES_REG_OCTAL_DTR + : DUMMY_CYCLES_REG_OCTAL); + s_command.DataLength = (Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + s_config.MatchValue = 0U; + s_config.MatchMask = MX66UW1G45G_SR_WIP; + s_config.MatchMode = HAL_XSPI_MATCH_MODE_AND; + s_config.IntervalTime = MX66UW1G45G_AUTOPOLLING_INTERVAL_TIME; + s_config.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE; + + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + if (HAL_XSPI_AutoPolling(Ctx, &s_config, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/* Read/Write Array Commands (3/4 Byte Address Command Set) *********************/ +/** + * @brief Reads an amount of data from the XSPI memory on STR mode. + * SPI/OPI; 1-1-1/8-8-8 + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param AddressWidth Address size + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval XSPI memory status + */ +int32_t MX66UW1G45G_ReadSTR(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_AddressWidth_t AddressWidth, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* OPI mode and 3-bytes address size not supported by memory */ + if ((Mode == MX66UW1G45G_OPI_MODE) && (AddressWidth == MX66UW1G45G_3BYTES_SIZE)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the read command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? ((AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? MX66UW1G45G_FAST_READ_CMD + : MX66UW1G45G_4_BYTE_ADDR_FAST_READ_CMD) + : MX66UW1G45G_OCTA_READ_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_ADDRESS_1_LINE + : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = (AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? HAL_XSPI_ADDRESS_24_BITS + : HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = ReadAddr; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) ? DUMMY_CYCLES_READ : DUMMY_CYCLES_READ_OCTAL; + s_command.DataLength = Size; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Reads an amount of data from the XSPI memory on DTR mode. + * OPI + * @param Ctx Component object pointer + * @param AddressWidth Address size + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @note Only OPI mode support DTR transfer rate + * @retval XSPI memory status + */ +int32_t MX66UW1G45G_ReadDTR(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* Initialize the read command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE; + s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = MX66UW1G45G_OCTA_READ_DTR_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = ReadAddr; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_command.DummyCycles = DUMMY_CYCLES_READ_OCTAL_DTR; + s_command.DataLength = Size; + s_command.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Writes an amount of data to the XSPI memory. + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param AddressWidth Address size + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write. Range 1 ~ MX66UW1G45G_PAGE_SIZE + * @note Address size is forced to 3 Bytes when the 4 Bytes address size + * command is not available for the specified interface mode + * @retval XSPI memory status + */ +int32_t MX66UW1G45G_PageProgram(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_AddressWidth_t AddressWidth, uint8_t *pData, uint32_t WriteAddr, + uint32_t Size) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* OPI mode and 3-bytes address size not supported by memory */ + if ((Mode == MX66UW1G45G_OPI_MODE) && (AddressWidth == MX66UW1G45G_3BYTES_SIZE)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the program command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? ((AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? MX66UW1G45G_PAGE_PROG_CMD + : MX66UW1G45G_4_BYTE_PAGE_PROG_CMD) + : MX66UW1G45G_OCTA_PAGE_PROG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_ADDRESS_1_LINE + : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = (AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? HAL_XSPI_ADDRESS_24_BITS + : HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = WriteAddr; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = 0U; + s_command.DataLength = Size; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Transmission of the data */ + if (HAL_XSPI_Transmit(Ctx, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Writes an amount of data to the XSPI memory on DTR mode. + * SPI/OPI + * @param Ctx Component object pointer + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write. Range 1 ~ MX66UW1G45G_PAGE_SIZE + * @note Only OPI mode support DTR transfer rate + * @retval XSPI memory status + */ +int32_t MX66UW1G45G_PageProgramDTR(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* Initialize the program command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE; + s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = MX66UW1G45G_OCTA_PAGE_PROG_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = WriteAddr; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_command.DummyCycles = 0U; + s_command.DataLength = Size; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Transmission of the data */ + if (HAL_XSPI_Transmit(Ctx, pData, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Erases the specified block of the XSPI memory. + * MX66UW1G45G support 4K, 64K size block erase commands. + * SPI/OPI; 1-1-1/8-8-8 + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param AddressWidth Address size + * @param BlockAddress Block address to erase + * @param BlockSize Block size to erase + * @retval XSPI memory status + */ + +int32_t MX66UW1G45G_BlockErase(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate, + MX66UW1G45G_AddressWidth_t AddressWidth, uint32_t BlockAddress, + MX66UW1G45G_Erase_t BlockSize) +{ + + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the erase command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.IOSelect = HAL_XSPI_SELECT_IO_7_0; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_1_LINE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = (AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? HAL_XSPI_ADDRESS_24_BITS + : HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = BlockAddress; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + switch (Mode) + { + case MX66UW1G45G_OPI_MODE : + if (BlockSize == MX66UW1G45G_ERASE_64K) + { + s_command.Instruction = MX66UW1G45G_OCTA_BLOCK_ERASE_64K_CMD; + } + else + { + s_command.Instruction = MX66UW1G45G_OCTA_SECTOR_ERASE_4K_CMD; + } + break; + + case MX66UW1G45G_SPI_MODE : + default: + if (BlockSize == MX66UW1G45G_ERASE_64K) + { + s_command.Instruction = (AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? MX66UW1G45G_BLOCK_ERASE_64K_CMD + : MX66UW1G45G_4_BYTE_BLOCK_ERASE_64K_CMD; + } + else + { + s_command.Instruction = (AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? MX66UW1G45G_SECTOR_ERASE_4K_CMD + : MX66UW1G45G_4_BYTE_SECTOR_ERASE_4K_CMD; + } + break; + } + + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + + return MX66UW1G45G_OK; +} + +/** + * @brief Whole chip erase. + * SPI/OPI; 1-0-0/8-0-0 + * @param Ctx Component object pointer + * @param Mode Interface mode + * @retval error status + */ +int32_t MX66UW1G45G_ChipErase(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the erase command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_BULK_ERASE_CMD + : MX66UW1G45G_OCTA_BULK_ERASE_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Enable memory mapped mode for the XSPI memory on STR mode. + * SPI/OPI; 1-1-1/8-8-8 + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param AddressWidth Address size + * @retval XSPI memory status + */ +int32_t MX66UW1G45G_EnableSTRMemoryMappedMode(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_AddressWidth_t AddressWidth) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + XSPI_MemoryMappedTypeDef s_mem_mapped_cfg = {0}; + + /* OPI mode and 3-bytes address size not supported by memory */ + if ((Mode == MX66UW1G45G_OPI_MODE) && (AddressWidth == MX66UW1G45G_3BYTES_SIZE)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the read command */ + s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? ((AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? MX66UW1G45G_FAST_READ_CMD + : MX66UW1G45G_4_BYTE_ADDR_FAST_READ_CMD) + : MX66UW1G45G_OCTA_READ_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_1_LINE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = (AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? HAL_XSPI_ADDRESS_24_BITS + : HAL_XSPI_ADDRESS_32_BITS; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) ? DUMMY_CYCLES_READ : DUMMY_CYCLES_READ_OCTAL; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the read command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the program command */ + s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? ((AddressWidth == MX66UW1G45G_3BYTES_SIZE) + ? MX66UW1G45G_PAGE_PROG_CMD + : MX66UW1G45G_4_BYTE_PAGE_PROG_CMD) + : MX66UW1G45G_OCTA_PAGE_PROG_CMD; + s_command.DummyCycles = 0U; + + /* Send the write command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Configure the memory mapped mode */ + s_mem_mapped_cfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE; + + if (HAL_XSPI_MemoryMapped(Ctx, &s_mem_mapped_cfg) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Enable memory mapped mode for the XSPI memory on DTR mode. + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param AddressWidth Address size + * @note Only OPI mode support DTR transfer rate + * @retval XSPI memory status + */ +int32_t MX66UW1G45G_EnableDTRMemoryMappedMode(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Mode); + + XSPI_RegularCmdTypeDef s_command = {0}; + XSPI_MemoryMappedTypeDef s_mem_mapped_cfg = {0}; + + /* Initialize the read command */ + s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG; + s_command.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE; + s_command.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = MX66UW1G45G_OCTA_READ_DTR_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_command.DummyCycles = DUMMY_CYCLES_READ_OCTAL_DTR; + s_command.DQSMode = HAL_XSPI_DQS_ENABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the program command */ + s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG; + s_command.Instruction = MX66UW1G45G_OCTA_PAGE_PROG_CMD; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + /* Configure the memory mapped mode */ + s_mem_mapped_cfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE; + + if (HAL_XSPI_MemoryMapped(Ctx, &s_mem_mapped_cfg) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Flash suspend program or erase command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_Suspend(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the suspend command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_PROG_ERASE_SUSPEND_CMD + : MX66UW1G45G_OCTA_PROG_ERASE_SUSPEND_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Flash resume program or erase command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_Resume(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the resume command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_PROG_ERASE_RESUME_CMD + : MX66UW1G45G_OCTA_PROG_ERASE_RESUME_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/* Register/Setting Commands **************************************************/ +/** + * @brief This function send a Write Enable and wait it is effective. + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_WriteEnable(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + XSPI_AutoPollingTypeDef s_config = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the write enable command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_WRITE_ENABLE_CMD + : MX66UW1G45G_OCTA_WRITE_ENABLE_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Configure automatic polling mode to wait for write enabling */ + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_STATUS_REG_CMD + : MX66UW1G45G_OCTA_READ_STATUS_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 0U; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DATA_DTR_ENABLE : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : ((Rate == MX66UW1G45G_DTR_TRANSFER) + ? DUMMY_CYCLES_REG_OCTAL_DTR + : DUMMY_CYCLES_REG_OCTAL); + s_command.DataLength = (Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + s_config.MatchValue = 2U; + s_config.MatchMask = 2U; + s_config.MatchMode = HAL_XSPI_MATCH_MODE_AND; + s_config.IntervalTime = MX66UW1G45G_AUTOPOLLING_INTERVAL_TIME; + s_config.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE; + + if (HAL_XSPI_AutoPolling(Ctx, &s_config, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief This function reset the (WEN) Write Enable Latch bit. + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_WriteDisable(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the write disable command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_WRITE_DISABLE_CMD + : MX66UW1G45G_OCTA_WRITE_DISABLE_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Read Flash Status register value + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value Status register value pointer + * @retval error status + */ +int32_t MX66UW1G45G_ReadStatusRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t *Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the reading of status register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_STATUS_REG_CMD + : MX66UW1G45G_OCTA_READ_STATUS_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 0U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : ((Rate == MX66UW1G45G_DTR_TRANSFER) + ? DUMMY_CYCLES_REG_OCTAL_DTR + : DUMMY_CYCLES_REG_OCTAL); + s_command.DataLength = (Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Write Flash Status register + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value Value to write to Status register + * @retval error status + */ +int32_t MX66UW1G45G_WriteStatusRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + uint8_t reg[2]; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* In SPI mode, the status register is configured with configuration register */ + if (Mode == MX66UW1G45G_SPI_MODE) + { + if (MX66UW1G45G_ReadCfgRegister(Ctx, Mode, Rate, ®[1]) != MX66UW1G45G_OK) + { + return MX66UW1G45G_ERROR; + } + } + reg[0] = Value; + + /* Initialize the writing of status register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_WRITE_STATUS_REG_CMD + : MX66UW1G45G_OCTA_WRITE_STATUS_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 0U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = 0U; + s_command.DataLength = (Mode == MX66UW1G45G_SPI_MODE) ? 2U : ((Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U); + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + if (HAL_XSPI_Transmit(Ctx, reg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Write Flash configuration register + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value Value to write to configuration register + * @retval error status + */ +int32_t MX66UW1G45G_WriteCfgRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + uint8_t reg[2]; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* In SPI mode, the configuration register is configured with status register */ + if (Mode == MX66UW1G45G_SPI_MODE) + { + if (MX66UW1G45G_ReadStatusRegister(Ctx, Mode, Rate, ®[0]) != MX66UW1G45G_OK) + { + return MX66UW1G45G_ERROR; + } + reg[1] = Value; + } + else + { + reg[0] = Value; + } + + /* Initialize the writing of configuration register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_WRITE_STATUS_REG_CMD + : MX66UW1G45G_OCTA_WRITE_STATUS_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 1U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = 0U; + s_command.DataLength = (Mode == MX66UW1G45G_SPI_MODE) ? 2U : ((Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U); + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + if (HAL_XSPI_Transmit(Ctx, reg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Read Flash configuration register value + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value configuration register value pointer + * @retval error status + */ +int32_t MX66UW1G45G_ReadCfgRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t *Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the reading of configuration register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_CFG_REG_CMD + : MX66UW1G45G_OCTA_READ_CFG_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 1U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : ((Rate == MX66UW1G45G_DTR_TRANSFER) + ? DUMMY_CYCLES_REG_OCTAL_DTR + : DUMMY_CYCLES_REG_OCTAL); + s_command.DataLength = (Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Write Flash configuration register 2 + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value Value to write to configuration register + * @retval error status + */ +int32_t MX66UW1G45G_WriteCfg2Register(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint32_t WriteAddr, uint8_t Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the writing of configuration register 2 */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_WRITE_CFG_REG2_CMD + : MX66UW1G45G_OCTA_WRITE_CFG_REG2_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_1_LINE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = WriteAddr; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = 0U; + s_command.DataLength = (Mode == MX66UW1G45G_SPI_MODE) ? 1U : ((Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U); + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + if (HAL_XSPI_Transmit(Ctx, &Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Read Flash configuration register 2 value + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value configuration register 2 value pointer + * @retval error status + */ +int32_t MX66UW1G45G_ReadCfg2Register(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint32_t ReadAddr, uint8_t *Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the reading of status register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_CFG_REG2_CMD + : MX66UW1G45G_OCTA_READ_CFG_REG2_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_1_LINE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = ReadAddr; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : ((Rate == MX66UW1G45G_DTR_TRANSFER) + ? DUMMY_CYCLES_REG_OCTAL_DTR + : DUMMY_CYCLES_REG_OCTAL); + s_command.DataLength = (Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Write Flash Security register + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value Value to write to Security register + * @retval error status + */ +int32_t MX66UW1G45G_WriteSecurityRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t Value) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Value); + + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the write of security register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_WRITE_SECURITY_REG_CMD + : MX66UW1G45G_OCTA_WRITE_SECURITY_REG_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Read Flash Security register value + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param Rate Transfer rate STR or DTR + * @param Value Security register value pointer + * @retval error status + */ +int32_t MX66UW1G45G_ReadSecurityRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t *Value) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the reading of security register */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_SECURITY_REG_CMD + : MX66UW1G45G_OCTA_READ_SECURITY_REG_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_ADDRESS_NONE : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 0U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_DATA_DTR_ENABLE + : HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : ((Rate == MX66UW1G45G_DTR_TRANSFER) + ? DUMMY_CYCLES_REG_OCTAL_DTR + : DUMMY_CYCLES_REG_OCTAL); + s_command.DataLength = (Rate == MX66UW1G45G_DTR_TRANSFER) ? 2U : 1U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/* ID Commands ****************************************************************/ +/** + * @brief Read Flash 3 Byte IDs. + * Manufacturer ID, Memory type, Memory density + * SPI/OPI; 1-0-1/1-0-8 + * @param Ctx Component object pointer + * @param Mode Interface mode + * @param ID 3 bytes IDs pointer + * @param DualFlash Dual flash mode state + * @retval error status + */ +int32_t MX66UW1G45G_ReadID(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate, + uint8_t *ID) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the read ID command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_READ_ID_CMD + : MX66UW1G45G_OCTA_READ_ID_CMD; + s_command.AddressMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_ADDRESS_NONE + : HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_ADDRESS_DTR_ENABLE + : HAL_XSPI_ADDRESS_DTR_DISABLE; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = 0U; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = (Mode == MX66UW1G45G_SPI_MODE) ? HAL_XSPI_DATA_1_LINE : HAL_XSPI_DATA_8_LINES; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_command.DummyCycles = (Mode == MX66UW1G45G_SPI_MODE) + ? 0U + : DUMMY_CYCLES_REG_OCTAL; + s_command.DataLength = 3U; + s_command.DQSMode = (Rate == MX66UW1G45G_DTR_TRANSFER) ? HAL_XSPI_DQS_ENABLE : HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Configure the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + /* Reception of the data */ + if (HAL_XSPI_Receive(Ctx, ID, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/* Reset Commands *************************************************************/ +/** + * @brief Flash reset enable command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_ResetEnable(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the reset enable command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.IOSelect = HAL_XSPI_SELECT_IO_3_0; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_RESET_ENABLE_CMD + : MX66UW1G45G_OCTA_RESET_ENABLE_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Flash reset memory command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_ResetMemory(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the reset enable command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_RESET_MEMORY_CMD + : MX66UW1G45G_OCTA_RESET_MEMORY_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Flash no operation command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_NoOperation(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the no operation command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) ? MX66UW1G45G_NOP_CMD : MX66UW1G45G_OCTA_NOP_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Flash enter deep power-down command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_EnterPowerDown(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the enter power down command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_ENTER_DEEP_POWER_DOWN_CMD + : MX66UW1G45G_OCTA_ENTER_DEEP_POWER_DOWN_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @brief Flash release deep power-down command + * SPI/OPI + * @param Ctx Component object pointer + * @param Mode Interface select + * @param Rate Transfer rate STR or DTR + * @retval error status + */ +int32_t MX66UW1G45G_ReleasePowerDown(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate) +{ + XSPI_RegularCmdTypeDef s_command = {0}; + + /* SPI mode and DTR transfer not supported by memory */ + if ((Mode == MX66UW1G45G_SPI_MODE) && (Rate == MX66UW1G45G_DTR_TRANSFER)) + { + return MX66UW1G45G_ERROR; + } + + /* Initialize the enter power down command */ + s_command.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG; + + s_command.InstructionMode = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_1_LINE + : HAL_XSPI_INSTRUCTION_8_LINES; + s_command.InstructionDTRMode = (Rate == MX66UW1G45G_DTR_TRANSFER) + ? HAL_XSPI_INSTRUCTION_DTR_ENABLE + : HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_command.InstructionWidth = (Mode == MX66UW1G45G_SPI_MODE) + ? HAL_XSPI_INSTRUCTION_8_BITS + : HAL_XSPI_INSTRUCTION_16_BITS; + s_command.Instruction = (Mode == MX66UW1G45G_SPI_MODE) + ? MX66UW1G45G_RELEASE_DEEP_POWER_DOWN_CMD + : MX66UW1G45G_OCTA_RELEASE_DEEP_POWER_DOWN_CMD; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0U; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + #if defined (XSPI_CCR_SIOO) + s_command.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD; + #endif + + /* Send the command */ + if (HAL_XSPI_Command(Ctx, &s_command, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return MX66UW1G45G_ERROR; + } + + return MX66UW1G45G_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.h b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.h new file mode 100644 index 0000000..cf5d71a --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g.h @@ -0,0 +1,384 @@ +/** + ****************************************************************************** + * @file mx66uw1g45g.h + * @modify MCD Application Team + * @brief This file contains all the description of the + * MX66UW1G45G XSPI memory. + ****************************************************************************** + * @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 MX66UW1G45G_H +#define MX66UW1G45G_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "mx66uw1g45g_conf.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup MX66UW1G45G + * @{ + */ +/** @defgroup MX66UW1G45G_Exported_Constants MX66UW1G45G Exported Constants + * @{ + */ + +/** + * @brief MX66UW1G45G Size configuration + */ +#define MX66UW1G45G_BLOCK_64K (uint32_t)(64 * 1024) /* 1024 blocks of 64KBytes */ +#define MX66UW1G45G_BLOCK_4K (uint32_t)(4 * 1024) /* 16384 sectors of 4KBytes */ + +#define MX66UW1G45G_FLASH_SIZE (uint32_t)(1024*1024*1024/8) /* 1 Gbits => 128MBytes */ +#define MX66UW1G45G_PAGE_SIZE (uint32_t)256 /* 262144 pages of 256 Bytes */ + +/** + * @brief MX66UW1G45G Timing configuration + */ + +#define MX66UW1G45G_BULK_ERASE_MAX_TIME 460000U +#define MX66UW1G45G_BLOCK_ERASE_MAX_TIME 1000U +#define MX66UW1G45G_BLOCK_4K_ERASE_MAX_TIME 400U +#define MX66UW1G45G_WRITE_REG_MAX_TIME 40U + +#define MX66UW1G45G_RESET_MAX_TIME 100U /* when SWreset during erase operation */ + +#define MX66UW1G45G_AUTOPOLLING_INTERVAL_TIME 0x10U + +/** + * @brief MX66UW1G45G Error codes + */ +#define MX66UW1G45G_OK (0) +#define MX66UW1G45G_ERROR (-1) + +/** + * @brief re-definition of legacy memory mapped functions + */ +#define MX66UW1G45G_EnableMemoryMappedModeDTR MX66UW1G45G_EnableDTRMemoryMappedMode +#define MX66UW1G45G_EnableMemoryMappedModeSTR MX66UW1G45G_EnableSTRMemoryMappedMode + + +/****************************************************************************** + * @brief MX66UW1G45G Commands + ****************************************************************************/ + +/*******************************************************************/ +/********************************* SPI ****************************/ +/*******************************************************************/ + +/***** READ/WRITE MEMORY Operations with 3-Byte Address ****************************/ +#define MX66UW1G45G_READ_CMD 0x03U /*!< Normal Read 3 Byte Address */ +#define MX66UW1G45G_FAST_READ_CMD 0x0BU /*!< Fast Read 3 Byte Address */ +#define MX66UW1G45G_PAGE_PROG_CMD 0x02U /*!< Page Program 3 Byte Address */ +#define MX66UW1G45G_SECTOR_ERASE_4K_CMD 0x20U /*!< SubSector Erase 4KB 3 Byte Address */ +#define MX66UW1G45G_BLOCK_ERASE_64K_CMD 0xD8U /*!< Sector Erase 64KB 3 Byte Address */ +#define MX66UW1G45G_BULK_ERASE_CMD 0x60U /*!< Bulk Erase */ + +/***** READ/WRITE MEMORY Operations with 4-Byte Address ****************************/ +#define MX66UW1G45G_4_BYTE_ADDR_READ_CMD 0x13U /*!< Normal Read 4 Byte address */ +#define MX66UW1G45G_4_BYTE_ADDR_FAST_READ_CMD 0x0CU /*!< Fast Read 4 Byte address */ +#define MX66UW1G45G_4_BYTE_PAGE_PROG_CMD 0x12U /*!< Page Program 4 Byte Address */ +#define MX66UW1G45G_4_BYTE_SECTOR_ERASE_4K_CMD 0x21U /*!< SubSector Erase 4KB 4 Byte Address */ +#define MX66UW1G45G_4_BYTE_BLOCK_ERASE_64K_CMD 0xDCU /*!< Sector Erase 64KB 4 Byte Address */ + +/***** Setting commands ************************************************************/ +#define MX66UW1G45G_WRITE_ENABLE_CMD 0x06U /*!< Write Enable */ +#define MX66UW1G45G_WRITE_DISABLE_CMD 0x04U /*!< Write Disable */ +#define MX66UW1G45G_PROG_ERASE_SUSPEND_CMD 0xB0U /*!< Program/Erase suspend */ +#define MX66UW1G45G_PROG_ERASE_RESUME_CMD 0x30U /*!< Program/Erase resume */ +#define MX66UW1G45G_ENTER_DEEP_POWER_DOWN_CMD 0xB9U /*!< Enter deep power down */ +#define MX66UW1G45G_RELEASE_DEEP_POWER_DOWN_CMD 0xABU /*!< Release from deep power down */ +#define MX66UW1G45G_SET_BURST_LENGTH_CMD 0xC0U /*!< Set burst length */ +#define MX66UW1G45G_ENTER_SECURED_OTP_CMD 0xB1U /*!< Enter secured OTP) */ +#define MX66UW1G45G_EXIT_SECURED_OTP_CMD 0xC1U /*!< Exit secured OTP) */ + +/***** RESET commands ************************************************************/ +#define MX66UW1G45G_NOP_CMD 0x00U /*!< No operation */ +#define MX66UW1G45G_RESET_ENABLE_CMD 0x66U /*!< Reset Enable */ +#define MX66UW1G45G_RESET_MEMORY_CMD 0x99U /*!< Reset Memory */ + +/***** Register Commands (SPI) ****************************************************/ +#define MX66UW1G45G_READ_ID_CMD 0x9FU /*!< Read IDentification */ +#define MX66UW1G45G_READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5AU /*!< Read Serial Flash Discoverable Parameter */ +#define MX66UW1G45G_READ_STATUS_REG_CMD 0x05U /*!< Read Status Register */ +#define MX66UW1G45G_READ_CFG_REG_CMD 0x15U /*!< Read configuration Register */ +#define MX66UW1G45G_WRITE_STATUS_REG_CMD 0x01U /*!< Write Status Register */ +#define MX66UW1G45G_READ_CFG_REG2_CMD 0x71U /*!< Read configuration Register2 */ +#define MX66UW1G45G_WRITE_CFG_REG2_CMD 0x72U /*!< Write configuration Register2 */ +#define MX66UW1G45G_READ_FAST_BOOT_REG_CMD 0x16U /*!< Read fast boot Register */ +#define MX66UW1G45G_WRITE_FAST_BOOT_REG_CMD 0x17U /*!< Write fast boot Register */ +#define MX66UW1G45G_ERASE_FAST_BOOT_REG_CMD 0x18U /*!< Erase fast boot Register */ +#define MX66UW1G45G_READ_SECURITY_REG_CMD 0x2BU /*!< Read security Register */ +#define MX66UW1G45G_WRITE_SECURITY_REG_CMD 0x2FU /*!< Write security Register */ +#define MX66UW1G45G_READ_LOCK_REG_CMD 0x2DU /*!< Read lock Register */ +#define MX66UW1G45G_WRITE_LOCK_REG_CMD 0x2CU /*!< Write lock Register */ + +#define MX66UW1G45G_READ_DPB_REG_CMD 0xE0U /*!< Read DPB register */ +#define MX66UW1G45G_WRITE_DPB_REG_CMD 0xE1U /*!< Write DPB register */ +#define MX66UW1G45G_READ_SPB_STATUS_CMD 0xE2U /*!< Read SPB status */ +#define MX66UW1G45G_WRITE_SPB_BIT_CMD 0xE3U /*!< SPB bit program */ +#define MX66UW1G45G_ERASE_ALL_SPB_CMD 0xE4U /*!< Erase all SPB bit */ +#define MX66UW1G45G_WRITE_PROTECT_SEL_CMD 0x68U /*!< Write Protect selection */ +#define MX66UW1G45G_GANG_BLOCK_LOCK_CMD 0x7EU /*!< Gang block lock: whole chip write protect */ +#define MX66UW1G45G_GANG_BLOCK_UNLOCK_CMD 0x98U /*!< Gang block unlock: whole chip write unprotect */ +#define MX66UW1G45G_READ_PASSWORD_REGISTER_CMD 0x27U /*!< Read Password */ +#define MX66UW1G45G_WRITE_PASSWORD_REGISTER_CMD 0x28U /*!< Write Password */ +#define MX66UW1G45G_PASSWORD_UNLOCK_CMD 0x29U /*!< Unlock Password */ + + +/*******************************************************************/ +/********************************* OPI ****************************/ +/*******************************************************************/ + +/***** READ/WRITE MEMORY Operations ****************************/ +#define MX66UW1G45G_OCTA_READ_CMD 0xEC13U /*!< Octa IO Read */ +#define MX66UW1G45G_OCTA_READ_DTR_CMD 0xEE11U /*!< Octa IO Read DTR */ +#define MX66UW1G45G_OCTA_PAGE_PROG_CMD 0x12EDU /*!< Octa Page Program */ +#define MX66UW1G45G_OCTA_SECTOR_ERASE_4K_CMD 0x21DEU /*!< Octa SubSector Erase 4KB */ +#define MX66UW1G45G_OCTA_BLOCK_ERASE_64K_CMD 0xDC23U /*!< Octa Sector Erase 64KB 3 */ +#define MX66UW1G45G_OCTA_BULK_ERASE_CMD 0x609FU /*!< Octa Bulk Erase */ + +/***** Setting commands ************************************************************/ +#define MX66UW1G45G_OCTA_WRITE_ENABLE_CMD 0x06F9U /*!< Octa Write Enable */ +#define MX66UW1G45G_OCTA_WRITE_DISABLE_CMD 0x04FBU /*!< Octa Write Disable */ +#define MX66UW1G45G_OCTA_PROG_ERASE_SUSPEND_CMD 0xB04FU /*!< Octa Program/Erase suspend */ +#define MX66UW1G45G_OCTA_PROG_ERASE_RESUME_CMD 0x30CFU /*!< Octa Program/Erase resume */ +#define MX66UW1G45G_OCTA_ENTER_DEEP_POWER_DOWN_CMD 0xB946U /*!< Octa Enter deep power down */ +#define MX66UW1G45G_OCTA_RELEASE_DEEP_POWER_DOWN_CMD 0xAB54U /*!< Octa Release from deep power down */ +#define MX66UW1G45G_OCTA_SET_BURST_LENGTH_CMD 0xC03FU /*!< Octa Set burst length */ +#define MX66UW1G45G_OCTA_ENTER_SECURED_OTP_CMD 0xB14EU /*!< Octa Enter secured OTP) */ +#define MX66UW1G45G_OCTA_EXIT_SECURED_OTP_CMD 0xC13EU /*!< Octa Exit secured OTP) */ + +/***** RESET commands ************************************************************/ +#define MX66UW1G45G_OCTA_NOP_CMD 0x00FFU /*!< Octa No operation */ +#define MX66UW1G45G_OCTA_RESET_ENABLE_CMD 0x6699U /*!< Octa Reset Enable */ +#define MX66UW1G45G_OCTA_RESET_MEMORY_CMD 0x9966U /*!< Octa Reset Memory */ + +/***** Register Commands (OPI) ****************************************************/ +#define MX66UW1G45G_OCTA_READ_ID_CMD 0x9F60U /*!< Octa Read IDentification */ +#define MX66UW1G45G_OCTA_READ_SERIAL_FLASH_DISCO_PARAM_CMD 0x5AA5U /*!< Octa Read Serial Flash Discoverable Parameter */ +#define MX66UW1G45G_OCTA_READ_STATUS_REG_CMD 0x05FAU /*!< Octa Read Status Register */ +#define MX66UW1G45G_OCTA_READ_CFG_REG_CMD 0x15EAU /*!< Octa Read configuration Register */ +#define MX66UW1G45G_OCTA_WRITE_STATUS_REG_CMD 0x01FEU /*!< Octa Write Status Register */ +#define MX66UW1G45G_OCTA_READ_CFG_REG2_CMD 0x718EU /*!< Octa Read configuration Register2 */ +#define MX66UW1G45G_OCTA_WRITE_CFG_REG2_CMD 0x728DU /*!< Octa Write configuration Register2 */ +#define MX66UW1G45G_OCTA_READ_FAST_BOOT_REG_CMD 0x16E9U /*!< Octa Read fast boot Register */ +#define MX66UW1G45G_OCTA_WRITE_FAST_BOOT_REG_CMD 0x17E8U /*!< Octa Write fast boot Register */ +#define MX66UW1G45G_OCTA_ERASE_FAST_BOOT_REG_CMD 0x18E7U /*!< Octa Erase fast boot Register */ +#define MX66UW1G45G_OCTA_READ_SECURITY_REG_CMD 0x2BD4U /*!< Octa Read security Register */ +#define MX66UW1G45G_OCTA_WRITE_SECURITY_REG_CMD 0x2FD0U /*!< Octa Write security Register */ +#define MX66UW1G45G_OCTA_READ_LOCK_REG_CMD 0x2DD2U /*!< Octa Read lock Register */ +#define MX66UW1G45G_OCTA_WRITE_LOCK_REG_CMD 0x2CD3U /*!< Octa Write lock Register */ +#define MX66UW1G45G_OCTA_READ_DPB_REG_CMD 0xE01FU /*!< Octa Read DPB register */ +#define MX66UW1G45G_OCTA_WRITE_DPB_REG_CMD 0xE11EU /*!< Octa Write DPB register */ +#define MX66UW1G45G_OCTA_READ_SPB_STATUS_CMD 0xE21DU /*!< Octa Read SPB status */ +#define MX66UW1G45G_OCTA_WRITE_SPB_BIT_CMD 0xE31CU /*!< Octa SPB bit program */ +#define MX66UW1G45G_OCTA_ERASE_ALL_SPB_CMD 0xE41BU /*!< Octa Erase all SPB bit */ +#define MX66UW1G45G_OCTA_WRITE_PROTECT_SEL_CMD 0x6897U /*!< Octa Write Protect selection */ +#define MX66UW1G45G_OCTA_GANG_BLOCK_LOCK_CMD 0x7E81U /*!< Octa Gang block lock: whole chip write protect */ +#define MX66UW1G45G_OCTA_GANG_BLOCK_UNLOCK_CMD 0x9867U /*!< Octa Gang block unlock: whole chip write unprote*/ +#define MX66UW1G45G_OCTA_READ_PASSWORD_REGISTER_CMD 0x27D8U /*!< Octa Read Password */ +#define MX66UW1G45G_OCTA_WRITE_PASSWORD_REGISTER_CMD 0x28D7U /*!< Octa Write Password */ +#define MX66UW1G45G_OCTA_PASSWORD_UNLOCK_CMD 0x29D6U /*!< Octa Unlock Password */ + +/****************************************************************************** + * @brief MX66UW1G45G Registers + ****************************************************************************/ +/* Status Register */ +#define MX66UW1G45G_SR_WIP 0x01U /*!< Write in progress */ +#define MX66UW1G45G_SR_WEL 0x02U /*!< Write enable latch */ +#define MX66UW1G45G_SR_PB 0x3CU /*!< Block protected against program and erase operations */ + +/* Configuration Register 1 */ +#define MX66UW1G45G_CR1_ODS 0x07U /*!< Output driver strength */ +#define MX66UW1G45G_CR1_TB 0x08U /*!< Top / bottom selected */ +#define MX66UW1G45G_CR1_PBE 0x10U /*!< Preamble bit enable */ + +/* Configuration Register 2 */ +/* Address : 0x00000000 */ +#define MX66UW1G45G_CR2_REG1_ADDR 0x00000000U /*!< CR2 register address 0x00000000 */ +#define MX66UW1G45G_CR2_SOPI 0x01U /*!< STR OPI Enable */ +#define MX66UW1G45G_CR2_DOPI 0x02U /*!< DTR OPI Enable */ +/* Address : 0x00000200 */ +#define MX66UW1G45G_CR2_REG2_ADDR 0x00000200U /*!< CR2 register address 0x00000200 */ +#define MX66UW1G45G_CR2_DQSPRC 0x01U /*!< DTR DQS pre-cycle */ +#define MX66UW1G45G_CR2_DOS 0x02U /*!< DQS on STR mode */ +/* Address : 0x00000300 */ +#define MX66UW1G45G_CR2_REG3_ADDR 0x00000300U /*!< CR2 register address 0x00000300 */ +#define MX66UW1G45G_CR2_DC 0x07U /*!< Dummy cycle */ +#define MX66UW1G45G_CR2_DC_20_CYCLES 0x00U /*!< 20 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_18_CYCLES 0x01U /*!< 18 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_16_CYCLES 0x02U /*!< 16 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_14_CYCLES 0x03U /*!< 14 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_12_CYCLES 0x04U /*!< 12 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_10_CYCLES 0x05U /*!< 10 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_8_CYCLES 0x06U /*!< 8 Dummy cycles */ +#define MX66UW1G45G_CR2_DC_6_CYCLES 0x07U /*!< 6 Dummy cycles */ +/* Address : 0x00000500 */ +#define MX66UW1G45G_CR2_REG4_ADDR 0x00000500U /*!< CR2 register address 0x00000500 */ +#define MX66UW1G45G_CR2_PPTSEL 0x01U /*!< Preamble pattern selection */ +/* Address : 0x40000000 */ +#define MX66UW1G45G_CR2_REG5_ADDR 0x40000000U /*!< CR2 register address 0x40000000 */ +#define MX66UW1G45G_CR2_DEFSOPI 0x01U /*!< Enable SOPI after power on reset */ +#define MX66UW1G45G_CR2_DEFDOPI 0x02U /*!< Enable DOPI after power on reset */ + +/* Security Register */ +#define MX66UW1G45G_SECR_SOI 0x01U /*!< Secured OTP indicator */ +#define MX66UW1G45G_SECR_LDSO 0x02U /*!< Lock-down secured OTP */ +#define MX66UW1G45G_SECR_PSB 0x04U /*!< Program suspend bit */ +#define MX66UW1G45G_SECR_ESB 0x08U /*!< Erase suspend bit */ +#define MX66UW1G45G_SECR_P_FAIL 0x20U /*!< Program fail flag */ +#define MX66UW1G45G_SECR_E_FAIL 0x40U /*!< Erase fail flag */ +#define MX66UW1G45G_SECR_WPSEL 0x80U /*!< Write protection selection */ + +#define XSPI_ALTERNATE_BYTE_PATTERN 0x00U + +/** + * @} + */ + +/** @defgroup MX66UW1G45G_Exported_Types MX66UW1G45G Exported Types + * @{ + */ +typedef struct +{ + uint32_t FlashSize; /*!< Size of the flash */ + uint32_t EraseSectorSize; /*!< Size of sectors for the erase operation */ + uint32_t EraseSectorsNumber; /*!< Number of sectors for the erase operation */ + uint32_t EraseSubSectorSize; /*!< Size of subsector for the erase operation */ + uint32_t EraseSubSectorNumber; /*!< Number of subsector for the erase operation */ + uint32_t EraseSubSector1Size; /*!< Size of subsector 1 for the erase operation */ + uint32_t EraseSubSector1Number; /*!< Number of subsector 1 for the erase operation */ + uint32_t ProgPageSize; /*!< Size of pages for the program operation */ + uint32_t ProgPagesNumber; /*!< Number of pages for the program operation */ +} MX66UW1G45G_Info_t; + +typedef enum +{ + MX66UW1G45G_SPI_MODE = 0, /*!< 1-1-1 commands, Power on H/W default setting */ + MX66UW1G45G_OPI_MODE /*!< 8-8-8 commands */ +} MX66UW1G45G_Interface_t; + +typedef enum +{ + MX66UW1G45G_STR_TRANSFER = 0, /*!< Single Transfer Rate */ + MX66UW1G45G_DTR_TRANSFER /*!< Double Transfer Rate */ +} MX66UW1G45G_Transfer_t; + +typedef enum +{ + MX66UW1G45G_ERASE_4K = 0, /*!< 4K size Sector erase */ + MX66UW1G45G_ERASE_64K, /*!< 64K size Block erase */ + MX66UW1G45G_ERASE_BULK /*!< Whole bulk erase */ +} MX66UW1G45G_Erase_t; + +typedef enum +{ + MX66UW1G45G_3BYTES_SIZE = 0, /*!< 3 Bytes address mode */ + MX66UW1G45G_4BYTES_SIZE /*!< 4 Bytes address mode */ +} MX66UW1G45G_AddressWidth_t; + +/** + * @} + */ + +/** @defgroup MX66UW1G45G_Exported_Functions MX66UW1G45G Exported Functions + * @{ + */ +/* Function by commands combined */ +int32_t MX66UW1G45G_GetFlashInfo(MX66UW1G45G_Info_t *pInfo); +int32_t MX66UW1G45G_AutoPollingMemReady(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate); + +/* Read/Write Array Commands **************************************************/ +int32_t MX66UW1G45G_ReadSTR(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_AddressWidth_t AddressWidth, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +int32_t MX66UW1G45G_ReadDTR(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +int32_t MX66UW1G45G_PageProgram(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_AddressWidth_t AddressWidth, uint8_t *pData, uint32_t WriteAddr, + uint32_t Size); +int32_t MX66UW1G45G_PageProgramDTR(XSPI_HandleTypeDef *Ctx, uint8_t *pData, uint32_t WriteAddr, uint32_t Size); +int32_t MX66UW1G45G_BlockErase(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate, + MX66UW1G45G_AddressWidth_t AddressWidth, uint32_t BlockAddress, + MX66UW1G45G_Erase_t BlockSize); +int32_t MX66UW1G45G_ChipErase(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_EnableMemoryMappedModeSTR(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_AddressWidth_t AddressWidth); +int32_t MX66UW1G45G_EnableMemoryMappedModeDTR(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode); +int32_t MX66UW1G45G_Suspend(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_Resume(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); + +/* Register/Setting Commands **************************************************/ +int32_t MX66UW1G45G_WriteEnable(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_WriteDisable(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_ReadStatusRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t *Value); +int32_t MX66UW1G45G_WriteStatusRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t Value); +int32_t MX66UW1G45G_WriteCfgRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t Value); +int32_t MX66UW1G45G_ReadCfgRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t *Value); +int32_t MX66UW1G45G_WriteCfg2Register(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint32_t WriteAddr, uint8_t Value); +int32_t MX66UW1G45G_ReadCfg2Register(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint32_t ReadAddr, uint8_t *Value); +int32_t MX66UW1G45G_WriteSecurityRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t Value); +int32_t MX66UW1G45G_ReadSecurityRegister(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate, uint8_t *Value); + +/* ID/Security Commands *******************************************************/ +int32_t MX66UW1G45G_ReadID(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate, + uint8_t *ID); + +/* Reset Commands *************************************************************/ +int32_t MX66UW1G45G_ResetEnable(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_ResetMemory(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_NoOperation(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_EnterPowerDown(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate); +int32_t MX66UW1G45G_ReleasePowerDown(XSPI_HandleTypeDef *Ctx, MX66UW1G45G_Interface_t Mode, + MX66UW1G45G_Transfer_t Rate); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* MX66UW1G45G_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g_conf_template.h b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g_conf_template.h new file mode 100644 index 0000000..15d62cd --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/mx66uw1g45g/mx66uw1g45g_conf_template.h @@ -0,0 +1,51 @@ +/** + ****************************************************************************** + * @file mx66uw1g45g_conf.h + * @author MCD Application Team + * @brief MX66UW1G45G OctoSPI memory configuration template file. + * This file should be copied to the application folder and renamed + * to mx66uw1g45g_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 MX66UW1G45G_CONF_H +#define MX66UW1G45G_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32xxxx_hal.h" + +/** @addtogroup BSP + * @{ + */ +#define CONF_OSPI_ODS MX66UW1G45G_CR_ODS_24 /* MX66UW1G45G Output Driver Strength */ + +#define DUMMY_CYCLES_READ 8U +#define DUMMY_CYCLES_READ_OCTAL 6U +#define DUMMY_CYCLES_READ_OCTAL_DTR 6U +#define DUMMY_CYCLES_REG_OCTAL 4U +#define DUMMY_CYCLES_REG_OCTAL_DTR 5U + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* MX66UW1G45G_CONF_H */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.md b/Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.md new file mode 100644 index 0000000..35b37ca --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2023 STMicroelectronics. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.txt b/Drivers/STM32H7RSxx_BSP/Components/wm8904/LICENSE.txt new file mode 100644 index 0000000..b40364c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/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/Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.html b/Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.html new file mode 100644 index 0000000..229e6fe --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.html @@ -0,0 +1,98 @@ + + + + + + + Release Notes for WM8904 Audio Codec Component Driver + + + + + +
+
+
+

Release Notes for +WM8904 Component Driver

+

Copyright © 2024 STMicroelectronics
+

+ +
+

Purpose

+

This driver provides a set of audio functions offered by WM8904 Codec +component

+
+
+

Update History

+
+ + +

Main Changes

+
    +
  • Maintenance release of WM8904 Audio Codec +driver
  • +
  • Changes compared with V1.1.0 release +
      +
    • Reduce excessive initialization delay by checking stabilization +ready flag instead of waiting a fixed time
    • +
    • Update initialization to use output device passed as parameter +instead of current device which is not yet initialized
    • +
  • +
+
+
+ + +

Main Changes

+
    +
  • First maintenance release of WM8904 Audio Codec +driver
  • +
  • Changes compared with V1.0.0 release +
      +
    • Update input devices to be defined as bitfields
    • +
    • Implement LINE_IN2 and digital microphone path
    • +
    • Add 24KHz audio frequency support
    • +
    • Update IsInitialized variable at the end of init function +WM8904_Init()
    • +
  • +
+
+
+ + +

Main Changes

+
    +
  • First official release of WM8904 Audio Codec +driver
  • +
+
+
+
+
+For complete documentation on STM32 Microcontrollers , +visit: www.st.com +
+ + diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.md b/Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.md new file mode 100644 index 0000000..8e3ca12 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/Release_Notes.md @@ -0,0 +1,75 @@ +--- +pagetitle: Release Notes for WM8904 Audio Codec Component Driver +lang: en +header-includes: +--- +::: {.row} +::: {.col-sm-12 .col-lg-4} + +
+# Release Notes for WM8904 Component Driver +Copyright © 2024 STMicroelectronics\ + +[![ST logo](_htmresc/st_logo_2020.png)](https://www.st.com){.logo} +
+ +# Purpose + +This driver provides a set of audio functions offered by WM8904 Codec component + +::: + +::: {.col-sm-12 .col-lg-8} +# Update History + +::: {.collapse} + + +
+ +## Main Changes + +- Maintenance release of **WM8904** Audio Codec driver +- Changes compared with V1.1.0 release + - Reduce excessive initialization delay by checking stabilization ready flag instead of waiting a fixed time + - Update initialization to use output device passed as parameter instead of current device which is not yet initialized + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- First maintenance release of **WM8904** Audio Codec driver +- Changes compared with V1.0.0 release + - Update input devices to be defined as bitfields + - Implement LINE_IN2 and digital microphone path + - Add 24KHz audio frequency support + - Update IsInitialized variable at the end of init function WM8904_Init() + +
+::: + +::: {.collapse} + + +
+ +## Main Changes + +- First official release of **WM8904** Audio Codec driver + +
+::: + +::: +::: + +
+For complete documentation on STM32 Microcontrollers , +visit: [[www.st.com](http://www.st.com/STM32)]{style="font-color: blue;"} +
diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Add button.svg b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Add button.svg new file mode 100644 index 0000000..dc4a222 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Add button.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Update.svg b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Update.svg new file mode 100644 index 0000000..75b3194 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/Update.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/favicon.png b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/mini-st_2020.css b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/mini-st_2020.css new file mode 100644 index 0000000..1b12ad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/st_logo_2020.png b/Drivers/STM32H7RSxx_BSP/Components/wm8904/_htmresc/st_logo_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.c b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.c new file mode 100644 index 0000000..dfb442c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.c @@ -0,0 +1,1045 @@ +/** + ****************************************************************************** + * @file wm8904.c + * @author MCD Application Team + * @brief This file provides the WM8904 Audio Codec 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 "wm8904.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @defgroup WM8904 WM8904 + * @brief This file provides a set of functions needed to drive the + * WM8904 audio codec. + * @{ + */ + +/** @defgroup WM8904_Exported_Variables Exported Variables + * @{ + */ +/* Audio codec driver structure initialization */ +WM8904_Drv_t WM8904_Driver = +{ + WM8904_Init, + WM8904_DeInit, + WM8904_ReadID, + WM8904_Play, + WM8904_Pause, + WM8904_Resume, + WM8904_Stop, + WM8904_SetFrequency, + WM8904_GetFrequency, + WM8904_SetVolume, + WM8904_GetVolume, + WM8904_SetMute, + WM8904_SetOutputMode, + WM8904_SetResolution, + WM8904_GetResolution, + WM8904_SetProtocol, + WM8904_GetProtocol, + WM8904_Reset +}; +/** + * @} + */ + +/** @defgroup WM8904_Private_Macros Private Macros + * @{ + */ +#define VOLUME_OUT_CONVERT(Volume) (((Volume) >= 100U) ? 63U : ((uint8_t)((((Volume) / 2U) + 13U)))) +#define VOLUME_OUT_INVERT(Volume) ((uint8_t)(((Volume) - 13U) * 2U)) +/** + * @} + */ + +/** @defgroup WM8904_Private_Variables Private Variables + * @{ + */ +static uint32_t WM8904_CurrentDevices = WM8904_OUT_NONE; +/** + * @} + */ + +/** @defgroup WM8904_Private_Functions Private Functions + * @{ + */ +static int32_t WM8904_ReadRegWrap(void *handle, uint16_t Reg, uint8_t* Data, uint16_t Length); +static int32_t WM8904_WriteRegWrap(void *handle, uint16_t Reg, uint8_t* Data, uint16_t Length); +static void WM8904_Delay(const WM8904_Object_t *pObj, uint32_t Delay); +/** + * @} + */ + +/** @defgroup WM8904_Exported_Functions Exported Functions + * @{ + */ +/** + * @brief Initializes the audio codec and the control interface. + * @param pObj pointer to component object + * @param pInit pointer de component init structure + * @retval 0 if correct communication, else wrong communication + */ +int32_t WM8904_Init(WM8904_Object_t *pObj, WM8904_Init_t *pInit) +{ + int32_t ret = WM8904_OK; + uint16_t tmp; + uint8_t iter_count; + + if (pObj->IsInitialized == 1U) + { + ret += WM8904_DeInit(pObj); + } + + /*********/ + /* Reset */ + /*********/ + + tmp = 0x0U; /* Reset registers */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_SW_RESET, &tmp, 2U); + + /**************/ + /* Clock rate */ + /**************/ + + tmp = 0x0004U; /* CLK_SYS_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES2, &tmp, 2U); + + /**************************************/ + /* Reference voltages and master bias */ + /**************************************/ + + tmp = 0x0018U; /* ISEL[1:0] = 10b, BIAS_EN = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_BIAS_CONTROL0, &tmp, 2U); + + tmp = 0x0047U; /* VMID_BUF_ENA = 1, VMID_RES[1:0] = 11b, VMID_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_VMID_CONTROL0, &tmp, 2U); + WM8904_Delay(pObj, 100U); + + tmp = 0x0043U; /* VMID_BUF_ENA = 1, VMID_RES[1:0] = 01b, VMID_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_VMID_CONTROL0, &tmp, 2U); + + tmp = 0x0019U; /* ISEL[1:0] = 10b, BIAS_EN = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_BIAS_CONTROL0, &tmp, 2U); + + /********************/ + /* Mic BIAS control */ + /********************/ + + tmp = 0x0001U; /* MICBIAS_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_MIC_BIAS_CONTROL0, &tmp, 2U); + + /**********************/ + /* Power management */ + /**********************/ + + if (pInit->InputDevice == WM8904_IN_LINE2) + { + tmp = 0x0003U; /* INL_ENA = INR_ENA = 1 */ + } + else if (pInit->InputDevice == WM8904_IN_MIC1) + { + tmp = 0x0002U; /* INL_ENA = 1 */ + } + else /* WM8904_IN_DIGITAL_MIC2 */ + { + tmp = 0x0000U; /* INx_ENA = 0 */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_PWR_MANAGEMENT0, &tmp, 2U); + + tmp = 0x0003U; /* HPL_PGA_ENA = HPR_PGA_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_PWR_MANAGEMENT2, &tmp, 2U); + + /**************/ + /* Clock rate */ + /**************/ + + tmp = 0x0006U; /* CLK_DSP_ENA = CLK_SYS_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES2, &tmp, 2U); + + /**************/ + /* DAC and ADC*/ + /**************/ + + if (pInit->InputDevice == WM8904_IN_LINE2) + { + tmp = 0x000FU; /* ADCR_ENA = ADCL_ENA = DACL_ENA = DACR_ENA = 1 */ + } + else if (pInit->InputDevice == WM8904_IN_MIC1) + { + tmp = 0x000EU; /* ADCL_ENA = DACL_ENA = DACR_ENA = 1, ADCR_ENA = 0 */ + } + else /* WM8904_IN_DIGITAL_MIC2 */ + { + tmp = 0x000EU; /* ADCL_ENA = DACL_ENA = DACR_ENA = 1, ADCR_ENA = 0 */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_PWR_MANAGEMENT6, &tmp, 2U); + + if (pInit->InputDevice == WM8904_IN_DIGITAL_MIC2) + { + tmp = 0x1800U; /* DMIC_ENA = 1, DMIC_SRC = IN1R/DMICDAT2 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DIGITAL_MICROPHONE0, &tmp, 2U); + + tmp = 0x0008U; /* GPIO1_PU = GPIO1_PD = 0, GPIO1_SEL = 8 (DMIC clock out) */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_GPIO_CONTROL1, &tmp, 2U); + + tmp = 0x81AFU; /* DRC_ENA = 1, DRC_DAC_PATH = ADC */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DRC0, &tmp, 2U); + + tmp = 0x32C1U; /* DRC_MINGAIN = 0dB, DRC_MAXGAIN = 18dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DRC1, &tmp, 2U); + + tmp = 0x002CU; /* DRC_HIGH_COMP = DRC_LO_COMP = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DRC2, &tmp, 2U); + + if (pInit->Frequency >= WM8904_FREQUENCY_32K) + { + tmp = 0x0000U; /* ADC_OSR128 = 0 (64xfs) */ + } + else + { + tmp = 0x0001U; /* ADC_OSR128 = 1 (128xfs) */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_ADC0, &tmp, 2U); + } + else + { + tmp = 0x0000U; /* DMIC_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DIGITAL_MICROPHONE0, &tmp, 2U); + + tmp = 0x0014U; /* GPIO1_PU = GPIO1_PD = 1, GPIO1_SEL = 4 (IRQ, default value) */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_GPIO_CONTROL1, &tmp, 2U); + + tmp = 0x01AFU; /* DRC_ENA = 0, DRC_DAC_PATH = ADC */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DRC0, &tmp, 2U); + + tmp = 0x0001U; /* ADC_OSR128 = 1 (128xfs) */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_ADC0, &tmp, 2U); + } + + tmp = 0x0648U; /* DAC_MUTERATE = DAC_UNMUTE_RAMP = DAC_OSR128 = DAC_MUTE = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DAC_DIGITAL1, &tmp, 2U); + + if (pInit->InputDevice == WM8904_IN_LINE2) + { + tmp = 0x0050U; /* AIFADCL_SRC = 0 (Left), AIFADCR_SRC = 1 (Right) */ + } + else if (pInit->InputDevice == WM8904_IN_MIC1) + { + tmp = 0x0010U; /* AIFADCL_SRC = 0 (Left), AIFADCR_SRC = 0 (left) */ + } + else /* WM8904_IN_DIGITAL_MIC2 */ + { + tmp = 0x0010U; /* AIFADCL_SRC = 0 (Left), AIFADCR_SRC = 0 (Left) */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_AUDIO_INTERFACE0, &tmp, 2U); + + /**********************************************/ + /* Resolution, protocol, frequency and volume */ + /**********************************************/ + + tmp = 0x0002U; /* Set resolution to 16B and protocol to I2S*/ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_AUDIO_INTERFACE1, &tmp, 2U); + + ret += WM8904_SetFrequency(pObj, pInit->Frequency); + + if (pInit->OutputDevice == WM8904_OUT_HEADPHONE) + { + ret += WM8904_SetVolume(pObj, VOLUME_OUTPUT, (uint8_t)pInit->Volume); + } + + if (pInit->InputDevice == WM8904_IN_LINE2) + { + tmp = 0x01C0U; /* ADC_VU = 1, ADC_VOL = +0dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ADC_DIGITAL_VOL_LEFT, &tmp, 2U); + + tmp = 0x01C0U; /* ADC_VU = 1, ADC_VOL = +0dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ADC_DIGITAL_VOL_RIGHT, &tmp, 2U); + + tmp = 0x0080U; /* LINMUTE = 1, LIN_VOL = -1.5dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT0, &tmp, 2U); + + tmp = 0x0080U; /* LINMUTE = 1, LIN_VOL = -1.5dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_RIGHT_INPUT0, &tmp, 2U); + + tmp = 0x0014U; /* INL_CM_ENA = 0, L_IP_SEL_N[1:0] = IN2L (01b) */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT1, &tmp, 2U); + + tmp = 0x0014U; /* INR_CM_ENA = 0, R_IP_SEL_N[1:0] = IN2R (01b) */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_RIGHT_INPUT1, &tmp, 2U); + } + else if (pInit->InputDevice == WM8904_IN_MIC1) + { + tmp = 0x01FFU; /* ADC_VU = 1, ADC_VOL = +17dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ADC_DIGITAL_VOL_LEFT, &tmp, 2U); + + tmp = 0x009AU; /* LINMUTE = 1, LIN_VOL = +14dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT0, &tmp, 2U); + + tmp = 0x0044U; /* INL_CM_ENA = 1, L_IP_SEL_N[1:0] = IN1L (00b) */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT1, &tmp, 2U); + } + else /* WM8904_IN_DIGITAL_MIC2 */ + { + tmp = 0x0100U; /* ADC_VU = 1, ADC_VOL = Mute */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ADC_DIGITAL_VOL_LEFT, &tmp, 2U); + } + + /***************/ + /* Charge pump */ + /***************/ + + tmp = 0x0001U; /* CP_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CHARGE_PUMP0, &tmp, 2U); + + /**********************/ + /* Output signal path */ + /**********************/ + + tmp = 0x0011U; /* HPL_ENA = HPR_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_HP0, &tmp, 2U); + + tmp = 0x0033U; /* HPL_ENA_DLY = HPR_ENA_DLY = HPL_ENA = HPR_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_HP0, &tmp, 2U); + + /************/ + /* DC Servo */ + /************/ + + tmp = 0x0003U; /* Enable channels 0 and 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DC_SERVO0, &tmp, 2U); + + tmp = 0x0030U; /* Startup 0 and 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DC_SERVO1, &tmp, 2U); + + iter_count = 0; + tmp = 0x0000U; + while(((tmp & 0x0003U) != 0x0003U) && (iter_count < 30U)) /* Wait DC Servo start-up completion */ + { + iter_count ++; + WM8904_Delay(pObj, 10U); + ret += wm8904_read_reg(&pObj->Ctx, WM8904_DC_SERVO_READBACK0, &tmp, 2U); + } + + /**********************/ + /* Output signal path */ + /**********************/ + + tmp = 0x0077U; /* HPL_ENA_OUTP= HPL_ENA_OUTR = HPL_ENA_DLY = HPR_ENA_DLY = HPL_ENA = HPR_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_HP0, &tmp, 2U); + + tmp = 0x00FFU; /* HPL_RMV_SHORT = HPR_RMV_SHORT = HPL_ENA_OUTP= HPL_ENA_OUTR = HPL_ENA_DLY = HPR_ENA_DLY = HPL_ENA = HPR_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_HP0, &tmp, 2U); + + /***************/ + /* Charge pump */ + /***************/ + + tmp = 0x01U; /* CP_DYN_PWR = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CLASS_W0, &tmp, 2U); + + /* Store current devices */ + WM8904_CurrentDevices = (pInit->OutputDevice | pInit->InputDevice); + + pObj->IsInitialized = 1U; + + return ret; +} + +/** + * @brief Deinitializes the audio codec. + * @param pObj pointer to component object + * @retval Component status + */ +int32_t WM8904_DeInit(WM8904_Object_t *pObj) +{ + int32_t ret; + uint16_t tmp; + + /**********************/ + /* Output signal path */ + /**********************/ + + tmp = 0x0077U; /* HPL_RMV_SHORT = HPR_RMV_SHORT = 0 */ + ret = wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_HP0, &tmp, 2U); + + tmp = 0x0000U; /* HPL_ENA_OUTP= HPL_ENA_OUTR = HPL_ENA_DLY = HPR_ENA_DLY = HPL_ENA = HPR_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_HP0, &tmp, 2U); + + /************/ + /* DC Servo */ + /************/ + + tmp = 0x0000U; /* Disable channels 0 and 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DC_SERVO0, &tmp, 2U); + + /***************/ + /* Charge pump */ + /***************/ + + tmp = 0x0000U; /* CP_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CHARGE_PUMP0, &tmp, 2U); + + /*******/ + /* DAC */ + /*******/ + + tmp = 0x0000U; /* ADCL_ENA = DACL_ENA = DACR_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_PWR_MANAGEMENT6, &tmp, 2U); + + /**************/ + /* Clock rate */ + /**************/ + + tmp = 0x0004U; /* CLK_DSP_ENA = 0, CLK_SYS_ENA = 1 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES2, &tmp, 2U); + + /**********************/ + /* Output signal path */ + /**********************/ + + tmp = 0x0000U; /* HPL_PGA_ENA = HPR_PGA_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_PWR_MANAGEMENT2, &tmp, 2U); + + tmp = 0x0000U; /* INL_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_PWR_MANAGEMENT0, &tmp, 2U); + + /********************/ + /* Mic BIAS control */ + /********************/ + + tmp = 0x0000U; /* MICBIAS_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_MIC_BIAS_CONTROL0, &tmp, 2U); + + /**************************************/ + /* Reference voltages and master bias */ + /**************************************/ + + tmp = 0x0018U; /* ISEL[1:0] = 10b, BIAS_EN = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_BIAS_CONTROL0, &tmp, 2U); + + tmp = 0x0042U; /* VMID_BUF_ENA = 1, VMID_RES[1:0] = 01b, VMID_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_VMID_CONTROL0, &tmp, 2U); + WM8904_Delay(pObj, 300U); + + tmp = 0x0042U; /* VMID_BUF_ENA = 1, VMID_RES[1:0] = 01b, VMID_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_VMID_CONTROL0, &tmp, 2U); + + tmp = 0x0000U; /* VMID_BUF_ENA = 0, VMID_RES[1:0] = 00b, VMID_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_VMID_CONTROL0, &tmp, 2U); + + tmp = 0x0018U; /* ISEL[1:0] = 10b, BIAS_EN = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_BIAS_CONTROL0, &tmp, 2U); + + /**************/ + /* Clock rate */ + /**************/ + + tmp = 0x0000U; /* CLK_SYS_ENA = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES2, &tmp, 2U); + + if (pObj->IsInitialized == 1U) + { + pObj->IsInitialized = 0U; + } + + return ret; +} + +/** + * @brief Get the WM8904 ID. + * @param pObj pointer to component object + * @param Id component ID + * @retval Component status + */ +int32_t WM8904_ReadID(WM8904_Object_t *pObj, uint32_t *Id) +{ + int32_t ret; + uint16_t wm8904_id; + + /* Initialize the Control interface of the Audio Codec */ + pObj->IO.Init(); + + /* Get ID from component */ + ret = wm8904_read_reg(&pObj->Ctx, WM8904_SW_RESET, &wm8904_id, 2U); + + *Id = wm8904_id; + + return ret; +} + +/** + * @brief Start the audio Codec play feature. + * @note For this codec no Play options are required. + * @param pObj pointer to component object + * @retval Component status + */ +int32_t WM8904_Play(WM8904_Object_t *pObj) +{ + int32_t ret = WM8904_OK; + uint16_t tmp; + + if ((WM8904_CurrentDevices & WM8904_OUT_HEADPHONE) == WM8904_OUT_HEADPHONE) + { + tmp = 0x0640U; /* DAC_MUTE= 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DAC_DIGITAL1, &tmp, 2U); + } + + + if ((WM8904_CurrentDevices & WM8904_IN_MIC1) == WM8904_IN_MIC1) + { + tmp = 0x001AU; /* LINMUTE = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT0, &tmp, 2U); + } + + if ((WM8904_CurrentDevices & WM8904_IN_LINE2) == WM8904_IN_LINE2) + { + tmp = 0x0000U; /* LINMUTE = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT0, &tmp, 2U); + + tmp = 0x0000U; /* LINMUTE = 0 */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_RIGHT_INPUT0, &tmp, 2U); + } + + if ((WM8904_CurrentDevices & WM8904_IN_DIGITAL_MIC2) == WM8904_IN_DIGITAL_MIC2) + { + tmp = 0x01F0U; /* ADC_VU = 1, ADC_VOL = +17,6dB */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ADC_DIGITAL_VOL_LEFT, &tmp, 2U); + } + + return ret; +} + +/** + * @brief Pauses playing on the audio codec. + * @param pObj pointer to component object + * @retval Component status + */ +int32_t WM8904_Pause(WM8904_Object_t *pObj) +{ + /* Pause the audio file playing */ + return WM8904_SetMute(pObj, WM8904_MUTE_ON); +} + +/** + * @brief Resumes playing on the audio codec. + * @param pObj pointer to component object + * @retval Component status + */ +int32_t WM8904_Resume(WM8904_Object_t *pObj) +{ + /* Resumes the audio file playing */ + return WM8904_SetMute(pObj, WM8904_MUTE_OFF); +} + +/** + * @brief Stops audio Codec playing. It powers down the codec. + * @param pObj pointer to component object + * @param CodecPdwnMode selects the power down mode. + * - WM8904_PDWN_SW: only mutes the audio codec. When resuming from this + * mode the codec keeps the previous initialization + * (no need to re-Initialize the codec registers). + * - WM8904_PDWN_HW: Physically power down the codec. When resuming from this + * mode, the codec is set to default configuration + * (user should re-Initialize the codec in order to + * play again the audio stream). + * @retval 0 if correct communication, else wrong communication + */ +int32_t WM8904_Stop(WM8904_Object_t *pObj, uint32_t CodecPdwnMode) +{ + int32_t ret; + + /* Mute the output */ + ret = WM8904_SetMute(pObj, WM8904_MUTE_ON); + + if (CodecPdwnMode == WM8904_PDWN_HW) + { + ret += WM8904_DeInit(pObj); + } + + return ret; +} + +/** + * @brief Set higher or lower the codec volume level. + * @param pObj pointer to component object + * @param InputOutput Input or Output volume + * @param Volume a byte value from 0 to 100. + * (refer to codec registers description for more details). + * @retval Component status + */ +int32_t WM8904_SetVolume(WM8904_Object_t *pObj, uint32_t InputOutput, uint8_t Volume) +{ + uint8_t convertedvol; + int32_t ret; + uint16_t tmp; + + /* Only output volume supported */ + if (InputOutput == VOLUME_OUTPUT) + { + convertedvol = VOLUME_OUT_CONVERT(Volume); + + tmp = (uint16_t) convertedvol; + + /* Left Headphone Volume */ + ret = wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_OUTPUT1_LEFT, &tmp, 2U); + /* Right Headphone Volume */ + tmp |= 0x80U; /* Volume update */ + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_OUTPUT1_RIGHT, &tmp, 2U); + } + else /* Input volume */ + { + ret = WM8904_ERROR; + } + + return ret; +} + +/** + * @brief Get higher or lower the codec volume level. + * @param pObj pointer to component object + * @param InputOutput Input or Output volume + * @param Volume audio volume + * @retval Component status + */ +int32_t WM8904_GetVolume(WM8904_Object_t *pObj, uint32_t InputOutput, uint8_t *Volume) +{ + int32_t ret; + uint16_t tmp; + + /* only output volume supported */ + if (InputOutput == VOLUME_OUTPUT) + { + /* Left Headphone Volume */ + ret = wm8904_read_reg(&pObj->Ctx, WM8904_ANALOG_OUTPUT1_LEFT, &tmp, 2U); + tmp &= 0x3FU; + + if (ret == WM8904_OK) + { + *Volume = (uint8_t) VOLUME_OUT_INVERT(tmp); + } + } + else /* Input volume */ + { + ret = WM8904_ERROR; + } + + return ret; +} + +/** + * @brief Enables or disables the mute feature on the audio codec. + * @param pObj pointer to component object + * @param Cmd WM8904_MUTE_ON to enable the mute or WM8904_MUTE_OFF to disable the + * mute mode. + * @retval 0 if correct communication, else wrong communication + */ +int32_t WM8904_SetMute(WM8904_Object_t *pObj, uint32_t Cmd) +{ + int32_t ret = WM8904_OK; + uint16_t tmp; + + if ((WM8904_CurrentDevices & WM8904_OUT_HEADPHONE) == WM8904_OUT_HEADPHONE) + { + /* Read DAC digital 1 */ + ret += wm8904_read_reg(&pObj->Ctx, WM8904_DAC_DIGITAL1, &tmp, 2U); + + if(Cmd == WM8904_MUTE_ON) + { + /* Mute the DAC Digital 1 */ + tmp |= 0x0008U; + } + else + { + /* Unmute the the DAC Digital 1 */ + tmp &= ~(0x0008U); + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_DAC_DIGITAL1, &tmp, 2U); + } + + if ((WM8904_CurrentDevices & WM8904_IN_MIC1) == WM8904_IN_MIC1) + { + if(Cmd == WM8904_MUTE_ON) + { + tmp = 0x009AU; /* LINMUTE = 1 */ + } + else + { + tmp = 0x001AU; /* LINMUTE = 0 */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT0, &tmp, 2U); + } + + if ((WM8904_CurrentDevices & WM8904_IN_LINE2) == WM8904_IN_LINE2) + { + if(Cmd == WM8904_MUTE_ON) + { + tmp = 0x0080U; /* LINMUTE = 1 */ + } + else + { + tmp = 0x0000U; /* LINMUTE = 0 */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_LEFT_INPUT0, &tmp, 2U); + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ANALOG_RIGHT_INPUT0, &tmp, 2U); + } + + if ((WM8904_CurrentDevices & WM8904_IN_DIGITAL_MIC2) == WM8904_IN_DIGITAL_MIC2) + { + if(Cmd == WM8904_MUTE_ON) + { + tmp = 0x0100U; /* ADC_VU = 1, ADC_VOL = Mute */ + } + else + { + tmp = 0x01F0U; /* ADC_VU = 1, ADC_VOL = +17,6dB */ + } + ret += wm8904_write_reg(&pObj->Ctx, WM8904_ADC_DIGITAL_VOL_RIGHT, &tmp, 2U); + } + + return ret; +} + +/** + * @brief Switch dynamically (while audio file is played) the output target + * (speaker or headphone). + * @param pObj pointer to component object + * @param Output specifies the audio output target: WM8904_OUT_HEADPHONE, + * WM8904_OUT_LINE or WM8904_OUT_BOTH. + * @retval 0 if correct communication, else wrong communication + */ +int32_t WM8904_SetOutputMode(WM8904_Object_t *pObj, uint32_t Output) +{ + (void)(pObj); + (void)(Output); + + /* This feature is currently not supported */ + return WM8904_ERROR; +} + +/** + * @brief Set Audio resolution. + * @param pObj pointer to component object + * @param Resolution Audio resolution. Can be: + * WM8904_RESOLUTION_16b, WM8904_RESOLUTION_20b, + * WM8904_RESOLUTION_24b or WM8904_RESOLUTION_32b + * @retval Component status + */ +int32_t WM8904_SetResolution(WM8904_Object_t *pObj, uint32_t Resolution) +{ + (void)(pObj); + (void)(Resolution); + + /* This feature is currently not supported */ + return WM8904_ERROR; +} + +/** + * @brief Get Audio resolution. + * @param pObj pointer to component object + * @retval Audio resolution + */ +int32_t WM8904_GetResolution(WM8904_Object_t *pObj, uint32_t *Resolution) +{ + int32_t ret; + uint16_t tmp; + + ret = wm8904_read_reg(&pObj->Ctx, WM8904_AUDIO_INTERFACE1, &tmp, 2U); + + switch((tmp >> 2U) & 0x0003U) + { + case 1: + *Resolution = WM8904_RESOLUTION_20B; + break; + case 2: + *Resolution = WM8904_RESOLUTION_24B; + break; + case 3: + *Resolution = WM8904_RESOLUTION_32B; + break; + case 0: + default: + *Resolution = WM8904_RESOLUTION_16B; + break; + } + + return ret; +} + +/** + * @brief Set Audio Protocol. + * @param pObj pointer to component object + * @param Protocol Audio Protocol. Can be: + * WM8904_PROTOCOL_R_JUSTIFIED, WM8904_PROTOCOL_L_JUSTIFIED, + * WM8904_PROTOCOL_I2S or WM8904_PROTOCOL_DSP + * @retval Component status + */ +int32_t WM8904_SetProtocol(WM8904_Object_t *pObj, uint32_t Protocol) +{ + (void)(pObj); + (void)(Protocol); + + /* This feature is currently not supported */ + return WM8904_ERROR; +} + +/** + * @brief Get Audio Protocol. + * @param pObj pointer to component object + * @retval Component status + */ +int32_t WM8904_GetProtocol(WM8904_Object_t *pObj, uint32_t *Protocol) +{ + int32_t ret; + uint16_t tmp; + + ret = wm8904_read_reg(&pObj->Ctx, WM8904_AUDIO_INTERFACE1, &tmp, 2U); + + *Protocol = (((uint32_t) tmp) & 0x0003U); + + return ret; +} + +/** + * @brief Sets new frequency. + * @param pObj pointer to component object + * @param AudioFreq Audio frequency + * @retval Component status + */ +int32_t WM8904_SetFrequency(WM8904_Object_t *pObj, uint32_t AudioFreq) +{ + int32_t ret; + uint16_t tmp; + + switch (AudioFreq) + { + case WM8904_FREQUENCY_8K: + /* Sample Rate = 8 (kHz), ratio=256 */ + tmp = 0x0C00U; + ret = wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + break; + + case WM8904_FREQUENCY_11K: + /* Sample Rate = 11.025 (kHz), ratio=256 */ + tmp = 0x0C01U; + ret = wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + break; + + case WM8904_FREQUENCY_16K: + /* Sample Rate = 16 (kHz), ratio=256 */ + tmp = 0x0C02U; + ret = wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + break; + + case WM8904_FREQUENCY_22K: + case WM8904_FREQUENCY_24K: + /* Sample Rate = 22.050 (kHz) or 24 (kHz), ratio=256 */ + tmp = 0x0C03U; + ret = wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + break; + + case WM8904_FREQUENCY_32K: + /* Sample Rate = 32 (kHz), ratio=256 */ + tmp = 0x0C04U; + ret = wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + break; + + case WM8904_FREQUENCY_44K: + case WM8904_FREQUENCY_48K: + /* Sample Rate = 44.1 (kHz) or 48 (kHz), ratio=256 */ + tmp = 0x0C05U; + ret = wm8904_write_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + break; + + default: + ret = WM8904_ERROR; + break; + } + + return ret; +} + +/** + * @brief Get frequency. + * @param pObj pointer to component object + * @param AudioFreq Audio frequency + * @retval Component status + */ +int32_t WM8904_GetFrequency(WM8904_Object_t *pObj, uint32_t *AudioFreq) +{ + int32_t ret; + uint16_t tmp; + + ret = wm8904_read_reg(&pObj->Ctx, WM8904_CLOCK_RATES1, &tmp, 2U); + + switch(tmp & 0x0007U) + { + case 0: + *AudioFreq = WM8904_FREQUENCY_8K; + break; + case 1: + /* 11.025k or 12k */ + *AudioFreq = WM8904_FREQUENCY_11K; + break; + case 2: + *AudioFreq = WM8904_FREQUENCY_16K; + break; + case 3: + /* 22.05k or 24k */ + *AudioFreq = WM8904_FREQUENCY_22K; + break; + case 4: + *AudioFreq = WM8904_FREQUENCY_32K; + break; + case 5: + /* 44.1k or 48k */ + *AudioFreq = WM8904_FREQUENCY_44K; + break; + default: + ret = WM8904_ERROR; + break; + } + + return ret; +} + +/** + * @brief Resets wm8904 registers. + * @param pObj pointer to component object + * @retval Component status if correct communication, else wrong communication + */ +int32_t WM8904_Reset(WM8904_Object_t *pObj) +{ + uint16_t tmp; + int32_t ret; + + /* Reset Codec by writing in 0x0000 address register */ + tmp = 0x0U; /* Reset registers */ + ret = wm8904_write_reg(&pObj->Ctx, WM8904_SW_RESET, &tmp, 2U); + + return ret; +} + +/** + * @brief Function + * @param Component object pointer + * @retval error status + */ +int32_t WM8904_RegisterBusIO(WM8904_Object_t *pObj, const WM8904_IO_t *pIO) +{ + int32_t ret; + + if (pObj == NULL) + { + ret = WM8904_ERROR; + } + else + { + pObj->IO.Init = pIO->Init; + pObj->IO.DeInit = pIO->DeInit; + pObj->IO.Address = pIO->Address; + pObj->IO.WriteReg = pIO->WriteReg; + pObj->IO.ReadReg = pIO->ReadReg; + pObj->IO.GetTick = pIO->GetTick; + + pObj->Ctx.ReadReg = WM8904_ReadRegWrap; + pObj->Ctx.WriteReg = WM8904_WriteRegWrap; + pObj->Ctx.handle = pObj; + + if(pObj->IO.Init != NULL) + { + ret = pObj->IO.Init(); + } + else + { + ret = WM8904_ERROR; + } + } + + return ret; +} +/** + * @} + */ + +/******************** Static functions ****************************************/ +/** @addtogroup WM8904_Private_Functions + * @{ + */ +/** + * @brief This function provides accurate delay (in milliseconds) + * @param pObj pointer to component object + * @param Delay: specifies the delay time length, in milliseconds + */ +static void WM8904_Delay(const WM8904_Object_t *pObj, uint32_t Delay) +{ + uint32_t tickstart; + + tickstart = pObj->IO.GetTick(); + while((pObj->IO.GetTick() - tickstart) < Delay) + { + } +} + +/** + * @brief Function + * @param handle Component object handle + * @param Reg The target register address to write + * @param pData The target register value to be written + * @param Length buffer size to be written + * @retval error status + */ +static int32_t WM8904_ReadRegWrap(void *handle, uint16_t Reg, uint8_t* pData, uint16_t Length) +{ + const WM8904_Object_t *pObj = (WM8904_Object_t *)handle; + + return pObj->IO.ReadReg(pObj->IO.Address, Reg, pData, Length); +} + +/** + * @brief Function + * @param handle Component object handle + * @param Reg The target register address to write + * @param pData The target register value to be written + * @param Length buffer size to be written + * @retval error status + */ +static int32_t WM8904_WriteRegWrap(void *handle, uint16_t Reg, uint8_t* pData, uint16_t Length) +{ + const WM8904_Object_t *pObj = (WM8904_Object_t *)handle; + + return pObj->IO.WriteReg(pObj->IO.Address, Reg, pData, Length); +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.h b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.h new file mode 100644 index 0000000..8319ac1 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.h @@ -0,0 +1,224 @@ +/** + ****************************************************************************** + * @file wm8904.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the + * wm8904.c 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 WM8904_H +#define WM8904_H + +/* Includes ------------------------------------------------------------------*/ +#include "wm8904_reg.h" +#include + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @addtogroup WM8904 + * @{ + */ + +/** @defgroup WM8904_Exported_Types Exported Types + * @{ + */ +typedef int32_t (*WM8904_Init_Func) (void); +typedef int32_t (*WM8904_DeInit_Func) (void); +typedef int32_t (*WM8904_GetTick_Func) (void); +typedef int32_t (*WM8904_WriteReg_Func)(uint16_t, uint16_t, uint8_t*, uint16_t); +typedef int32_t (*WM8904_ReadReg_Func) (uint16_t, uint16_t, uint8_t*, uint16_t); + +typedef struct +{ + WM8904_Init_Func Init; + WM8904_DeInit_Func DeInit; + uint16_t Address; + WM8904_WriteReg_Func WriteReg; + WM8904_ReadReg_Func ReadReg; + WM8904_GetTick_Func GetTick; +} WM8904_IO_t; + + +typedef struct +{ + WM8904_IO_t IO; + wm8904_ctx_t Ctx; + uint8_t IsInitialized; +} WM8904_Object_t; + +typedef struct +{ + uint32_t InputDevice; + uint32_t OutputDevice; + uint32_t Frequency; + uint32_t Resolution; + uint32_t Volume; +} WM8904_Init_t; + + typedef struct +{ + int32_t ( *Init ) ( WM8904_Object_t *, WM8904_Init_t* ); + int32_t ( *DeInit ) ( WM8904_Object_t * ); + int32_t ( *ReadID ) ( WM8904_Object_t *, uint32_t * ); + int32_t ( *Play ) ( WM8904_Object_t * ); + int32_t ( *Pause ) ( WM8904_Object_t * ); + int32_t ( *Resume ) ( WM8904_Object_t * ); + int32_t ( *Stop ) ( WM8904_Object_t *, uint32_t ); + int32_t ( *SetFrequency ) ( WM8904_Object_t *, uint32_t ); + int32_t ( *GetFrequency ) ( WM8904_Object_t *, uint32_t*); + int32_t ( *SetVolume ) ( WM8904_Object_t *, uint32_t, uint8_t ); + int32_t ( *GetVolume ) ( WM8904_Object_t *, uint32_t, uint8_t*); + int32_t ( *SetMute ) ( WM8904_Object_t *, uint32_t ); + int32_t ( *SetOutputMode ) ( WM8904_Object_t *, uint32_t ); + int32_t ( *SetResolution ) ( WM8904_Object_t *, uint32_t ); + int32_t ( *GetResolution ) ( WM8904_Object_t *, uint32_t*); + int32_t ( *SetProtocol ) ( WM8904_Object_t *, uint32_t ); + int32_t ( *GetProtocol ) ( WM8904_Object_t *, uint32_t*); + int32_t ( *Reset ) ( WM8904_Object_t * ); +} WM8904_Drv_t; +/** + * @} + */ + +/** @defgroup WM8904_Exported_Constants Exported Constants + * @{ + */ +#define WM8904_OK (0) +#define WM8904_ERROR (-1) + +/******************************************************************************/ +/*************************** Codec User defines ******************************/ +/******************************************************************************/ +/* Audio Input Device */ +#define WM8904_IN_NONE 0x0000U +#define WM8904_IN_MIC1 0x0100U +#define WM8904_IN_MIC2 0x0200U +#define WM8904_IN_MIC1_MIC2 0x0300U +#define WM8904_IN_LINE1 0x0400U +#define WM8904_IN_LINE2 0x0800U +#define WM8904_IN_DIGITAL_MIC1 0x1000U +#define WM8904_IN_DIGITAL_MIC2 0x2000U + +/* Audio Output Device */ +#define WM8904_OUT_NONE 0x0000U +#define WM8904_OUT_HEADPHONE 0x0001U +#define WM8904_OUT_LINE 0x0002U +#define WM8904_OUT_BOTH 0x0003U + +/* AUDIO FREQUENCY */ +#define WM8904_FREQUENCY_192K 192000U +#define WM8904_FREQUENCY_176K 176400U +#define WM8904_FREQUENCY_96K 96000U +#define WM8904_FREQUENCY_88K 88200U +#define WM8904_FREQUENCY_48K 48000U +#define WM8904_FREQUENCY_44K 44100U +#define WM8904_FREQUENCY_32K 32000U +#define WM8904_FREQUENCY_24K 24000U +#define WM8904_FREQUENCY_22K 22050U +#define WM8904_FREQUENCY_16K 16000U +#define WM8904_FREQUENCY_11K 11025U +#define WM8904_FREQUENCY_8K 8000U + +/* AUDIO RESOLUTION */ +#define WM8904_RESOLUTION_16B 0x00U +#define WM8904_RESOLUTION_20B 0x01U +#define WM8904_RESOLUTION_24B 0x02U +#define WM8904_RESOLUTION_32B 0x03U + +/* Codec stop options */ +#define WM8904_PDWN_HW 0x00U +#define WM8904_PDWN_SW 0x01U + +/* Volume Input Output selection */ +#define VOLUME_INPUT 0U +#define VOLUME_OUTPUT 1U + +/* MUTE commands */ +#define WM8904_MUTE_ON 1U +#define WM8904_MUTE_OFF 0U + +/* AUDIO PROTOCOL */ +#define WM8904_PROTOCOL_R_JUSTIFIED 0x0000U +#define WM8904_PROTOCOL_L_JUSTIFIED 0x0001U +#define WM8904_PROTOCOL_I2S 0x0002U +#define WM8904_PROTOCOL_DSP 0x0003U + +/** + * @brief WM8904 ID + */ +#define WM8904_ID 0x8904U +#define WM8904_ID_MASK 0xFFFFU +/** + * @} + */ + +/** @addtogroup WM8904_Exported_Variables + * @{ + */ +/* Audio driver structure */ +extern WM8904_Drv_t WM8904_Driver; +/** + * @} + */ + +/** @addtogroup WM8904_Exported_Functions + * @{ + */ +/*------------------------------------------------------------------------------ + Audio Codec functions +------------------------------------------------------------------------------*/ +/* High Layer codec functions */ +int32_t WM8904_RegisterBusIO (WM8904_Object_t *pObj, const WM8904_IO_t *pIO); +int32_t WM8904_Init(WM8904_Object_t *pObj, WM8904_Init_t *pInit); +int32_t WM8904_DeInit(WM8904_Object_t *pObj); +int32_t WM8904_ReadID(WM8904_Object_t *pObj, uint32_t *Id); +int32_t WM8904_Play(WM8904_Object_t *pObj); +int32_t WM8904_Pause(WM8904_Object_t *pObj); +int32_t WM8904_Resume(WM8904_Object_t *pObj); +int32_t WM8904_Stop(WM8904_Object_t *pObj, uint32_t CodecPdwnMode); +int32_t WM8904_SetVolume(WM8904_Object_t *pObj, uint32_t InputOutput, uint8_t Volume); +int32_t WM8904_GetVolume(WM8904_Object_t *pObj, uint32_t InputOutput, uint8_t *Volume); +int32_t WM8904_SetMute(WM8904_Object_t *pObj, uint32_t Cmd); +int32_t WM8904_SetOutputMode(WM8904_Object_t *pObj, uint32_t Output); +int32_t WM8904_SetResolution(WM8904_Object_t *pObj, uint32_t Resolution); +int32_t WM8904_GetResolution(WM8904_Object_t *pObj, uint32_t *Resolution); +int32_t WM8904_SetProtocol(WM8904_Object_t *pObj, uint32_t Protocol); +int32_t WM8904_GetProtocol(WM8904_Object_t *pObj, uint32_t *Protocol); +int32_t WM8904_SetFrequency(WM8904_Object_t *pObj, uint32_t AudioFreq); +int32_t WM8904_GetFrequency(WM8904_Object_t *pObj, uint32_t *AudioFreq); +int32_t WM8904_Reset(WM8904_Object_t *pObj); +/** + * @} + */ + +#endif /* WM8904_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.c b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.c new file mode 100644 index 0000000..108facf --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.c @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * @file wm8904_reg.c + * @author MCD Application Team + * @brief This file provides unitary register function to control the WM8904 + * Audio Codec 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 "wm8904_reg.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup wm8904 + * @brief This file provides a set of functions needed to drive the + * WM8904 audio codec. + * @{ + */ + +/************** Generic Function *******************/ +/******************************************************************************* +* Function Name : wm8904_read_reg +* Description : Generic Reading function. It must be full-filled with either +* I2C or SPI reading functions +* Input : Register Address, length of buffer +* Output : data Read +*******************************************************************************/ +int32_t wm8904_read_reg(const wm8904_ctx_t *ctx, uint16_t reg, uint16_t* data, uint16_t length) +{ + int32_t ret; + uint16_t tmp; + + ret = ctx->ReadReg(ctx->handle, reg, (uint8_t *)data, length); + + if(ret >= 0) + { + tmp = ((uint16_t)(*data >> 8) & 0x00FFU); + tmp |= ((uint16_t)(*data << 8) & 0xFF00U); + *data = tmp; + } + return ret; +} + +/******************************************************************************* +* Function Name : wm8904_write_reg +* Description : Generic Writing function. It must be full-filled with either +* I2C or SPI writing function +* Input : Register Address, data to be written, length of buffer +* Output : None +*******************************************************************************/ +int32_t wm8904_write_reg(const wm8904_ctx_t *ctx, uint16_t reg, const uint16_t *data, uint16_t length) +{ + uint16_t tmp; + tmp = ((uint16_t)(*data >> 8) & 0x00FFU); + tmp |= ((uint16_t)(*data << 8) & 0xFF00U); + + return ctx->WriteReg(ctx->handle, reg, (uint8_t *)&tmp, length); +} + +/******************************************************************************/ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.h b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.h new file mode 100644 index 0000000..3e96da7 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.h @@ -0,0 +1,228 @@ +/** + ****************************************************************************** + * @file wm8904_reg.h + * @author MCD Application Team + * @brief Header of wm8904_reg.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 WM8904_REG_H +#define WM8904_REG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Component + * @{ + */ + +/** @addtogroup WM8904 + * @{ + */ + + +/** @addtogroup WM8904_Exported_Constants + * @{ + */ +/******************************************************************************/ +/****************************** REGISTER MAPPING ******************************/ +/******************************************************************************/ +/* SW Reset */ +#define WM8904_SW_RESET 0x0000U + +/* Bias Control */ +#define WM8904_BIAS_CONTROL0 0x0004U +#define WM8904_VMID_CONTROL0 0x0005U +#define WM8904_MIC_BIAS_CONTROL0 0x0006U +#define WM8904_MIC_BIAS_CONTROL1 0x0007U + +#define WM8904_ANALOG_ADC0 0x000AU + +/* Power Management */ +#define WM8904_PWR_MANAGEMENT0 0x000CU +#define WM8904_PWR_MANAGEMENT2 0x000EU +#define WM8904_PWR_MANAGEMENT3 0x000FU +#define WM8904_PWR_MANAGEMENT6 0x0012U + +/* Clock Rates */ +#define WM8904_CLOCK_RATES0 0x0014U +#define WM8904_CLOCK_RATES1 0x0015U +#define WM8904_CLOCK_RATES2 0x0016U + +/* Audio Interface */ +#define WM8904_AUDIO_INTERFACE0 0x0018U +#define WM8904_AUDIO_INTERFACE1 0x0019U +#define WM8904_AUDIO_INTERFACE2 0x001AU +#define WM8904_AUDIO_INTERFACE3 0x001BU + +/* DAC */ +#define WM8904_DAC_DIGITAL_VOL_LEFT 0x001EU +#define WM8904_DAC_DIGITAL_VOL_RIGHT 0x001FU +#define WM8904_DAC_DIGITAL0 0x0020U +#define WM8904_DAC_DIGITAL1 0x0021U + +/* ADC */ +#define WM8904_ADC_DIGITAL_VOL_LEFT 0x0024U +#define WM8904_ADC_DIGITAL_VOL_RIGHT 0x0025U +#define WM8904_ADC_DIGITAL0 0x0026U + +#define WM8904_DIGITAL_MICROPHONE0 0x0027U + +/* DRC */ +#define WM8904_DRC0 0x0028U +#define WM8904_DRC1 0x0029U +#define WM8904_DRC2 0x002AU +#define WM8904_DRC3 0x002BU + +/* Analog */ +#define WM8904_ANALOG_LEFT_INPUT0 0x002CU +#define WM8904_ANALOG_RIGHT_INPUT0 0x002DU +#define WM8904_ANALOG_LEFT_INPUT1 0x002EU +#define WM8904_ANALOG_RIGHT_INPUT1 0x002FU +#define WM8904_ANALOG_OUTPUT1_LEFT 0x0039U +#define WM8904_ANALOG_OUTPUT1_RIGHT 0x003AU +#define WM8904_ANALOG_OUTPUT2_LEFT 0x003BU +#define WM8904_ANALOG_OUTPUT2_RIGHT 0x003CU +#define WM8904_ANALOG_OUTPUT12_ZC 0x003DU + +/* DC Servo */ +#define WM8904_DC_SERVO0 0x0043U +#define WM8904_DC_SERVO1 0x0044U +#define WM8904_DC_SERVO2 0x0045U +#define WM8904_DC_SERVO4 0x0047U +#define WM8904_DC_SERVO5 0x0048U +#define WM8904_DC_SERVO6 0x0049U +#define WM8904_DC_SERVO7 0x004AU +#define WM8904_DC_SERVO8 0x004BU +#define WM8904_DC_SERVO9 0x004CU +#define WM8904_DC_SERVO_READBACK0 0x004DU + +/* Analog */ +#define WM8904_ANALOG_HP0 0x005AU +#define WM8904_ANALOG_LINEOUT0 0x005EU + +/* Charge pump */ +#define WM8904_CHARGE_PUMP0 0x0062U + +/* Class W/G */ +#define WM8904_CLASS_W0 0x0068U + +/* Write Sequencer */ +#define WM8904_WRITE_SEQUENCER0 0x006CU +#define WM8904_WRITE_SEQUENCER1 0x006DU +#define WM8904_WRITE_SEQUENCER2 0x006EU +#define WM8904_WRITE_SEQUENCER3 0x006FU +#define WM8904_WRITE_SEQUENCER4 0x0070U + +/* FLL Control */ +#define WM8904_FLL_CONTROL1 0x0074U +#define WM8904_FLL_CONTROL2 0x0075U +#define WM8904_FLL_CONTROL3 0x0076U +#define WM8904_FLL_CONTROL4 0x0077U +#define WM8904_FLL_CONTROL5 0x0078U + +/* GPIO Control */ +#define WM8904_GPIO_CONTROL1 0x0079U +#define WM8904_GPIO_CONTROL2 0x007AU +#define WM8904_GPIO_CONTROL3 0x007BU +#define WM8904_GPIO_CONTROL4 0x007CU + +#define WM8904_DIGITAL_PULLS 0x007EU + +/* Interrupt */ +#define WM8904_INTERRUPT_STATUS 0x007FU +#define WM8904_INTERRUPT_STATUS_MASK 0x0080U +#define WM8904_INTERRUPT_POLARITY 0x0081U +#define WM8904_INTERRUPT_DEBOUNCE 0x0082U + +/* EQ */ +#define WM8904_EQ1 0x0086U +#define WM8904_EQ2 0x0087U +#define WM8904_EQ3 0x0088U +#define WM8904_EQ4 0x0089U +#define WM8904_EQ5 0x008AU +#define WM8904_EQ6 0x008BU +#define WM8904_EQ7 0x008CU +#define WM8904_EQ8 0x008DU +#define WM8904_EQ9 0x008EU +#define WM8904_EQ10 0x008FU +#define WM8904_EQ11 0x0090U +#define WM8904_EQ12 0x0091U +#define WM8904_EQ13 0x0092U +#define WM8904_EQ14 0x0093U +#define WM8904_EQ15 0x0094U +#define WM8904_EQ16 0x0095U +#define WM8904_EQ17 0x0096U +#define WM8904_EQ18 0x0097U +#define WM8904_EQ19 0x0098U +#define WM8904_EQ20 0x0099U +#define WM8904_EQ21 0x009AU +#define WM8904_EQ22 0x009BU +#define WM8904_EQ23 0x009CU +#define WM8904_EQ24 0x009DU + +#define WM8904_ADC_TEST0 0x00C6U + +#define WM8904_FLL_TEST0 0x00F7U +#define WM8904_FLL_TEST1 0x00F8U +/** + * @} + */ + +/************** Generic Function *******************/ + +typedef int32_t (*WM8904_Write_Func)(void *, uint16_t, uint8_t*, uint16_t); +typedef int32_t (*WM8904_Read_Func) (void *, uint16_t, uint8_t*, uint16_t); + +typedef struct +{ + WM8904_Write_Func WriteReg; + WM8904_Read_Func ReadReg; + void *handle; +} wm8904_ctx_t; + +/******************************************************************************* +* Register : Generic - All +* Address : Generic - All +* Bit Group Name: None +* Permission : W +*******************************************************************************/ +int32_t wm8904_write_reg(const wm8904_ctx_t *ctx, uint16_t reg, const uint16_t *data, uint16_t length); +int32_t wm8904_read_reg(const wm8904_ctx_t *ctx, uint16_t reg, uint16_t* data, uint16_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* WM8904_REG_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/.DS_Store b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ec8a0ddcaa604f81f24ec7e1678631cd570e609f GIT binary patch literal 6148 zcmeHKyG{c^3>-s>lW0<=++W}iR#Er@J^+*ii2@XfKz|kA#iucT2oc>OrAdRvl0Ca# z&z^3I^BI7xKlZo462L%r#HWX;`MLYVt}0_hI`4SH6OP#JkGq#i^?bs)10L{0pQvfVf~f zjO&;sh|LqkUN|N)L$jn3lWH|$SkjqqRo4s0#H7P&_^^7i)r4a4bl%^h9M%&RrGOMT zRp2_eOYi@8^grhRQ<8R4KnnaT1#Gdo->msc)mtYo=e@SkAL(B6MR(&mC=Ah#iP4U^ g@pin5qO5Da=6Nq16NAot(24pPa9w0l;L-|w1NsCNkN^Mx literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.md b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.md new file mode 100644 index 0000000..912ac1f --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.md @@ -0,0 +1,27 @@ +Copyright 2022(-2023) STMicroelectronics. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.txt b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/LICENSE.txt new file mode 100644 index 0000000..b40364c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/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/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/README.md b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/README.md new file mode 100644 index 0000000..dbf57cb --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/README.md @@ -0,0 +1,44 @@ +# BSP STM32H7S78-DK Component + +![latest tag](https://img.shields.io/github/v/tag/STMicroelectronics/stm32h7s78-dk.svg?color=brightgreen) + +## Overview + +**STM32Cube** is an STMicroelectronics original initiative to ease developers' life by reducing efforts, time and cost. + +**STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series. + * The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product. + * The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio. + * The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series. + * A consistent set of middleware libraries such as RTOS, USB, FatFS, graphics, touch sensing library... + * A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series. + +Two models of publication are proposed for the STM32Cube embedded software: + * The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series). + * The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions. + +## Description + +This **stm32h7s78-dk** MCU component repository is one element of the **STM32CubeH7RS** MCU embedded software package, providing the **STM32H7RS-DK** BSP BOARD component part. + +## Release note + +Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/stm32h7s78-dk/blob/main/Release_Notes.html). + +## Compatibility information + +Below is the list of the BSP *component* drivers to be used with this BSP *board* driver. It is **crucial** that you use a consistent set of CMSIS - HAL - BSP versions, as mentioned in [this](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Release_Notes.html) release note. + +* [stm32-bsp-common](https://github.com/STMicroelectronics/stm32-bsp-common) +* [stm32-aps256xx](https://github.com/STMicroelectronics/stm32-aps256xx) +* [stm32-gt911](https://github.com/STMicroelectronics/stm32-gt911) +* [stm32-lan8742](https://github.com/STMicroelectronics/stm32-lan8742) +* [stm32-mx66uw1g45g](https://github.com/STMicroelectronics/stm32-mx66uw1g45g) +* [stm32-ov5640](https://github.com/STMicroelectronics/stm32-ov5640) +* [stm32-rk050hr18](https://github.com/STMicroelectronics/stm32-rk050hr18) +* [stm32-tcpp0203](https://github.com/STMicroelectronics/stm32-tcpp0203) +* [stm32-wm8904](https://github.com/STMicroelectronics/stm32-wm8904) + +## Troubleshooting + +Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide. diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.html b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.html new file mode 100644 index 0000000..28a8564 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.html @@ -0,0 +1,137 @@ + + + + + + + Release Notes for STM32H7S78-DK Drivers + + + + + + +
+
+
+

Release Notes for

+

STM32H7S78-DK

+

Copyright © 2024 STMicroelectronics
+

+ +
+

Purpose

+

This driver provides a set of functions to manage:

+
    +
  • 1-Gbit Octo-SPI NOR flash memory, 256-Mbit Hexadeca-SPI PSRAM, I2S audio codec, 5" LCD module with capacitive touch panel, user LEDs and push-button available on STM32H7S78-DK Kit from STMicroelectronics
  • +
+
+
+

Update History

+
+ +
+

Maintenance release

+

Contents

+
    +
  • Fix Misra-C 2012 Rule 12.2 violations
  • +
+

Supported Devices and boards

+
    +
  • STM32H7S7L8H6H
  • +
  • STM32H7S78-DK
  • +
+

Known Limitations

+
    +
  • None
  • +
+

Dependencies

+
    +
  • None
  • +
+

Notes

+
    +
  • None
  • +
+


+

+
+
+
+ +
+

Maintenance release

+

Contents

+
    +
  • Enable Hardware flow control of SD handle in MX_SDMMC1_SD_Init()
  • +
+

Supported Devices and boards

+
    +
  • STM32H7S7L8H6H
  • +
  • STM32H7S78-DK
  • +
+

Known Limitations

+
    +
  • None
  • +
+

Dependencies

+
    +
  • None
  • +
+

Notes

+
    +
  • None
  • +
+


+

+
+
+
+ +
+

First release

+

Official release of STM32H7S78-DK BSP Board drivers

+

Contents

+
    +
  • Official release of board drivers for Discovery kit with STM32H7S7L8
  • +
+

Supported Devices and boards

+
    +
  • STM32H7S7L8H6H
  • +
  • STM32H7S78-DK
  • +
+

Known Limitations

+
    +
  • None
  • +
+

Dependencies

+
    +
  • None
  • +
+

Notes

+

stm32h7s78_discovery_conf_template.h file must be copied in user application as stm32h7rsxx_discovery_conf.h with optional configuration update

+


+

+
+
+
+
+
+
+
+

For complete documentation on STM32, visit: www.st.com

+

This release note uses up to date web standards and, for this reason, should not be opened with Internet Explorer but preferably with popular browsers such as Google Chrome, Mozilla Firefox, Opera or Microsoft Edge.

+
+

Info

+
+
+
+ + diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.md b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.md new file mode 100644 index 0000000..85d1c19 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/Release_Notes.md @@ -0,0 +1,146 @@ +--- +pagetitle: Release Notes for STM32H7S78-DK Drivers +lang: en +header-includes: +--- + +::: {.row} +::: {.col-sm-12 .col-lg-4} + +
+# Release Notes for +# STM32H7S78-DK +Copyright © 2024 STMicroelectronics\ + +[![ST logo](_htmresc/st_logo_2020.png)](https://www.st.com){.logo} +
+ +# Purpose + +This driver provides a set of functions to manage: + +- 1-Gbit Octo-SPI NOR flash memory, 256-Mbit Hexadeca-SPI PSRAM, I2S audio codec, 5" LCD module with capacitive touch panel, user LEDs and push-button available on STM32H7S78-DK Kit from STMicroelectronics + +::: + +::: {.col-sm-12 .col-lg-8} +# Update History +::: {.collapse} + + +
+ +## Maintenance release + +## Contents + +- Fix Misra-C 2012 Rule 12.2 violations + +## Supported Devices and boards + +- STM32H7S7L8H6H +- STM32H7S78-DK + +## Known Limitations + +- None + +## Dependencies + +- None + +## Notes + +- None + + +\ + +
+::: + +::: {.collapse} + + +
+ +## Maintenance release + +## Contents + +- Enable Hardware flow control of SD handle in MX_SDMMC1_SD_Init() + +## Supported Devices and boards + +- STM32H7S7L8H6H +- STM32H7S78-DK + +## Known Limitations + +- None + +## Dependencies + +- None + +## Notes + +- None + + +\ + +
+::: +::: {.collapse} + + +
+ +## First release + +### Official release of **STM32H7S78-DK** BSP Board drivers + +## Contents + +- Official release of board drivers for **Discovery kit with STM32H7S7L8** + +## Supported Devices and boards + +- STM32H7S7L8H6H +- STM32H7S78-DK + +## Known Limitations + +- None + +## Dependencies + +- None + +## Notes + +stm32h7s78_discovery_conf_template.h file must be copied in user application as stm32h7rsxx_discovery_conf.h with optional configuration update + + +\ + +
+::: + +::: +::: + +
+::: {.columns} +::: {.column width="95%"} +For complete documentation on STM32, +visit: [www.st.com](http://www.st.com) + +*This release note uses up to date web standards and, for this reason, should not be opened with Internet Explorer but preferably with popular browsers such as Google Chrome, Mozilla Firefox, Opera or Microsoft Edge.* +::: +::: {.column width="5%"} +Info +::: +::: +
diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/STM32H7S78-DK_BSP_User_Manual.chm b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/STM32H7S78-DK_BSP_User_Manual.chm new file mode 100644 index 0000000000000000000000000000000000000000..fbc0811e34bcc05d081019053c64ba04c4fccc06 GIT binary patch literal 1361888 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 z z$2TT}n17GDGR71Z4-N^W#MRv5L+!8dg1BZxLmrf6KkD6(4(=#cJB0bwQ1+O zSHm64zU{o+f8bsde=jyP6w*qonE^sGN6Xe7YfD5IMYAii9Dh}z@LuQ69rUN;`1HD- zT$SAK0Po5$^~7>iVi4PS1Yk2!L`-NB0F0u#Ya0`xmU$Dts~O3T)JRaDOU#7s3Ws`k zxKwso_>6N}L6KxsE>%dbnb2w>r*RLGmQbG`xc3=COQ#>rb7l{zzmpaQ?Sn;u4Gvb$ zLKmPSKBm=*22z~3NYYMAcSAdEul%KUxCJOZebGFZl1kndz~GwMsnmSmCAIKj0|Fx3M(1gPGgVcQ0lZfxnY#-Kaqd2OJWbwG}SqY7>eiclAlSiNu@4muo6U+s4&UPI9_Z)xA-m= z^khNmi(LGeH-qG8UBQDa0HQjeau{RnDOWqu4tk42vyP5__>Tip_Ip;8>HwGuJ#h;L z;hpIiYNDx-bKy$lQX5?IA#aAYyOs7c@0c8mI7=iW5LYh46U$A?aY7_TJAlI4S^Eds z*;F6>r7YltYPAT*ETDNrm}2M)o7RfH^yx*;x-V^a*u@}#7|MeY^fqn*ta)od1r}DZ zMbg-{&j$Pom$A=bWJ{qL{W)ZCUQ&y+r)*7yf^(+hVy2vnB%zOG-ds8HUM~l9%Wtyi zu&BIivoGB>z_>0>&s)y@FL3vbxp%fE{ly<6NkkQj(dHtr6o7IF1`@bg2lSecNq*pU zmACZ!2*TxZC2n%}Cr&E|YsWN00D zF|f74e(L%;0z=RA2uYc+@^eC=Z~&!!+&ar}r$zpBg5lSM_nS|z%N+fGoVN6Gca6)i z6o9aa9S(FEbXW-mMFCSXj^)d4)&12p4!r%fdvyC#z2)^et+IRuv&iP`PEN5;t{+DW z@3QszJZsNlL3?5LTn>~nOn!b z4~y)$7)g6@b?!U@r%rznMVw2i*kMMdfDB#w!lfX9DqSi0sr^61FoeC`PFhJ9S{@X} z;GGMguyqN-o_0?AUtf)1pPmc=aw=nA&yj(Ub4VnT6f4rXZUtc-Yf&b~ObfC}du*td z|5I*7vCI7HeHL7}$AQp7mgF`Razz+PnM+gfBHvffVup)8kCfKRsR*7qaCpS(v<5<4 zF;y7N5I!2sxtrRr&)=G*K0ktrEGZLTExo!Q3@LG!yTSN8^egSSPjssH`=K{-M8J^c3{A9>(4Krz*d1KC?}a|UI`bnt|8wO(Im*?~$p8F#=|>)N=j^iHUq(LAkJIU& z`qLwy@A9L(y6^iwq3NIg^iQ4g&^kKU@2` z!@&{xWbB&m{Q1AtZ+*Zsv~==)G=~nK*v~9|q$7kH^}F4=I!--kvi|bIZoE7vpOIha z(x2Dq=l`Fe3Tz|KH^J%n6{;B=Uet3QFdeqtZYRg^Ec&>cDN?|P2sPKdn_pK%MP3r5li~k%> zcQH+G{0VMnuNS4QEXT2t6q*$tIa{0!lGjtjx-W`Cf znLl|l8ND*~9wYPmvWW-ipUq=%eS1&AJ?%9&CnFV!s*DkzJ^>zf_>I>vWg)J~c;$U^ zbDQ}g{owlcqJn$cYoSyx-yIx6Mtileq>&V57cdM;{Uu{w{yu)&n`?sa+3W?$A8x8A zovBNmqwAv~-^Z`QFSgN0G64UoIf+ zM&FHCTsmo6&ix+t6OJ_gEKSGYE@^w4Z`t%+dG6AEij53?jTQshG zc7GfC=F8t7our?EiygbYpnucM=}F48O}DSIPQPYEarV>o^`mLKv;RZGHB;rh1^wp< z>S8lZz%h@)Vh~Q42yXA}l)Ir~#@GHat=@=Fy;@VV8OPD;H<>TX*S5?uetUNuh*u8Cd19o+Zx^*0 zU(8~o#Kd>7RWF+hKSo$+V$t^?`zvW z&iv)x-+tM1%BlWoa_(PwQ;Ex9?6Te4&nBIEiN90D*TLdbz^!qe!_T3Qu33IovvW&@ zRZ#!L4Gx&oT))%4yp!#42FPr$9DJ9j>2wp^SobSY5FPP0MXtl;&3kz|KDc|_&CAu+ zCv?Fqw-@C#Z#%jBAoWW2)47qx=G$_@k=#o||Hr$OxVyX2Nl7UR%M!>er_pW4>z zbr7vzc*$)CuJYHe%ij=3B2)CH?X4o!mn@y35FlW z$lZ`asn=VRy78vQiLUIq$5)x$vfd2fn)YHUjDrF)9cE?OiZXEPokj_CvzLvG0L;eY zuRfo-r)6F*i;+9!$^T<6r!NR_O?xqLLs8Cn-a;rauTuJXNA8Vy(T#B!k|*}FGW#*^ zX72}ZO?xrzK_8Y>!mjWT&oXuFOh{Sgn#*;!Z0yE2-^p24-kSnC#Qh zFfqWS8HZbMDFu18!}K83#y77sFIXOd`_nrNT+LqA;4|DYLzFjxQ*p?lFF0_O;?#gqgn5FDlczRkHJ40VgI*fMcntJW1^m?oe_HhqXoRKxu2XG zPHWhTaojtmy~?{hj#sfSZS#B4_1=27*8K6O4?GNgETAF{&#n>M9KQyf3~eR2r){j6 zmrLuJk(H6oo#f2p<{!7}cI4h`+KYiV--ffenkR}GS;p|bchji?;|XVn_i1Gu<1dfX zt3~mblp}AJwRScB(#z-KMWvtsKTHH5n`GUuA$Y@!ampp=W4?hiNqy1A+&)v;4g&#(xaU2n&H+(_Rex(BUVXUAIAX#88md;T{n8 z_gjaiP_DDaG3IA8^1L&woPpneG9EiCS!;n@(_Rdn&|sxhCGpomWs`9ZzXo_a(iY3< z{Wp%eBxatnJOUS{ml(M0y)N$%cXh{8JEZX6J9UL{DIs~D;0VpzGxUz1kuSWl6LUlU zHAy?VDcG@M^{tQh)t78m_Z(-x=)baBUA&c9LhzDcfkW}|Z_eQRH#}`>Px1MHI1?5H z_w#_W|KQ?nZ(ZhhuwJnk#5J~;Aav5Vqc`6Yh`xq5A&<7rh-l+_XLtD=K^+_PZUZ1I zz19J;Wxl3Pr;A=;iNs=m@!F9 z@u>Z~_WzHVk}>xvH6H&GJ42)WxrLRSSm`E-#0_QAaF_hsp-jPdU?6QHYvM?i~H+P!J2qVR9{X$ zW2X-@@X7+Uj{nW=zLbLrhqQt{n^(3bd&9HnH^3_^JU(Ex%zS=Q?_HgL=NoJn@L2p` zL9~l=pm5`cL>#ue5UPnAC--$_<@011zuL3t@CWt4#%*tR?VEs#{S`wr_J8{UL{a#q z!tbk&{=Xl`6dwu14~lDgyr*FYehxpmL%yBo*TcuwFVC?Sv-8fepv6*vmpYgoMK6qX zl8ayU<&|ozrOaz>txtp9ZSI=(-MqhY^2u;}-1fU7Y2i0)sim*$GK=x<<>?;BA?pI;R@7_7?6;RGXdvGT{Maxu*1*_$`|$gw z&!n(pt=~-Lm!i)Py>?U3!Otn;j4^zG`!8K*yP4pD%H$4w74GkTz{-JN#rKO>v*Vm<`p`qE; zrKO?J_4?9jXzXz*A{#C|#}E$UMnlnDTwFujJWwo>8V&P`v;IJ>!EAxt;Fmp6HgGnOXz zw@{B)uq;CN*>*=8*=z8)u|T`zxK4Fm;NHs0W_Op$MY_y5AqD{j@$&mV7g#NT5eo(J!}jrh^$Ewc2s?6PoAFhzZm z9h1#e&~c=;#lxZgg1p6XJ?{<26Je+Esa@9}Z6~|qm`+FB+VswYUF7%H%X;?bK)8HXhZq$YXnFi@##`iptyQEk}I3 zLAcSH2MBS+Zu@mz{=lN2ark7NufT~=YC<>h{#{0C;w^l#iWKi{L-(V*911Hr{C^}S z1#Q3|*!&5)ph~>FOFmPJ5~CFy^Pc?xNc7U2M1=9qY6QF6)C*hAR$vDOEbXc-j!c$9 zP9)c*Nn-+NY+=yG;3%P>o=A%=;UR2v*i_hFgbNKt;zL_F7gsGw-AiaZ2D%I<;b}QF z9V(PD$5~ykTJD&^Z0IP=l-gq6)Zsz|7!G8^NqnQL;FFl?Yk`{8|u1A(K$w06IFb9Zpnq7kl~wQGb2lK%6#G`AD*xK{Yn>JH=A~K10Tz@m zvc$iNn!&E00~b=7zVYBJT2f2?!&OuQ%qk(K$fp4 z@h7QoG2~LNdM)Ihd_#YoM(9socl1Bx`c}oJRTuThEO);X@?~U3I7t$2uLn>m;2b_N>LMY+#hmx^CjxqPjTwa+~SoM7{MK>*RuD!>w9Utvf{{;4Y3g zqKj3EA#T||T%)IaY$~KB3C3#jg4i~rA|To=>daymwdl)V_}D^W{0bBY!}T@tr3G(D zV72DaUQ6NgR@Rxe(XQ_RrP(NyQBIKh8ZyRkQx+^nMQ!~5z1}nD;3l`$8&3unb98zH zs#ZvuQ0Oa-l~4~|nWs*vONH+z*Ud_n$*bj}#d!|SwOgFMM|50~f`z3yFS+l-9$q~< zZ4{q;7zh^R?pMv9iz``?s9I5*_AHfDDrI$MA=#r78uaMUY3Ay^AH83hT%dA?wh2&0 zz&6LrRV+FUD8?$Jg-!MzJ$rf{Mhf&N)tf0%YQ}t+WPk{c(j`g%=UMdyA8?XE$5mfe ztz2uY!co8vFlmhqS@cQHh2Rxtv?h1pEM!Ii0Z?l+DKLfSLbW{LXrq32-m*&;d=4ze zm2n$@Hd=0CW=y_5{*WHglta1H+${#9I2Bc zEq!x!PE2+vEz%%qaXFAG)TGI5rc9zihUr;06Viz->W0xc@wgD%RLvL`qjplhNmex! zO3piW^(Lih7)LF zW3SqI;9}-J{j1QjG*VnJw}cN?(ZC7yXlo(=5>Xiv#Z_>|?w0CHk94Q4V4YfIaM6*% zq)2sO9a-k>!8d+>Q*ZLpk=6YgElO_5pAGS3RV&^>S}KXJ;LxU{sT)f?Ylvy&-!TXu zZPhl(Ag3f_H1wvbqhfl|SAw|XZ(j%%fgzz2PJcgMFG%1UoEZ7n1g%Mz9i>x6_BkSSK zs^dAPD#H0fK{phMqiFULSO|@;!WSU!wJvM>AVT@5Oe!)eO@f6ym;`DVZeA2P65>|B zCnb2LJt`MMI&BQ$7@;=OEbUG>F_&zAmrDr7lL#?SenJwm*GO;C6sWTf#5xyON7k3Q z*~Y-V5qR>FR!s;8srHp@Qd+^hO|Dxgg)7k(Fd)f2>J7>tgcun*pv@w0B01mt!J@uI z3gFr}UrIO@XU@tXXPsN251~I{bXGk#bX&(tN7x~$L#@uKq>^RvHu*Pn4%n(nwXcab zIXedm3#+go8Fnyn$@%wt&KaqNF?0aNYH+<)a*sI%ouqYfY2OZX#_}S}U{~Y4E~K$# zAe=-kV926zVc!hVIo@>C=%T@$FfjdfGE{2V7%ADrrGFpkn5Z>CAgzgKYz#JzjSYxb zA?Q&Mck{hDosCjXX%V2xY=yE;kbPBWlwbxR?)UqljvNbGk0s90(u0v85eB#A*{{llNe$zzSl>I%ILwUV*uOb4PxmPj;i80g8mpCTcQh zJ&GM^m3#o>W_4rx8V&D?*eYe#Kzj_P3dE$qn^T-bX`@bzd29c3l$DNv6e7N5an>TT z{sxkT${HugT%6iQ@UztsR3eMUM4=ortA7-wzJprk{~U?_gxI}$hjpFyqy{VkML-vE zEU=k59ksOf8xXQSNv#ZxXxAg3BOMpcl5X9i3@&%qUamFRMyO4MGcR5#1+8f^7y=>d zq)VymL!ZCa(W|$9Z1ur~j03X45ZVmkdZdI#;;97RsJ@_O1Hl?cA6(A^Fe7r+V91y# ztIEC96s2F$)^7Hl`4A>Xawk$1ixLVTn>)D97%faPMF)0o%QshRz^v-o-ZQevbD(I0 z^c>9!xKl>Hp83_%&)hW0qC!3qhRk3xAU+CPZSV7_r7y3X91tK;ZBVSFz*Hn~L$T^H zkv~~ZQM3KN;=Qkkewm0`1M#{!sZ-$5v5S&inKRy}Gx(Vu;cN(&>6##e_M57CJLkW zLTMrWQr7=oMmtB$m+{G-S5sTW@u+VCwK8y{DEXvdBb~`?ir!XZSC4Icx&Mp{$*P|i z-PMFph;?XAse5r3e;{C`6^i_d8eaJ`E48t@K)UvH0O)ipOvUSg%^gdz&ZYt=9u1 zGYR0Gzmu1nm56bih=qa?1|q;Zz*I(GY;{1f7FW`nn;V3NxoZ?arMph~B&e_&ujF5) zBFz?*xBFU(oOLB@XaN2_M4T3VBkYWlj-8hCqmga1f9Q*=vc+DI@FNWZ zuGq4OqV25PC=Zvt+4J`jfB&^`_G9a<;iHSlNXFhJ&B0oa0XEfvU_E1BN|!SM8SZ}r z28ySrFY5Tq1%LaX9e%uxr-~?DJ$o}Tq3bwx5`&1W(qMJ*DO0W9Pvnn*d4vCQlbk#z zd?2@)IRH`$G@QI)5O&U@39$i`r00cve5GhJxenT*VAZvgVFqi8oHkS}BsZ(>4Ugx5 z(36`YA~ue7I;=-6zuGQxCSs)sOD_xKJ1>DI*Cb4;Fi21;3NdEhW7kHkw#K2Pi;maq z+DtC3U=&%+Ym3g!3DlB^Q3of4LekV{YqJOx-mr#bHPbq%`(-hK6X=syKrS}zPMO&% zwP2{N^2cCJ!KIB+Tiul53*gwc`0?)1K26Mw?DA?UQpFL0@eG<`S?p_$bbF`bYS_4o z4<&{aePboBo_&3S_LJ3j<*j^+s~-=nQ9N{oecA98M70>uYZjZG-@_&qz6t%g@kxGG)n{Cub@G7x%MU$V5bk^lOC`A<#^XQwQl^Y<7%DxKC z^FX@P;^kyhLv?kOU>HoXLTPGRxF^j@hcHPWN>PaLD-}=NqZt(MIVGv6Wft*{kzfw5 z&Ag^4Tk_2mIwyg?6j_Y?sEu?{S?I*)K=CV-$dKZzSwz1tQuMr}bfH2HqZm{K)I#4{ zb?2fhN-7sU>49|Q6hyHCeM9-Zq*o#G$88i+1w0qM6amRXOGag&G@7Wnfmj1&q@@`_ zB5Zl&w$W`rxl0m^ZbA^OaLOuRgM5*LZ^{Ys7g%xT*8BmxH}}jNa+_>fUr_;+sH4*j z3Un3ssPZLorS}arWyIjRYE~4{)sU1SSP39jrF444W!)R5Ig8?2VJJixaCFX9N3rc< zk3v<7JIp`l&SYmj^B>$G>2g-;>(POw(I8b=)Er-!>E=@3jFQ9}+aA#gF)D#;?7YFCW+D5AO5&?lCrBKaDLtIzZ`c^V7NsM#` z>jl>gCE7#83%TJHm)u&}<2izAh4NJHGpaR{#l$}s6=gf6DCz6moFwc<>; zRAYm%I%HIeJ*z%ASI1@sMFckBn|KW`>in5UsK}RO=X`n0jIPYrRc#4~0ii&vDgmUu z7mU-f15PRX^G7&oBBLZ-Km`?=R15)I7YSoDGMTz%oVwXYF-VUBvVepK@sv5$F<`3* zio7$9|4u_`e6BTCsVT708Obk62NPnofOx{XFrS&YiEQVco2%~UG;K2l9%%)TgK;R3 zd9kFew#b=t<*qz0cjGU4u8_Oq4+;F#o~=BpTyk-w42t2LNIG;L!AKR^*X?V{_s`1! z?r!#g{%bIdQtWHy#z_=$W%mV%F)0{0 zH#z0mG-EBQUkxfMjMVyZoA(R}F%k+MlhK4_d`=XRz+IyX6Fi_XZ>Ra)Yqa9`H8dax z>EJ|CE#YLfT2sSNoNCrgtSfDV_R7y*`m|sAU<7VH8B~yBB*O$Wv?E&4He1aPono8X z&U7**YDxF~bt&l@lNj43i+Gkjt%9fQ=FCya&H1oKS0F@b(?&gGPAFL~)*?8cSYuGH zh}=Jn6OG9|s)4K!|IpU8W{K_ztR`lzqio%kc#?_0)btJ<F>u1q~ z2q<2$tdUB&7PlIBskPEqCMP51n?Lh`HTKnDXar82702WxrCQ+%-~mW>Gj#@#xjFY* z_w+e`owWZF8>Rd?SfKeKo!v) z5dgpg7%M1*vczt;8@liozI@%e4m$8Jd~(;n4C;km_!GEQ*LV_kBCcBPccr@DeG_w}*U zU1j&b{nwv+>_%zzu$slOx^?N*;j;RB>sQvcd#-*pt2e*jTc0j{=0r!)3@J%*D)W$y z0vskS833orw*K?yhmQL@>-pPF-QKr{#y;83e^LLsa+x_g+C92W9qn8_4XsSP3_aZr zU6*EG-O|b|brQP;_?qjU#&*8(w z|Hw(HInfwC?UD%*g?V+Ll+lW0M5SPp>|Jo(Omo8~wFj}$cRh-|m}4yzh6a%xplm`$ z4GEZ`(B|nP&3=MI2N+Wpo@u&C-KP{!xMF>sgr~x}7+?9|PISIL(#7r}5uX%ZYf}Kg z1t0>F#neP_uT0?52e{3BC#y-UZAn}BMECCh_>-!_ziSuCw)K6)dD$;|G)NNxkBPNq z*t|==2h^t5u7J#R@V85e)+f4s@XyhUq=qKLsWh1>i838pq!9MiS`52gdzAPMX*E{k z3Mv1*6 z$e<>5*J%ckA|_Ax?ztVEF)QOVxNu{*GznU1<~8(qf9rhaUpq@_sic{;F!x)mcysaK zif*V<`80T_+@XZhNy>b09<5vJ)#YmE_L)z2a!u*3B_1Rs{Rhiyp%HVwAU-e!SMVvq zpf6=EoifKg(}#YI#C<=`y{4RFlXOXVk-0=iUrSSsTUWMfRN<9U!-08vx$4d(b?ehV z=(4R`oAG;*CkMDn6LGJ1$#I^~8+T>Z*Do+%GNo7L4G0h58iGIPnv|e&z^GgpS>tQq z@^9EbMk@YJdQI#{MF?r@iG9}2-x#FGLf{N;_HY3+B(99u#Dyz*Pw}s$CWgxmFX?-H zV+DGEE5URZF!ktXdz#xzhJBBG@PM9L8;EzTAdVZ)cE#HbGj{A#i@x7pr(fjP1yh=% zq@b`NcLZakovPJ>;kUB81I!e7seoz8oUV=aV6I5+7-ejZrLQ%zXi%|cLQ4mI^n;7j z4lo_MZP?% z7E-*q;VqPbFTHxrXoewS?`pMc(=mhymxrYqrLH4l*k5|*lYI~ae;50AafQSy zXKx^Z9pndG+VGC??zXFgD}C3&Nxf7`Oew5Hnb_mM5EY%ElKiXhcGCAHmC&rlW0m@f zCR67BIEJt?Q6}k{l3NxZ&^^Y5Tuk9tJ02N3WnhmrM8raMt?ha48X^NWz&I)1c@E(c zRWoJaj=+nmK)g$3EwM`*CU1r+s}e@eG*u5}GLIi4v`-WDyAqgEX9iLA4J-J=d*S1C zpj|O7^XYNn2$3q=ZAca2!aEcI2@d!QR=Z1*e!ksKWr910La+c@5Tb&G>&Z!;6n!O4 zWOC@d(R^Xxf5S-{3n;I<2Wx@}j79Odt4x`HtCv1hX6pD`32nZ(SSH-%+b$v!tWxxs zXRi>4aS0E2xdip@w(|Nq;ZB%m9_-w?_X77q(n%bv?RJ9eV*T?L-W+gv>LmrLm}4@I zger*E!YR^mqb4#ZVNFP(WVGZH7+fKBf!}%GF4Jo*1L29^HfJ5*IMs{0I~%{silh!j zjP`JqQp4@r+lW(}KIy$6q+N`3lEvYj?$b|!HZP4q2}GS zfd~Ec4>=N6+g}~A3IF(>qZPacFZZCS{}%~a4-?zqtRd{X7{+^#WMPkB(CH`(;DV_L zaPV3iZYA%L?UJbzV&nbe80ffn;KKWC-sC{BF3ZBQh?0uRk^~+T&ip8+eF#a#ztAXs zh1kJTVTfD&PFSz)N)O^onYiP&>7-ISr4r=qP~tqL^9eVC-<%vCAu`X$kJM3jQbT)3 z1-0aAiU@=6{e2GnD#I>S)CDvD$6FnDg=-VY4zpha=oTz^7sIV*n~}T{zenfAsS8mj za5{;2Pg;QY;_bvR_#H|~5{<`$&mD}s0PsRlI`_*~dY9cl9ZerUjMx^9Z z54R(}56Io=nnbD=2DY0`!Kprv0+Tg;e5{E<@wO7Z_jh02vCOAZR#|+6YO1n3c=)_k zG2pw6C{d-IU+JO!=Ugq$to3R7auE~%M?b|U;Jy1>eg01t=w10w|34_l&E@~i@3Dny*YB=pr?cQm z{tTsQw{hY$%v~d<0I|ybgtnh26>iYqv&%FWTsj zdtuk6%ha`r*(#hO=gSnn?7jxDt*%ode-wP(#!Dp#+*b-CIZTKZY-JZ@foc5bGw zmTqP*IOo-U<)A4`J$NT7BxI>5Y z8Y|HI^Q^#`IjLV8Gz)|X|KnMjj*caxY*k8|X&B)Ry~V-_=Y+rieEZly6SZ;hNmW0y zELbw-qJLwQ8;VyKXdHyxgfkDFJE@(Ym4WW|U)?&5YDX2pr5fnuD7H(pjh!|t}Y0o!K(eHR#Xf$apmV@BMz zQ=54aklG=?!L~CXF()P68vp**lKk3bJn@NMuaDJ4Te@OF;?1tL;0@xo!JhZE#ftUu zwJs|SA6AOu?-s9i)EGyV;LWt?gxuy@;r&Tek6W=l8pH~DsaS^}pCcSq^_YK&T4M4jd- z{LP-qf-p9-C7$0XX9GFWv6|Ds24kB=;Q30H(4=|Gx_)p496E&rg`DzwL(55(nVF>u zG(l|QCu7MLEI~GHr+%%JYMMXT-#VlVZi0|s9Nm<1%FNOHVU&JvDdq*r$1eh16Wx~3 z_^Z-B=HydZ&j_20s?rvaZ@E=VC^3uovPvTZ-U;8~B?b>M?U1J~C$+ez- ztJV57yM3#xHT8XctE;uvZo93wT5k>c)c`6^x(9yvwDDMh0A4_$zwZRsO8NXVkRM{&p{(z@vg0dDa2ZaQF z=N`VBwDM5rwUT^4qV@?OWxe+Ihwr;1ZLk&RE{2+)p09 z7Fby#TnnLr?Ym{`o%hbr;n5zue(bypzp!L3ZMyp9;&7BYN;Rl%_&PF9boevqf3)!+ z^M%v5G<09y7(I&BDVG70IYa0Q>1fb!haqDKRU_Ksli$5_jf}9aRgd@@`jCv2C(4sU zialrlYu=YxqQ|`d`S`j{!tqVjcukJ_i2H0qW}k3nGON2xKQ%y=|F#?7X8&;9|L*Nd znD%&k;eD9d-BEkxgDuCTKRr_|UkK}>!JW*y*J33+_V6p_&>Op8eC4}Ehg56h+*jsP zom|_lDc&1C6m!;9YrW?&J2t3Y$D+F;>+h0JuyOeDAxgZ$KhMp@xOH{?kFPD&UF@(z z;C-F@b~o|3FU(Kd5&ELXPi6=6F!Sm~Og`eXI#K<&idij34!lV&r@y&915HYO^}fHB z=~MgfXA=l{6-D8-a-a(_0@?_*-&16%CZopTTwmwkbzTu!?8^6LN5v)Dl@@JDtxZ^o` zx^it~IZX=u+;yk7kxkpEvNZ`DFe_$nX2|3??1L-ZZRxeM-hVS=m7l6TlQQjam5ihu z$Wj`-QIA3LV%KIEUl`|Ln*!_qE>mjbc08%SAFL`CA#SsiUh0kB&d>%p`KU@lHBB|FmxY;)!6H|u*kmI-7&P#lM=HhZI>U?nb42Nd*b`l=keHTxS z#Mm&u+l25d&WF>@*58qzm=~2*Si%1ZD47&lx4SN>&i0K=q@5s%VM`P0_!T$d}e8uldpnnex?Y&Z9+Lg`8!Rb}9Yp~{nCsLST`@shtC5rD0 zGK6k$u+6<{%y*edm{btw2AJKf)cRO3Hd6fx-xnloaD&eKqm$kmmQcj`KSwf0{*kvq z;E-frTzK&#D>8EN{ZUIy_O)9Q1Cc6rEEAcg=!f-Kax`=F?DzFpnItN>!m9$j4XNf* z^iYYi^DKi3V`kcJH1x9amj657J`m9|V!sH-@% z&^Neq^6+vFt6B%VKY*XqruvqbVhDS7#uX$P!#5uf$v$Dd2n_0i7{}`13*i&o*<|p# zqtH>`TYll&=O9OTF0ZFm2FTp+(pV_QXFfhfuk%SB!AhNb=!Q~V2u~dvd(~M*cnv9? z8o8X<@+qP7uxhvou?Riod$O?5bmxsd5c`cA_}l6(YML)%uh*yf>Gd1tS?N<)40qZ& zpLvtTo0)2<6~1ERW%sD#-wlwEqGZcYwyK0&t{R*@-{vEQ8T$3iQ=MlXy3O^9siNwU z(6ZAJ`%^Bd*7q0SB=RWI{*Cx3vq$41EHu@8|jn005z_Q!+7@l!62*GS?Rj z8L-0_oA6Jv82qg~JUw>qk@i`~NjU^;X_SHh)N488N$Lt7;!K}2pwDXYfP?4c&>?|H zhB2@dR0OtlfDwzehny5}QqM#Vl7z8v&&7~|G-yG9a_wyB?1+oSI%rlr?Wu@D*bYFM zDq~ejJJRpK_CC3lIteP+WFP1M0PaG^~?M#uHo&!!>QG zz#k`}49YqnaEu*`7!|-297Mf#pf$_){`AmcOIrVwn7oUCLPnHM<5;nw*jXf$)l#L& zf+u0CGxlBjQ%;Kezu0pjAePzar6j&rT}-HQG4fCd;qB=ETGsG@B652#LJBF_kqg$4 zm;soVSr>2qr%Te)Jd_+1=vs_CHo1IJ3?2a%63OF&S0@&x_sf|(f;B9NQdUT45TIEy zf@Nl(W7^e_-;C7F;v(*r9ys@j&9t71E{0{ulEg50L+Uu=-vf@+$n?;REkFWAT4ES?3KHOAngYBw@IT5y zdW_23G7g{^(^?RNbdiaItQf_VXgL{k7clhbGOb?!fJlk#VhfYZqeZ9)&MaMQ#TQyJ z1j6fQwTJ4`t4DMCjX)w|CJMf)yCRk{7#2{m)q`0A2j1uq(zCaQWF`?RK9)ySxwQQr8^r3WfFttlA zqXq0M`piJ{C4pBs83iMTNtvRHJE|ueNxau;6KkWY*E13B5Ko5OiV0)~_@Xj85QJ3G zDOR3fv?O<1U*AQv$5s^D2$-bUiT5bMrGX0sDiZ-4*$UR@rv1^z;wZqOWJ55yV^YUF zTyw@{7$*aQm07?TjnI_??zsKuW#&Bg zLUdwC<`NQ}3pvk0idtC)Ak>*-tgQXlpXKUHC-EW6q@Y~>%)-+yIark_?YjAdn<3>>A07jn)LvyqI*BgyYwz&(TZ zM@Au7v|^q}sm5x{%tBG-_oCpTE7jq z+iI)z)^EG5w_3G+4R79R)jDgp-Bw$zt?Rm57vC3&EiEcQ#X`FNkq75IB2Y&S+GPLl zAvQe!S8qqVKi}BMtMzYpo$+J?p?C*}=`AS|0#Q3FX33@nFk9zl<>>x*{Q2Dc?95NC z$U$PBe;Bx2peZpjkR2DT z5SL|V*!<=eHLM#fwcrG;8X&Wf32DJxIROFNV+jPVoKh|=h!mU#iT#L2a%Vp0{2 zTv698o5j7G7ePiP7;zW!!YM*{g-%J98Vlv?IlX=!J6GBwrt%VlzGWo~A#J9;07014 zW>sZGA_ntXa%pGe#MBo=H3JBXwMzp5KrU^e9TZw)`BX>D&C{dLQ+sJah>}*R*9Hx-*aS-& z9dp^RSI)-@q@s(-NkavJ1jz#Hp-_@ak##Mdj-C+}lBg7i4lI#$t|wFn`J5<1MHy|v z{CPn&#T<|Xq-GrikrfY$k7UmFsNLse!Z#|Ywa&&I(t;q!p-ccHTgDS-D=fv~;oA(R zIb_IHnKO9+Mk$(t+At9{kK&>azYWP!4w}$w63K+t?ir*}v1fE_>ZogQX3NmZc;_K# z(MeuALBn=}k|1#_o-cphZRW zCJdq(tfkiCBO$XQVX-?3(C3OrBhBh^tFK~OO$2|=eioBFH#G%k4C z%e9qrCI+$#;601gla3KBGH94HHSPtgZ$U|fX=w%oS}I}CR78N)m!yd~TH?pN#v}-Y zWS~tgQj35|#X!6inRbFcSU7l0DZZ0%qtq9i7$Rsb5(w6QHH-Y_>n1JIAX256OfK*V zR*Dl+3^GAH>Ev@x-mlDiCN&UBB(IOf#8OZNj7kES2-k=u?4R>?$qjhx5Q^fOIwtA_ z4g{TraI|nF@y&ixpx!&H{3@-QbgcA0>4&HoQH*G7G;ky4rK9A~!%Spi$@e)-sq7-# z2!ph%A$4)k=l9}Wzo#WgbE_Anrx}h2V#7;_a&C)z=)rr$#$KIwOfwnuOeZK)Bm{%y zK-(fyScm{b<#*mzTBsL~nz-6dhI!m5KP@ufkQm^K#M-m|^58R5O_;Ti18~wE9R&sE zF|uHDnbw2{PQZ621rlr_lCSH9pm`bjr=;Z3rPnwG;=>%KMk6dlplCzJgy7;V^=i?) zK}ayAkrN@46fxuq7`FyVkXe(bL)IM^K(@eqOFlCu%7mBvi3yKlOxb~2h$qrHX*U5g zEcuU^4m7#di%PPPk_0dgz6NS3i|mjMvg8b5^`F`06ht+7D`L`f3&;r79TYdSts1TP zigGK_SOWuw+K@ve$nwnHRXQUu>5>?IqJps2hvcitJ#bsgN+_@w-Jrv}N(?$?olzRvAmROwELeNN*_%R%$*f;^j7(cmBAr=+j6#->2h6(U3REPIK$*Oxl7X5#C75b$VjKcJ0#hrwz?4A{ zj2yE60tt2ExSEXZFd{r`+Yu`HigW`i+;H`PWw9|>k zDM1}ENXa(@53#4?$M5lB5?NA!e8I7pF`x(1(2?mvoPkM}JgIjOPPJTQz@`h^U;*T~ z$Y&;i@&hJUbP~q2#Csvg7JD$2_oTQ8CW$9v+&CUA2{RPt7>gzZV1gtK(J+w}u{rUS zuNT@$f`PEq2ECIek1Bm## z+YOrVPWTDG;n}=8*e4r^5}u5B0;HO<%K!(V*rICpU(p2gu``AN1KqR@byz0dmYX^x zI#5J(rPJxy0?`B==`=%131!8kC``{pW)T1YW&mhp00051?p{YpNyTg|HU^A4t79;z zd={i>k)Hrg0>f%|-2u3^#<4@Az;DK%fuEB!s*Y&Osyf-WvMeISD2@A+^w-C}{oUMb z*UxPISN?MKbn?f(?q3UapZcz6|6cW9-FnXo?!4Kj-Pv_V?_G|4SCw zi$4{;S(W~wJ8v^f@0&;2unQsTSOyx1#baA_5=FpLeIW^I=dyVk#XecTdD%d-RSJQ< z>uv|&k8I~--@01YHv%_Lh6bI;G;lfcKyzVjw~cVo!yB<|eQ{mWLN2(mRWR&u9>&^l zhy0EVZdTA-#~`%(g|NJs!~E>$(^rv18>G3GLKa`Xjlxo9BhKh}u{toJ~*Z-*gVwz-avVZ+rI zWK8pOa&(~QoJZT3sepCC2@WodNv8q@!BsoybcW9a%+Suu$kJ!+TIVA}D?1_QoX&zH zSM2t#a5M8-ooZ>H!;=7ENw_(CT+^I?ZVpzKo=!(k*X3mF`t;~hvwIPQzcu5;_W>`Q zl}K)lv=8e-Bjw>T(+Thgn)$i!!oMKoEz$brm^aM*2<}{H)F7?W$|%8gosV-cRywi} zs}B6!)Y|a=-8$jVoBc;VcR&BhH@kDcQh!4hicN1mN5iY(_5Ef|^4Q(N4p8df3c|iM zjLPo}Cy051$~}|u-aclQjh?5|q(eJdq9;T5JN9D!^uOT?7yC^O7@>Pa8XPM8Nh3Bx zqfH0SvKjd=$iPp3*Q-IA?Yo~;xNp!pu&<#K|99=&IdYpOHdo4l#V=&lG5zONHX&;~ ze{6Vf@fu^<9oq@qd`Wv6`ZUtZKkk{Q{h?uRDBXATnQpLVd98)&k}#T-rNy)sRGvz+ zQsET8=Ckc@VS`cMpy(G}5E5K-dLMUxfoU7rOTTT$WIi(s!%LF_0KD{82i!}rSeJLe zz0GZAaBr&wv<-f*E}Cp##d`c?daDGRyR~#cqW5**+KgjS#t(7Us9vIad3Y z_4IrXFsDUT?&9?B--Z!%65CjC@$uO}{;OS&f88IMV_pm%t6uze?=4_Lm8YHTY6fyE z+H7|Nw=7h0@k<~Y8*RI@%)DS_weJ%5$<+{9hwqC)p;(;$_CXL^Y zwrsD<*Yk}7u)oFa%VKHYbLA#-m2f5{C&geC#hFgy+v4o?4-^Jo^S$;LXP&(Y_`Zu7 zz1WG4SLyX=goJ7=?g(fnOY1CeP-mVTN2fr2zWo6=nD~p`fV)(0E6HR%0hqRd!>>_I zb?t|HGk92l4A`r1YM$nC<|B;B`>IDsux4=}$u-4NvQN;?hO|W1i zmz&H0_+bJf_68Qk)it|OzAqX|kXB{EDHK7w#yo--F+jgVEf`7E?o;v+Gbtb1bPHFA zPH?VSu`ipE=)sPL1iT3jtZ}Me5QRM5qm}IBsTnyxwAqIa-oFZv9PdrXMjAZ}H}v2SiJ$jV+?k;}`ed2iHX({P z_}+E*X_>4X?odEuA$z?q4)b_;XEa8QoBZDx5ai%8}Nf~abV%tswidQX!LXC zxq06wwNEMZ86DnRD%`1->iW*WPOr3Vpk-!$b2%NlRF|LT(s68wYl8jTn`-28MFs6P5-*pqsB)h&!p- zwX6+`WE_Ae<8ml;7o%K@1qlxlzJ8%?HV^#3FZJis-XajUXmI*1Lm4a==BX(70(vQa zq*Y8A>RjoMM#umj?qU7}CNSn=f(yd$1oxg@1OhAg;C|bLg&R^E?Wgc!Gjn#fxH;(} zF6k|Xdy|k*E{xUFwh5*OX#9ikZXyU7L#aW?aqQW6VUp8+jaA=)yB}lbrpFl=g76o% z`?1~Q42rt%*+Ras$&hdfTiwM_32q{uqGZvJ(2v8Cu#IygYws=gRx&PnJ9EFO_8i zTZQP8^iU#NkGZfND!**kk8J>I-1+ecjQ2ivEw?9F;~4gH@k6=HBWDR?}rd8Nd2xF5Sg@@{!7@a5l|`R5t$1j1M15xH-oox&a4n;Qr3Mc@yGK{sUpSx|dy~+m?FsTK9vi zl)0vTcCR->?*RPfxV-KS*3fP`2k`3)j1TP=jljjg|7=(TI6NK)KIkO_iO5A1Vw6A4%c{juz z^1QhN30|+n)_XTrO9(r@J}nt$Gw%#b)7W+AZ+fHe@UQr2t0@=KTgRIg&w3ZeKX@_A zPIe6YPqmzpDL9qQPPHo&K5r`Zbrsmw^TrB3c&CQ_IEM0wRROZo^C%Em5PUi+V=O}d}s)xdCe%4{@_Y8a+IS~ zsr@ZSI!aM0Qq{GM+bE7wlzP;1*Q1S6D0Ru(=D6eMn~r%H6ToQ<+t+DFQd)x;&}K}$ zpL{PfOGlxfaF-hfpRdEuZPJk=na&HsS9;FIg{?mKMmvJVcRXiX%D{@@)VVtgrexvlA6f0N_KeF_*zWyc{N0r0WqEE-yOjE&n zL$H5Woolo}tbKOQ+FrFMV8qrF7hA;$9FGk>^>;OOw*k85re#jAxXo`en+404MBm5X zMvli`dez2gcsX*ohu;MH6p!PCn@y&JTJW41V$Tj}F!RJxL6E4t**@*7=O3haWy>v& z?{)`Q-Ou+y`G+-k{wPuERQ;v>ZN+1KdKK^9h!M`{eEe!iUAka&u6tYmI(EdVx(}|vC5p$=Lm63>*H0_^k@3`%Kz3T28;7L;d(TBiB^=RvO zs&p*7#CO|;x3X@iI|Bs95e(m)=|Q?x$oHgwN(S#6n)UHMuw+H;$Dxd&3k)F@9p4zS zj|by-SHE|2lJO4xN3$&6o799gg4auXSii&ujG5s*<7i9cTWsq1>D0vul9u4R9s8Hc z$S=*x3V3BaVir2GrB(gbd9@GGC5!kYj6jz%b>+uN@vbkepn8lU0}nZ6o!-% zUK>@7Q?jmQti7$wVlVm0cl3}CSi$d}2bbe@eF=4BrSI9w@KK^r_R%@A(bo+Br!kNcOul6wxV>GC z0Q{^#7&tTw5j_R)5G3ULEYGc=cDV@0a|S;v`?i zK{ou)Hm*wUjcq91Bc?jNBCTZmzFsDJmVO%=c5w~Z(G>C!wDo2#cvx>POI=0V&w z6V!tlK=v3bpo6R39oOXf>af&WKs?FZp$GmOuG$29(X&#ZD$icc|NKAId??kc&Y29lZX1Q!?MwcXa9)rCfB@F zLFMY$OZDHSl~c;YckU&CEB!{?f%QyZFy0fW=q43dxj$zg(WkrX-QB}h>IPu?fZbf@ zAy01O*3B7j6+OlMT>P%n?2fO1$zA91`DHkOh0*E8IgDb33jBEG@2DCcrA)l_84*$) zzjgJ?~tb6q!=IPqv)@1~)0>;@RWrbI>CAUkX@_3J3di&ew>W<2FyFjobRJ z%oXbBI5K)j=shwg2EQ6G&r<30bk96AkS1h*>HrC5zC5TYo= zA-JD8PjnLN?u`5?o}2(s7@~HlM2Fg%y0p{)ps7bSieyt!R3`HKxi|6b%T3N(n59l! z<5O5$5PerFBV8XdCj4c1 zJ(u<54Xw2Zf#%$Q5*YVFpD1*(cFO26!qXJY)hI#BA4JoqAt)e(&|Z$+NK z(Y{WZyX&V*q{AR{WAFu~ZpkodC0~_2D%ct(;#1s-hiC3cbxTXaSwwSKq{%6_10l&7 zDA+L-=Cd~SxVM==2(K(L*jnQHnv}`3G_J{_|B&Q5`tE>SEw)(C*O4eG6Jki*7a^#UQ`5kAVBQKku=%wr7W>0Z*HhX`rm$Ss7 zDr1(Ij*O+1VTLNgA&6VZ@L0ie*J9Ki&N-R&{@1S?p-EzD2`rNj>je}R=ZS723DfIo zXbYM}`p%~wHL=kYl6wkc3`DK-6;85By_9NX9a>kd^Us%@okz}M%q+>NLTHm( zF*#-k+{$(FO`ttWDAlR&RYyKbD3z)2Wk)_rIJJhoQimFkdz4Y?QsD}Zc9f&krM8tF z>nKO5rN%lRe3VhD)c@O~k5Wp7YCPRhj#8BB)ONC?N^{xrYlkAm$zumh3$+PDs?AC~ zTr)JUi^&@5zo~`unLO1=yTj$#ttJE?D&u4;^q`=EJ+O{hpAEj13P?EvB+bx;AUguJ zfFc}V8PcHFZp^K zOk!Zd>tlKT8)%;V*1|Sby5Mm1}0;>6C;?Mp6gEuT#-i@ZNoS{ zkkgEeWPwCb7X?Skm{L;bV1SObyrbT{|7SZ!oM{h@*0Fzf|JbAU zx|Zc&s6m=pE!Ie|0*n!Mjo^zXVGiI@L3Jzwse2HBt)#CDzr_cK59lIkg-2Eoz!Df@> zu4~w`(fA@W>Z}<_2JdCU`cC;Tv#SkCj8ugc3duw%rrO_$ga~O~qzpohdg*z=hI19 zT1K&uQEUqs5Y-fPB6!#f0vNbcde7%oJOwRMj5Ni@duirQL8uacl5&d3&55}tYE{Z~`js#5V>_Q|$gEBoNOHnTc0|IdlV}1Z;&K$j_hb(wtwlo)SKwh% zE21Dfa#9%&1}OuidD}3C`(840}9c`-V5FrReThb4tKm``YJr!AOh>4|^3!VK*rKuDt5FdjTf!5SQD51`g zAjUV|wb-{eJN0A9h_+ITg0ZPy!fRXzmV_vYKUZ5TiL!Ut9g`>+LIT2du&K>4s27=( z%@B9?c;v$jC?3RU6<1vBReh=%aZM45dQUyl z9{Cz3QV9eCXyR)noP_qM@oN@y&$m5&^$m?X4mt9MU*@5xsyoVP7%>VRypcRkY9P+(g3W^@ zpA^+MqWsMRIVv=X7G;CM_O6VnT|40Yx^?#zfzMDx$e8rt)R83zX&=*i38cznFfN)k z3EVQFU^E$pbQ0qnJrI|xp=9c`M&P4fQhzxm7%`fb$07j0ZGqNNaA3#8M2W>rfu6MD z&)kI5jlm&dlFJ}FaW!^|TMCm{aixlKxsbz6b2F{|)8CO?sV8^~39JN3@T8VBdq;Iv zs5J9)@lPLGiKnFE7<0s`;t~;BYXH-toTw>ik*&E-jB}-^GLCZ$!AP|yC##TFhUfsi z4WU10`zm24;gf|?6=BFrwbmz1@;#L|C2cd2w@zjRd{Qea50wefksSRC5WZli)#=0*#4e2yAgF2z#FFo%t5!1#}Mu?iau!9Yi4{7cWaC z7*MGn;lGJjgiZAh5vsq5PeV+K6Qfv7f~MhSn4fW!X7{KXD{{ ze!r4MfNIsuJgk$*I%GPkFhT=hv{K4WH7FAbUyD!zF;zs!gkpixr;qO}IvG)RMDOu^ zBus6&*9xdXe3PW6CgV>oCKI7=h~Opg$pyB;A_5)PQzj}x+KD*F4j1kF^1H5K!9oO~ zRK&=&E0j}7JI*&w0_%aO=7b6+ zD9z8fj6kB2)=!RYS#Y~VCrmh(=}81u+5A0$)f^(3bTZ5 zNF3ZrMPrm`#Z25%A=8tU3xkpNdlws+?lunjL&>!d`C1#-*HcE~2WZ zH8#Jxze!=z@HmnIOTm+n1e&GYjSNU}YO!m1{}YVf|7nLtm)wVDjxg{*K}u}PVHzob z%ipc!h|nd+BR2!VkRbKZ}&iA-HcFk&v+RJF{Laf3U#zw0#b8p29EE$L1V zK*pW7mbE)5gHfIa)@hOtOAaE;ES@13LQkpW%0QSohtQao!hqCLBp)OfK$yj9C`N^X zl=W5&Mde_oBtlawPzR)$l<&HGD^oQlcrsnft*5}q1|cTCAbfK|6KkD7Wys9h9UwDj z_0Whdno&Ua@s1ElC9*VI9yQ_2VmCsVYW`beppd|5)TC&m2(gT$BX1hh^0B&Xo>3Ztw70I9AIixiG9n>x+RhRw_Cmxu zj{bhfth>y}#UPRdupSGM2HYia~ zU>J;-#EYFX2d`H+YAR2U(3nu*;kev$G1oIsAyi5x1SO_w^db?m!kGQw!bJ&;kp{iN zLX`KA%($drhhXBjsjw#z2xR*VPA6Ou&=qz?|w6e-9!=N`kbG3`7I9E5tmG zPf00TM;qP@^aBy!VQz{Mgd&$3!pS!D*pSrHtia91ok@u?tGbLbkV>%j zI`Al#ZWbw#mA=d%30z{t9Al`bs)iR*3`nV#nTPK|MCX<=k`ISe=d9F;sHI4e$&zJ2 zI?2?F_x-wbynCT1$YCo?RWpksN!);m=ZK|&CrYJR#m6D_M0`BX5*Tt3Fie^{?d5_3 zF;S&|kDGWnK*r8ER&24P6zpihg^UvoBd~3-%O?0A?RXZ;nhJmsSd}^vY6u-qn4(5z zWxfA@=hM}v@A_rCJ!A-~!8#V{kTAT+i5!$BD)dyD1aBVt?GXAL{zjm7i6Vw2t74Qt zP{eEa-zupUq=%?ZG`eRg%|aO@YZ3rc1w?GH?LaAX?C&}1*zamesSS5PLN%|&kO-iu zN#L%{MB%KJ>EGYR!lY0P19bJ2aV-=R!yHuB9mqk)E{qP;0B{fx0{{a6GDHIa08npa zK9!3C%3pq-*0+}0NIXe^pa(z`xtRi=z7?+bvcX^kdrkhmE&l)rA{r|q0Js1HLTqZg z?FxafU)`q*^};WF_+-Bx?1dYo3!lPgLE0rV^R9#}!1mqme{g~9+n#m}t|2_6(Dkk7 zdk$-8P}}X-8mXlHeyoSvwmt1Rtg$S(45>yU01yEHBAI|9vjZjOqK(2&wK2WN_ulSy zQ0~jL6?(F@0WxJwXe*-7#9#VDCqf>#wbys<*$s-@$B{-dey~0f$^Y#m)*rs~dEDXN zcmICtE9c_ZICGBtGf&cu`1bysPj7zf?AOQs(Y{o^m5{1QX|y7YH{ z{@dwP+@JpGOUHGaqxS#pdno8}68yRJ9{1w?2lU6_d&Mrjw4Zym=`Q>^Va|GU&_ieY z`_Z4b@wuC?c+7ME?AbdHfBPzGphHYhrqt@GBx2Y)fXNu6`FrmFFV$Zk|Lc8{=_9c5 z&?(3G3`5tXro~Ux@Uc;Zu~09YySr(eiyFwLn|zt`>A}tY>~lNZ;5j+j%LE&o`0N@= za2=1jYFc$HcktuD$9y9^wC>XFCxC|r`}?9gjK+51T&YkZCj(KD_W<~6?Aa`lJsX=# zq6XF>&YF1sB3+uI{B`kP9r|Y;+zY+-yRZAf&ZCz;qXX{PukP#R;@GL(H}e14z9wI_ zuof$R|KRplUvu16d=@{y&puA?CJ&#;lM^`HnLxgX*%3G9q{P$JA6;ipGtcpI)6eqa zKRB3Quh0G6=?+AEU>}Y4Z35U-hy)T;E9$HqY5+7cBf^krv{-U6Hus; zQ6FNcMOncMbLh?IUi&(yFFl54ggg-YKl#+PpmBIGsVd$%lQwcAv|I)z53-*nRBhaUzk_Ds!L#kIDJ0=*c zEbN8C1L?c!A-P>Xx5meTdgVTxC{24Huq|RD6NEaIdzHR#Lb!FG9!pVlJ{)p?0pl!_ zL|9w?x4H6f0`XF3ApN-xQgFIN7=K2%-+s`q7ysP5=<_3I83=~d_77LgNhfT5OSO(9 zl-W$RhopFNt{m?k{1_RP3Z)FF2P4S`HmE+~UXgk*2%et8iIdT~d;gnM*O(4WVK8aK zrDj1j_h2VsLW;vakM!x8u=D;67z)hh79d5o7|^U`P#HV8AUqu1v#@p{5vD%)H_xHl zJdOS!Bu-Y1L(Ldbl|rgXO`yC;^+v+o!JWAEy`F3g9e4Yk5lHrHF@L+nY3r$B)D~e; z{wNXVv|AZ+_q9TpVV3d{&0KY=htNW4aP85w`a#pDbK=nFJ<_tD@!9o)|6n{@B_UT) z;a9Bzcc}h_N{TBV9;dmVq0+aDP=Bb9gUa*lxB=im5B)$+-uB{cMI-qO_W>hv(PVlD zQw)QrL-9~k+7QcDRLIVN#eMIE%C-^B67hwhR%pOO%;niyaUfM91D3| zGdQ3I0_z4_LT1^CSdtTAL4-|IKTff}igWmJ-^VDeBZGdI8p0-S*yQdizY8&y1j}eC zC@M$pal0J39WF-WMPEFC)eM63(y9EW5q9v$pX&jTkP}IdgEnyY- zua-|$a|bVEhxPkEWXsdH@4%2tK0SNFhTbQH<0cA3Ir72J}**XutTh z3*7FvICGzz>#?3k?_AW4TQm9}q@bJD`!;EFuW8@-WP!2z~4hFcp?;^lZQCMQL(y`}QE@k%&3Q6t{-Z((tP;%?7f`;IV8w z86>QDogW*Cw+HVSnAGMEq2ii}ZJoVD1qk)6oQ~zADEY@Wa&9xuePjD|Ne?D!%&y2(wDv%s)bP#w!lucC6tx<^Tp)SFZs-nlRT}rXAH> zD#-UNf_v1Zy@dC~9{_5Fjaj-I}HQZV+#*BKsEk#at`=e3nJp9^^LM@oBX~)`E z`TT&BvA9}(i2NH|G*J%1Uh53w&bvO(cGl_^OWHeX{K}JaZVIiAFBXX>;mf`5gz;K$ z7qyKQn{Zgl23cQHLU~-7-Sx#h(C)SQFmJAM6~ntl${>fw-&5i;t8t$&x~YqKq1|ou zGa?;T2C}(LZO5~e)+UFQbc#Hk?&bT?)EZ?>+PAQ-wAqG~Ibl&f_{i^FoELVR;fLg9 zHtij}wPhYH%fq%0>ZRs98Qa$kI=Obs>ape;21`h}C8tRMX+W00Ip@3EV0q%)xGlsE zHh%WG`w#sO4LvYOKI;DL)ba8=@oidZhJ?qF_g}{z2h;x+IZ8ToYzp&L+T=i2(ZBph zg=LViy*%jLZ}Rze;2=k{IL{$$m2cmwI94G8@kaa?qQ1`l$D=$>YKMe`t27R!1m$0F zsFrV`l`WNbdja;>3wY%+@45f)l@0&W{{p3KLSvlgkGZq9dE^C=0V-bpLZj;H2~Q|l z9*=uD^Ca!V+y8h}9k4QvO@Esp%Y83B*sW{CoPwqFccWMdNv&>yP;cD0Q^7lj@-wH_Kmh+g*mt(;CkI^5D#r zdXq5wX*e_7D)C#4l_p4~75T*l7f`g6-|~N0v7Qtf*k6lT{<^wy^BtSBlW1rpJjzg5 z2@{@zG;?)Ul?4zl8|p9}$PQbJWmkz2G&C_bBB$17YR^tP4jp%5u)38IHT_{`wZ}D1 z>~IGgJQW7LxR`T|3@)yaw1#(*M_s#jO#?$mw}y#<>b7M?b}e}4#4&|lFKuY zt`cR5MmPlrtTfK7eU+Ub5K5y>DA&3?j~FYp((=aby9im%5l9D`}TqMb4tLr8ha^j)kQVeBq12R zULEoz`eGFxuwd1su~*i9wjUzfqoDG1Bj`oGD?w)yE9=2VqTuY1IR+Q9PHWd_e+Ulq z-cC;FOkyHFXb^9g9Tqb>j((Pu#$t1uortxB7wd`Gmkykv?A@HJ*%43MFQ^5#+n|A@ zooaceM+J$jcpV3Pq$cC^c{_WhdYM@*%S$D6Kq*6=&2ogo}$^Ac1%u^1hG()kWO8%X@rKF)t0 zma}2sw#4(OgJL2+Xm@^y#^TMpMvJBfdOW=ii#qnN)1yP#$DI`R?k%U5Nqvz!5(JwmX>@Z~g^T zRA$z4I7c-#@53X3f?+kZ5Yp=h#p?yoW;)J%HUO%pIVuwB+^yWX+&+ZcD z6;4Tc%we0x(r;cII8ppRK(HhgO1vCj;giWgw)&Xsj15 zfncjhyQ_DCTnIXvm?aOyB4(L9A2zffU{fY5Jcd@_ohr&)AH;rk;007;Yc>W?gMyfB z@FLGUVX`Z*8H9gdP4lt(+ObS>qMD&?6{1@T&un*mA*Asd(YFC8V*Dk2@Ucx)m7PN) zV>|DxE!nT1kHY4){Ct-`k@KGCdoS4Nv$=(SZ)%8OE$ETk5*gMD1 zsYu1&zv8-c6u=#Bkf%VFI_ET`9s4m)=OKu#cz=IuRD1}jt$yy zUOrq(cI)|FS?}sSC7H4n0&mB1Lc=TP!IcAY-DX_D8McLWiR-M5{?EtK0~eVieZZ(m}5r0 zfunsiKU+XF*N!f>4+GMm&TU6|H4|EtARF0hLgrx$P|Du6(6uJPc`I3L0b=sI9yjFV?R2g9k-!ae7QjZi-e{TiQRwceW z*^VDFfZ}InSrY}IakmXQU$^4NQmNipp$GMUlzcYy-Si6cwq2`7I4)1u!`D&UM`+L5 zRPE*Ht}v2de}di}u3i1w>dybaZv7}LPAoz(_u#?xdE5%Se^g)0-uBhT| zEIeo)-V(A(^Ix!%T@lD5(XKI@^C75zZyr;&@$xT;xj7%})V8JN1IAfFYHGQlu)UX% z3C^{ZQBBM3dhgBbQpvcxmqJ~1-2_eQT}Ecn$GoDw`RFxHmzxo?1Ul+36DAL-LUFBn z|B|Ue3qReKCrwuYc9vhVFMK$D=8Nk!EG-0P>u68rDpypSl%5 zw$jb-Xfjm;%d)R6c3HP0%Pw=3w`|>>(^K)@*&*p$Z}2joXF;!%`k<9L1+>%kwn{3@ z3g{a48aL^ocLOu9Jq+jdHt77Usd!XGGtOk|ptQbsA(^Qsm6tKq?WaJcEGa5d22Rv z%=Jrf8VT)_3N>2&$ENB)dtuWEqV1hGLLVSqd&jO?*CE`}KM)kHxAvLNJ1i(`wLAYW zQFG|jU0L79g1cV?4d}fFO>&CO>f5ni1H)jh=uNH_AU&jwp{Ih+TZSv4;UgYlnHUo;F_XV=Qc$fE&?12_NXj@82%z z3jSa%rT^g0Kz;L|gPtN*QBKExTH$c@8{WklQ4rGpm)Wsxt6lg4voZSnaB~1{`fIk(B#Kg(QvTHi0%;$0LAxw+&Q*-jwl`k?-ThN;7~s$;`Eq=U+oRW z_$=ERf72w@mG)#G_gs_;JzWs_VnTNKUb{QR_0iu9~I`oQeP(#9Tg_|bl!)ND-zB`KmDbfQet z0osg9A{?2?1ImH8f#Tk|wnih|zrrc6*Yl z+A|%xXAui5e8t-2yoQ)Qx_sZHUA81luAqy7C@n4^Cshnd83&;N(Z=agGNC4lY*Z<$ z8*zFOF<%rz&O}+i6)m6G1V#8B+W|}odxs{TUH^uYK#(hu2BYaQe&u%5gUY2h6Ck{T!Y7#*CZVW& z%z|h#wdTl*XercRY{?d-`XM$!P4$UT-seodYYNFl(-=cI~Q{nzg)SUEGa`J~F(KqojTuCw1iVHx40n>C#4JRjM zO}+@c2xc&$h?fGfnNhLyskIUyABYhgxKyKXSwgj34X|66dAM6NLnzu}Yo+xCGqX8H zlVT9wL$?~W%k0YsPDKQX&XSx0nK6N?S$$;?i2q8WhJSQ__br<9%~pz}$8%UR*f3+E zy0*e)prQiBh^Y)DDwJ+eYKR55ECN^?n==Kc5GB23)XBsHTX#0oDE(FfBsB?3h#vYzW9hQVDP50n z=HfySn)MqH5CSOaKrAYdTx385hnhf5=YWiZP_*9KwINSPF-0(ps&kDcHn{lL>dwdfM@U_GMOi~aP=_kFJP;(mwX1l}+o zC;b)gF8io<;o2+Hz2rh1dwaV03rt^ehCF!PEyvcK!j0U;Z|06K=s$(OEqpg0xx0i| zyv6_BO>f+t!kFB}zuk?lWiaau|6zCSg}Vdb_Z0roZv27WSHIjP{Nml~zPIkG7!eVYM0=)D_dkF12qB{Z zQW7goP+~IWrVL8Sfp{Z`0#7gF$J6#P+N`HZLd*zITA_kcASmVD9CN~*mi#3L{EUXs zZKhkcCXXRWDNAq3TB<2dnlevL(!}>D1`)=kIi}(P$YALODvC97ML2Mw*iO<5Eo#l$ z4Qj-C!G772IDAkho!B%`hT&H^a87*YKC*b$+-^=>OG;8|j^Ubh5LeQg+f()5$gOi) zmDeA#^a$|r0*k##INsiOX#8fdNg2~1=XkG#tC=xL}Bshs_ z$&`-L%>ue|g4bSAAsGXT98?ckF30b+l6595Gviri!W|~AN!@5nXl9ic-dVw*d$kh{=aM0fS>4xQ23&P~nHLx<+N<`u0 zh11(cRzc7JuFcjsgUV^A&lGz$4Zumol{-zUm5UD}VGv|^F;?B`^!-eyD+U9d1HdRK z8Kf|A@q4 z`xxEsI%U9A_IyJ8ru`Zwe4|KAAK6q4!3Z_jn`3FRlp6?cKxUJ?n#VaLH$YS+;~z{4 z2(;1&LClEOqtG<{m;tgm!g_cXz9$NG z7*RC`BgmYgTwNz4039Uv5=xI#Wn$*N)k6`S2-{aQ6G5Sw7~=!6M4_o`s;~)(bMi)B zOA;pEX}3URxeEGi{QA%5C>D&2vEfjcOmuspBxge?)YZI$LPT?qRWU(Bb5Kdb25k9y zSCCvvQV||Ap{BVhENo$gCcT-cIt&?bC(YR;@M*wYBjc;8bMq)r07=PQREa>=nlQ)p zB5PkGCw5H57-{r9)sTTm_J$bfg_uNnD-x>NzAh?R3`yFU4Q2#-;x{Y6lv+!%wY_l`g?G<9uJatt7DNggC6a&=4YJr`3G|#7>iyX;e52Bg zA2Se0V#L;_}ObEWw-lB|x zYsUJN*%!cr6mP`_zCb?J+-cK4o)-Qa|G$C4?|M2>8zP|+#4;fv2x|{7LLzcP=uJm<_Kyx}geccd` zQIkEX88;}##4hX;2p7>nEnc~)(e*z*Q{`3`#M6X~)}v$?YEyn0=Ze0RkBS4CrE9YZRpio0||19w{15y~)Oc5ZMr8noKs{gOdrSfW!L~ z&D&F6osol=%_J`~Il%}8C$}kq^m{B63j0!?ovefbVn!&E3Y%bcqexcWQ_eP3Z1xnN z<{d*N2*skWEyRPXdWB^9Kz|}%n;WQ``svH#?<(GiF}9m>1WeRjOsF|I7vn{VB1RHn z8n>{AFZ}N1PWsA$z#3d3ZlquoQ7~*R^-*z(f-92W>#ba&%bF`4*$YrcyJ8WmRBP=< zOnLt)9NZ!uoH=qUJk{q~q?L0qCAg$i0zQ~*ZzG&GeMo4UG4yJOZ;b9!S*ji>UEWQE z?po`S4~03%6?6t`kt3(Z>SdCt7&d@f;G9bm9=9=i!h>NQ$T%xQ5I0??^^GQvA>|8 z0>P$(F^%5PhF_`JOOtZNFMi;E@4TNfDN=LQqV+7&P@IE=*W}ldCTLst4EOW^p$eRl zQ_w^*ssAlBIUzKNFo42;zkNr#CQE3;&^ah_WeBibJRpc5^`GRQgqnla-D zs{tIRC42VGg>~qD3OA?IosT}2|LzicOEDW$j30w0eS-N%D%TsE>US;tY zFz3WR{cqI6D8`bHIRY0mn?<@Ls1l+~i6OS?LF8badvrPpAJHkUPM{F*|K1$6epX*BIm77L+zY-DRH7xg^jE5M3k)El6sQN$K1xsFB(`Z~JrcPU z0Umh4)q|4++NOj3(WVXAuHN1EDe$A$hxaopzW(jg4b!4OU3dV5W}q54X)Yq0xdPuH zkWie}XV#6I(xVUl(SOhLI_aJ2$Fkm= zqJePof55VoY!?CAs0q@E8yk{!1zu9K4}Tu{JTBe5JhXqOv>1le8k%w!5n(N+C{bW>GEAY(n^KyO@bm4t zNA1#yqGQa-2>nyh2MreJ;h0$m3~y3O`D5~L_3J3OO;rmdNxkPZstA}qbE0Wj5dL;WR(zWZG1RB>@4OB~tPl&T?AAe-(*8Oc9I zr|Y?Ab@~7IZ{U7FoDdKL00RIsLj*7YKyPIqlpp}gkA4pB-O%meFk2RsTO_O7ic1?1 z;O=fW_l^N%NaBs(NBs9dpk@GQYQT&L09OHW0SyQM^e0!33CM&ExPXho*&Mw7*hlpD|v>~31Ms4h7E&msNkE89~P`2 z77-ORNjfKmO`dr){01_WRPky!fxwx>(xed`RQDjs}VPcg>f9kXeUiNZ z>-t!ZL8PSZv)v6BxYeUGruDrV?K_ouBUlkO7?{J}_t$#KuFdZBQtYDT)EQTM>ehbj z#0@NPi(aCuSd7jJ9ZF6Dy(Wy1xmB8TrmN4^#;LzP%YUBTynQZ?XGf65x>2mVEGTMC zR%4}CPj}f_Sxdc79v-tmhyD3XPUp5cBfL`d`qd%#>uNrPEXZB5kyDhkq{KE6Nsw}`RK|ZgS6V#<&z9pgLu^G7d)$Y8rni|DyWOrk zBc-y|gY)R<_Bkq|jivT6?E}3fvIOo8ALF75+)%w-HtLjm^g2~W^sG<9rSo9Bii&SQ zNWHt8TbDibBj-Kg?57XWlT!SropST%eevgXul@e8XP`A7l{H1H`xZF{=Y($T2I_@q zcBSegXLje6k1p!D#T)&}6W#3IIZnm8&lS5zNt$TR%QWvUn;zQ&XgrMN1ZP$Edv3vsY+?7^4=B2C25Q1~9 zTxGI7=nl6e+x>IOC=Nd^6WgF;*liXz4;zW}qZZb>OW3-e!&}!@Tg%(@=|}s<+o(Jh zM}0TinBEv0V`a-WWeP;(o90`VaYqfw0#WGh-}3bDI<$+;-Ivfp*Ci@D189;cjpQ24qc>sa0T-l|Q}E6(@8eUyr$ z{hvb~SNqDIZCK1&0N)`7|0e`=V4&bOTJ;V5OiuX+4sn3+`R@Z@yoUu942Lq@?Lut z^*83E-qQ8yURP@Fpa|$y-Mx8#T*#^R_9^LZt&NZ=krobqM-a!`x>yLQ;-h-oD%N!# z%uRDD);9SuASnuCg@kW4o7)4~wu3vB>xQ@fOcq5s-gfyBH;;|cwd|90r<9&mHEUcS zpIM_C**j9_U(D%#Arwo$MR@2LHF2SN3W0~@IHM)g^t6VmY@E5YZEp*m*3M^Z%Ozla& z(|b<$FAd6W*akPfOgFF|@tNDLd#JGI+kkOdB3}#dbyL?*t9oz>W=w?nX643uPS1M} zFv7O8OExuh^bFip&Ms=140($vNrmkA(UzM8N8DmI+#U4J+`cWYifMHW?vq(C!nY+( zl34hv@j z_E-v@6(kIIzt*-6^<~K&+4Q!stE(YgZp{LWIUdiy52!%ZG$!{NtYX=e>bc+U#_d=q z6)-!k*Hx7at_Qu-mwV?~n+~3Lu4((v;J?j2fIk1SpB!~Iuj;qDCpko3iU8?SAgk_J z@EqoheD~k}9HV@R@YkhO!P-{03`l=E*H98ziPc5afRf!B+9wN^Rr=078GkOcRx>W? zbQ)t=@7K=Nq{w0e>|2QdLM+u6sUGp|N@s0KVcKHK`%P&Qs5kpK6&oFD})x55%A_TROdtr5rjj!zTjwV`{{`Poaq6sgTT_JnM z;@FRtS-0OxiRUYrA)P#S#zU=bJLw*i3TbR>cZ9f+J@`BTTfXIcEN(zsj6PJ^XmQ zug8cee8c=}*Gn-6w<_mef<~?;XQ96uu;jZ~8ZUO2aN@p;X|BN@FzfZIz;B4hi|OUL z`Mf!vth>|oOE0s|Cxxzbw_Z4SHwGSq<1OFvQiD*eECL`aBBtn&Q_{lhjmQ6 zwsI%gPHD^DlKk1BNuA_VJuRvOyT~QZrj3>GZEnR{8?Uy#xcof~#m)7?b%mIzmiUoA z)x&Mz+wSs2H5|MG$8^sawRd;se_>R_agCU-`ZCLlsO!+#&JDBgBv|3@IA$5qz7WS? zp0`>%l;Q$S+uV8oR!w>T>u(O%E4=z!zc(+ahRHE3-?932=yGk}2-*{ru*uDX4G7@2 zGCX2jmDb_syxG3S^EiC0-0X~Qu2*LHez3;W(U0x#pr$Q&G&1}$dzsSjD^-j z;k6xe#~gRaLet~@zTHbaSC8eVQ>XYTB*x>^-j;k6yg#=3Cv^@n@FoeoD~#b+8@X^3$W$89z){rs6S&incW ztGJd2R&i|{^1m-vSl;?7{I7w@?ZjU=23J@v0ejWWKRV;9`<4Y(xNQgVdzraM^|T7x zZ+=biBNh3es`N(&grOu+!L%)~l3k?0)ZNANZd5tglv8*+k*LUH7Hv-e>I)q@ro9QeLd-M1u|VjKHA42Lh) z*8Hoj7MCfh$-|RIVPS`y^cusTufmBGHPMyGuE%P0)lU6(R$op#H$N{zFQ~Dw4P&Vu zcy_snFGV|Je%w6I_U|ErA17DzkNS z^0|4X9zJ83@cPg7!ws&uyL< zE`v>$j(jn;&f8ro){1@$(_)28_Qg$(gB(Bc&2Ll9jvB+ObIxfiU%flVA_cb}iiR-o z17Sb1!?4sm%9qA>LaXcK5za~AC)1u zk(em8-^H`(C;RR}zFvp0q_0}oHJ&uGy54>^@gX144Yw#b64rHv;V__HjXRomLyY0F z`rq!ExVhL6)1GS=>e994pJ}{J?^GP6NA{|38c4UvnXslQ{C%mpQ0bd2#SSmw)aK^P z;`jAfnnd^?-j_t_AqK;C@*xfnudt1$83Xw|%96WhY~z)~W4S zP&C$xpT|0NX$gjV!796U_j%mHiQ9l?yFVidtK3g!tQp7kX5SirukM1slzJU(Def}w zraISLHS^qY=;%X{Jz}&+-hH?7$zobJ{?z)=?!Zwnu{l_Xck6Bb^nLtI>B8|r*9F+UqH}~ZVTaUJ5dhCI^n}%<DcpPW^gK0`xTW)jBEaADo zLiQ*ppOKr$$>q(wdQ;ywGcQ9DJ7(5=p&Ea$G$N%|FSD;FTxAmvQ2XD)G)+C_U<#zhYVJzmsQs9I|v* z9X4Z7W0zaLfA?fRrIc<1tkJ*&zow2OC~ws7vklc9j#a8>L=lQj_bDr-t0Vmaj{M0j0vSGEO#lzj0?5J|fu|cM?Ab%pT6$w-O6Y7Ev3^o6F1Q z%9;9q*;6;4k>bI7|NhlWixPB8#Xi0}`!3_V9y5&{~VdDoY_JPUFc%?2+A73d5t5jaah!`f}{C>^ZKEv zG1@I&22=IqlRArn_wkC%wtWH7HKV*UL#B0Zu^LaO zu^AZ|-+wRlnO_RHjqK8uh3n!Mc8#nmswp%YC+RSBkN`fks}a zbfb%!J`IP-Cu-g!KacLZI;(E6#GAoj%XoQNGAi!T==l2yM8G^S2W)Q*op<mE{yZX9yllmpIF_ol(xNADgGWaJ-+;OJ?AKb@9aA`=BppK1t2V?feC(?kE{Cib^sh-aRo_^d9$Kk!RGs9oW zoNw*bp+xk`Iqitc(li>1dy3(_2Qy>V8S{7Jp4O!<*AW%p-1Dx@ss8F+CN{ro?R_6f zmg{&2v-vWXtN0X(XW)ML={4ZDoI8ESMuScR_{(~t~n;Xt2 z&$rWU;wUgbeCKnbvyi;Ptyd$3_pIbrPPavoGt0=#%FxKd@->7D1{d~C(01#A zNKw&O8>&Z(ZFd`5pq3}n^$*lnlxrtComEI27pWj5NZi*L-@=Zwh&{7DUMGh?F9SdI zhdDC3nIj&|+mYFN^2FvbTh?1n#e+@}zz&3rXgjCCLbI(|dEDIZjEq;Q|HANoGGk?y zU|q3jG_9!0pg=tihW&BqnEMkgA6AJ?vq&H#%1}D=m@z2&O!h|eU9W|Ame(st@2R@Y zsA$XzD$p41W)>1ul&$M&P2%U;IK>2_sz@P#f>$| z*0x9_8%E_PVlfKH$X2=|x?#aV3h%RD~ zDJB)7w-n%lfM~QfWX+v>@bmqgXdyI0VB1!pig|M3JzOe8Uv0jm9JHye)3B~i z!$9_ITLgj@Un+#1`!nOsQG+*+Ab}Ypv1>3*99DCv2&MGZq_ zyZL?!^<89Qrum|gj8x77-IAWkt~(Pw|I9}I@fHPR5&+G`7%ocNQ4b#7iHPpj)mg5e z9KTmcBSqs+!roMSOQaD*5w2N;j3_9(uIasASovfP4FHGUjJasCkf2ZLHH~m}r{IB6 znM_U|qg0Q;2`CGVJxe3Nn|Eio%J3T8d_@wJLnNN#&!qG<4(KSG;iOm^n^(90=pMt< z;OXmx22Kd+8|}6FN0pufYX6a2@Qx0f{w~!0G5dW=ungMD#m-Cjj0xz zQ`97Mzy>L1qck^Uqfc7Kt<$?MH=~kCVmT)eYbi7^fQ@Dv`?QbY_tAb1%G+eNMr1wh zl!oAZO1j>X3|A-J;P(4`COL2B%%hFqAnO=eRQAU(M0m12YEXOSQn6EfZ7BaJjQ z(HF413!70CZ%(j@Ex#P^tS!v0VF|pWtBy(~MF=5k&dsYcb9}jaI@;@za_hO*Ukr85 zX*rI}t>TQAz5L`eCoNh=fJi3`suvmxyJs?5sVPeN-@So8ewSxAN{Y$bYMe%A#u*Uk zLg;hb$wWw7m26DCPNd6_qUlIQNgPJMK}<#ZC#fyn0mp%xL zln5t_DN3D&w;N-YT=WCt=1Gu|QwXYE=?UkFH7Z*l??ndCPy(NnVok{fjI@&Q`lHdc zKDSEU477<5CPf&GL@7{`ju1!{so=t?GT~LQqm)GE?@#yKYqP!vX-E<=hG;dVwuWcD zj!h*9aMZa0i>L*Z#S+F~qW~Ad9%y)k>-utLhPlZAX9yy%$w`@-(>+eOhxR1^vennkB1R}EgGjo!F(d>{wQ`P2F|^)rn{G^IgwfwS5t@y3OH$~N zD25w0iK=$rDJD}p-D;)+ zd~2nihRK*>$b66D-hC-WgL=(VQFdu=H;dPvh6t2MOn=oe_Nj(58x2v%gBY2?FF&FS!7e%905Po2VGx zf|WDs*iMyP9mwdmT9^tMip)`xDN%xX6C+#IcR2P!W`q;4SiO+8BtGer1gW+g7mQ#n z_TjS)I+Uges1lCKYw$)#AjZVDNJb%hrH+PjXf76XP)J`By3kcm0{kcgG8#dim0TUG z$rNlzsl=2#Dd!r>p;07iM9QAWzGiwoWuhcKX@ugosRU!yV+2CNNLz>6Zs0nb!vA1< z>(K;tgG)lZX&Mmh#D^CwcR7HM0bFwzK^C@6=7g(ABqiNEY=-Mpj(pORg4{UHG%Q#o zbx?w|h`H#mRO;{z930(7nnq^8+;6BpF4{^M8exJ(hHJZDPO(6uYLj%281Gf|ON! zy{*hB4o6o;P(p7yD$xuXQe6acK#QmwY7yByv}Mf8H}T{mZ?vP*&&4PQuFcKGospAX z>WSB?xSYe}UW!x^E~6=BMOr}KP)HNR&3&X+-|Sm5Q^t@6P{tJoDd-z?E2!jElg>yh ztTNaQIXfx3X1Ed)!qJ0udcpRVqWo;^ zP3^WxjLVyE$4q})C<@dqCYzIv)|Z0RLbz*dZDHJWD^lCp6&}~_@f1%lQc~clZ9$IQ zlz6xltwp1)MM|UxW7SQUvcjVk(O?BC_0tnhJ}6o#soTZ^1S|z?1rzMCzZ4SD(^-_0 z!D$29(!AFPl@1j8NN$m|{-_*{*rlXP=u>mnE&>o1N5v9BocFC)mg_bF~-_aj>}T zDGki@(-A!uj$L`2w!XYdFL49*bm@~ldc$cu{@GQX5E2Rk2S92HQX!Lr1)q$^CAYA< z=r%h?KP!sVpo|mXDGu6Gl;%WO3r-SLVqkPq*}l^Bi`eM)89o{b5I~%54$T*g^x#{G ze09$|SJa(z=^gKS<#S@7-U^VhiMC0X8pH|*p^B=KYBxpggrOJFSWKF8b_>n{>+usZyX4QUE5?w!R$DcYi+GskJ^58>J}$1n6X}A@(Q@ zD&(XY=1FG3bcD|$@lFS=0A1;KNc>R$7BToA?(~G9#1+ADy`ezev*~IOi;?t5kYi& zkyYw${k3-eat|@sPXh)`!5~$mQ{{$I7?m_Y8=3)DD(j27^XL@4{#s*Y56K1C4}#F( z?{-+E4%9twNYY zailb|{z2VmTP;b`bIMH=ndxIe5W4wU8K*yh5E_-BV2UHLoFr2+&;p8A+C?+jJYH#- z4T=%0p@0RhL7yx{2hku!xeDx6NoDV~Q>sZCblf>MHo2ZX84h1cJ%_c}W5L)> ze*+2w8ETTa1xtk=R6l9b=jOYk&qEX)J*j#T`15PP_mH%rn>Rt~DXB%I&Fg6Jy+}D6 zkdij!$}?oqD^-ILRe8@QDV?`CCFjsUHb9-cCPbHY2I$At@mnk;~lyH9J-!y67`@#n?a#eaMa=|f^FQJhROV%n%Z zk=nT+!O3AZ%WyU+Q&S)q*-wL@MQKHdFW8ylpf;b6MFgSpCZRE6qns)~Vd;xjg~K*US0e;aV~k1!Qw7zF-R4_^vKkFq$TlY;e(B8tzNW{1t#15= zW-EvOlYPY3FZPe=!{PM!%l>>}pmY@SV2NY}Z>f?tNHgJrL^kIAl7FTSL5I z5^n}n5w{p^(DE^qWuPiov{?8(3XN-y1vz=f5iRGVk2`66OeC48@(e1nU@b{0Nn7#F zNqU@O(9xpZoR4V?lU1AH1G@+_Qx}VB2`?_ZnL_21ctj%yt8n@QN>k~dF#u=~5CZ@N z05U`bFaS_qRj;aI0qV-Xt9iF?&bktyv>XrutddIR4HR_lUsbjmjO79MJpcU=Eg1kA zsxYGh07L*SAO-}$$GBR=OSo^vO>V%Oa3JK6FOPtWgqVcv+0Aoz2of5r&;I}kAE2>` zbftn3@}5gd2P)VBY`AG@h7hx{p$!2tm>Qc}3Q&>=&ypZ<0>BIa0L%y+%@qK(pN=z- z#tWJ5x7+`h_VpIqB5YltO@s=DBvE-o;$G`Zvei>r*mf<&FozS`c0^VR2@rXSl;a}_ zp&5aXM!KkPpMUkb>g`*ved*NybNs?TKUpi4 z|E_)D&%XEfI^bje>|>u{r(O4c@7M1Ad3R|0^Y^6Jw|ndM{)dK8&E8-A8~-DZs6v@# ze*Fq_FYdEH_3f`jxZM~?XwFn~DwmcH*oy-8Ih2XVuRANdG9xdUHqC&p(PZcm(P*L>w`4MHwXOv&1Z;R!SE?-PD9lp$edlIn zWoYybh^ftt=??tJ#&?*sjND2Zr20^hs~A!`G#MF8RH>PJ`+j9&oH9IHNbv8R^}780No@ZiC0(LsgZLOuPw|g@6VOTd*TbjWepXt`uNjc{=iVA*K;x z3Zh+cXsxr+;vjUTiqt^U%w%#Z!Fj-x`hA`x}q-#wW{&n`!ec43*RaA}HFn(j52*t*;s?tFJVy@a)dByO*@Z*UZ(4nqm@UuG%AWO8*6cI+|GWm9*x zd8U<7y|)Eiq&a50zfNReYC<>d(JKf&(h>Fm*v!vlgPV!KNF9`g? z+4hV=y{*2{hqhV3-xAxWZAVE(>a_kj_XLgu3iC!s&C=KY?y!2S>yix7elHNGO=S$( zy}S7NeNn%zd53AY&Ub#6blbzq2-7m_|Am0D7e>&Zn&yM$7e;HEfY=6F&PlY1p z_LsCP_am$Q2|fJ{jf?#Vi~VBV_FuHHHzbVx2z~zTX4Z0q`2Wz+-;LJTckhphUBXn6 zdLY}S8dYPb7eDMl3RXL-yZ=IOe?f5lM`-`AUCspw*Zzc7{c?WysQi5nnE%i7sK3wU zsM*?5R2`&?^~=5sdle&Bnwc3xIyk6u`$+qN2Iz=LWgcj<+X zj9Z1H#$2AN{`7^xy{<v+-HD0;d^dx z93{KfYq=h){`?MSmT;({$6Z!UYx=D!zg3DxR<?oD*<2evBu3P@q}|5@7Q}Ak-dTp(2E|;jJl!LM5}%Oh>NwR zz{HrAUS7Tzopezvt@N%OOMg3uP~4){fZ&CZZmsPw!O57dAH3DEcU+1wZJ}o8MZo%-WPe#H$AC8@qYP* ze;YB}IW+%# z-?>&cM|Php<-Jl6bD_Oqgt1Z3%SRvEz`H;aY^!N~X^dXFMo-0@uwFwhxvml!<5%$Q z-qm(LPW0OGqo8Jm=4I38g+QRMf5^3iE6;Gcu$2{lPPT2LTX)(@OcWW;(|D=oCiJqU zEZ|za&1N=SD#Y#>F_8;Va|RX zRBywq1^`$O$=p$&#xsFK%&(&S_=5X75s908!vyc=`11xvy2m}G3)Q|O!u+vUO{~2D z2*jM=1ar%c$WDhM;drE0Q>Du|*&0w*+zKMpQQW>LP2;;g^x1!Y{kmp%+}M&Knf9S% z+(Z%PfxY%TA;6!ECN5RUhNt+jSx_~IuZ;lm+yIV9`n}Y$9>IsxG=x!63Koi(Y^7U3 zLL0c38G(jlj^vUc)a}2nlX2%&=_LlI2^tEW=2jA+vBSsO{(Ss(-<%JFg=0gq8cncF z&D74gBUV%L`}U@@FJ_wj zCB6k*>PqLDkbJ*NR||<%-^)=(^Wf=7pzo9`uUSXMoYWh(<-l@p)as8ai@BP48?2ls~JlE4hX!%2RR(zX(zF7Rx}0~FYQ zf@jxrTl+Av{WwNTS7>yct8L)DX%Bd-VOd?hng3?(bLjbb?HuxQ^K-TBbFpnQy$|TU zQ+~c0^)z_VU^31y_-LCsf^vEaaI|YB^ zH6eNBamqwq+lnFlIQd{Q(=3(XjcrA(=Bcl3{OA3)2WKY1fHLZo!ZT#r@o0v#eYXU5 z!h@vAEbJ8FEq!`_&Npd~zlN{a*xpU?eI#NxRN*r4LfcEFjn5{~T z!Emqx&nU)*mnRhm8ISEUr%i8OtoZ}F+YkIvP03OW6u}|m6ReEcTJdJh#oA&VEB<(A z`k_OEb8d_0R%^P|b{;(6njJwk7$U?``L4PXg8{vUpkQ0REe~|`HJez$K0DJCbA)8O zDyP2_jw~;aJ13(<;mSoj575qCu3T$A%fb*~t3Mx3;KNw!;lKm*Ir;*Awb_#$+R@qj z%{YR=tAI7iv9Vq#7=pxvW}nry8ewfNND$%c$FE%)7{?Z9E|lvZ_y~66qLa|+&j~Zc z+_`hy$}eZ>>V14nUp}}#uiO#Bf?3oxk=1KbcyaEW1# z4|dx=G2=}ez!L-=-R2ONyZ59Gg1L8tB^xLy&9>*ly>=%VzEb%XuNBozvodD)>9ckF zxTYs(w#rr7@)jyETS zaJGP}Z$tcuY9cfXv zcZ(As8@2~aj-58alC7X!16Mqh$F6GUQGR4niWA4XSRdm5JkjBE0^^nc;{(k2LacsvabOURz@~^qUk|V(?-ZNN^|}wmf1Yk!Gd8E49*UPVy~O)k92x!lhCBTo{;w!714jIi0j|&TUKY{*C$gyoe6^EG+qxu5>PT9f7mIhO72QI;G>{oSUBqL7N5#5QRGuo0K#yL z*M3_mj*DY`!wE@_^Yd@GUo#bX>$F*ciDK*<#1@QC%Bb>)!(zsa_SKu6v{l!#ynB{7 zfKuF8cOd)W@V6s>r5}Ba42Ej$%fMT(F3m8^+g1GGCtyf~`X2)gkpw^o{;taU58a2p|z|3r%F* zdlSN<_`_W0g5C9BP4+(+jfbfHY72Tn%2wR@9GhV3czOZV(?6i&73*6WD~Im+4;5XJ z*mxZy`n9DkY&>q~-YA2#|F&%mR~Q?IQ24+PuDlgvzY>hs<#(`H>>n&^tl84Iy*^OJ zWcb>CpA^XoH_TT-MGRvQ3OK@uL&!87mEfST&=dQ}9=cA(J6GA*PSkOskt=Q((XfVP zqx?FJsH;JaYxdC*L!E|VIBmtM$Tr9_^h+`fo%L?ypK)DZ1lUoh)L*;U!T7Hf30M0Ubyj#Zyz}zki+H# za5NK+RmGbCqr`hI@sL=p(ih@b$Voo(ZOJdhqqF^Fx$959Xe3LIOo!=GSyo}YyJLf8 zpCUy=^I%p@N&NBk7aOaX@_WgLiNpse=4&s6Dvb#>KF3@v4MZ9Aev;~4V1{1{#*L+$tXEw14yV`N!kGM*RJ2-3Ns|iKe4b(z$l*{(ZQ-#BlMB zOF%aJ#yej&BIWt~B(NA<4Ua5J*h;gVqjL6%I&}XYy;J?1;c#&7;K&9PKWBfXa**?T zf){txu#Okw_!oWnYRS%mUtcb#!mg}->IGri2lpGb{*vzes`Q5^a^6f7D)kv}(fN7R z?r!=!PJNV~PPo-Y^nx_8WZpP2lZAQgyQEFk9JKO?qF0>(RY!vVSDxGnWJ_?Vi!r*N zb+^uTv-q;%0$!VH%wqm(WfWI0CJ?Ep0NSh3FbI_(Z=y6iqNX%qhOAfCAPi(w8SV-x zRDgw41fm!TuB`+s>jA!bOl--Pv#xkLO7?(ZOTtmbOf+er+E94Xu%S}5X@#A&tGv@| zNWuT!Up}&$3O&Cka!f=CK)K{amt%^S-4gfPiDJ?^V<4kRkX$hYf)Oj zH6=~3R7_UdjG!YIYmDbu^W@}j>m11{tEmN(s|BfuGBO@~Fvaf;igS#$9^R-hsG?4U zl2gW#l9M-OipjAl2y@_q=-BDlaAq)O$MF4lapWLra7`>L)M;zd#nv2(1eB%L4@OA| z)5eN+p52Vb0hEx|F)2(^>?^OPP@_P>3{5pO^T_!v7(3H|_ub#Jy8TQ{71Y(yv8@nf z$(B?L7xvv!#W|r$>`5E^hM2zi$TA-9pSSwIjMZ~y<9h@qx7eCIw58YJBqmHtmbYhF zQ=0qn`>ZnZ+!S*r6=WM9S%DCuq}3pvqh=*);ShNU=Joa$sfu*akvqP%`?cai$NJ{C zuc?D$DZmf;;p#VMJ4>0Bu*~G~ia#yz)c$2ZTKtMZtBsxGaF5zCSdlX!u@<7{WK*u= zWlY5#xrdo~Qi$~zlH8*|_!;VQ23<FB(Ij-PmFCQlT3i~7FGm3upbi4eAk-Aol9I*82n}E|n&E*&Mu>fk z&n)dxSVbvj)N-6}*P5oZ<75LhXl&+R)1Jw<-FeHDu_r@|+6|()a!#n@Etm*u04Wh1 zsmrrOng9(HrHV=>oG&8MI@e&*h(JFp=gq(KD4e{i{*OuxrHCYjQ6^(CFW|#&2k5|x zKj()koMwF&;!g7gn3R<9N+PWW4qKy>fH6cNLAu>FsBWf^(i71{&M65~DnZHwdNFn^ zL3))hWW;%N|D5q%_6x9{AY{}=nxK4Ymfn&CDBlNkChF6XAazAUMDI+2P-`dwtO}m2 zRiqp?=|Fi58QQxXvlqRSe9&7{!UbGP1kSSMgU*p$5MdcIPD?KiYA0jRss$+xh#<*H z5}aaFT0lTbO{R%<*||M6k(-mB!0DRmvJBu;1Lo#rfy|RkiVc@rlPG5&Yeh~zJfIWN zP=kcvjKR4%ix071mD?#|k-EXvkgR&+)8sTkfE0n7j4%mE2TiddAbtI&gE_BBeE+q4 z2Nw+tgG7-wV8LY&jvx~KT091n5|mIdUIS6n#H@-C z+DP^s3~Fy@v{iTN=O7M6PHp7%>dZ6tFVXP@IS)@TDS)O!PG;HdY{h;G3fS6lx`` znI#jco}8?uhal%55FaWJH$k`t!F+PaXAelsk z6$b!Di}3*+6-?Cvj3F+avsap~FIa&EXrjbv^OlTDg+bH!VTBu7oU~gc$O;G`$p|?T z2(_Vv7#9+LNS(W6#X%b=+a>`7Yp}PFRJ5GrlwKALF+00O#z{(|PQlJ`Hbo`Ofo3Sh zxS7RkG}K?3bz^lk=~rt%^ypcNax#la5rJouI0@9EGfI|w=)}$2o%D6U5rs6VXS_7TW4fim^7GQz`@qhnmO9X=uU4 zIMPy!i=rwH;ev}TA$7eO1Cte!q%vhyI`q39c>O)?$Yx%fBr8C{7-28Hf{a>EvEX!5 z|6w%LXSN8LP_ZVGn@+(V5Q3ErO|D5KovL$amugY&P7-`j1Xz;CM1c|_l8m*M`bdd# zwN|QkTeh%WP1F!%##@kjih?3x#8jIKZ}vcIFST8h3m7mNLP_AbqJ$YQ=L)1C-Bq}z zP(!GgAi^zClUpP(?HWsQ2$)40+AWbQAY+5GL?!};YEX)AU9zH)y#R5W)9y80SP+n@ zq?1`}CKQk1&uTOm^of_=>NZ1bl1ek!2(&G6rurWQBqY@u+*#fu>Tsq|aXU~Kfp%NjQP9#MTDV3>iQd2i2 zDbhLr*6Rj&o;GT&8PVXx)X+kJUKh-P1dG6o||k`&+=6N*F` z(h!SIyx1xq!_DE*ajH#C0(&vOs9xGgthC{xY?Pxjf3KwU4}MtGldwd^Ch%5Bt;Iwz zNy?IWCoP0=no|~ijOUu|6(x7BcW@r-l6z0&#lJiH& zxHZPstIb&qPf-p z4l0zIgSRA>LoA~ob-l18Ae@kwF~a>v{3n4{jYJC;i&d|qGk+mz(d?!SSquxULVA!6 z2F;XD0)ddo<2n7JVkZG(lW8Ryh%gUIB`8VA&^UX8U-T3`a;<_Xks?ht)ar$>)_gLB z7->80cMDxJ{A!zX z>&$Y0eqCCJlRie64}(mWv&os9MGaBKrcF85xZu(#rg1*(Cz(M>$7M(c+0>q>T;Swj zoHVeqPewWc^VRKT`}CO|{&mNRQ?6*Jn>UwGT#|+`NUaW%f(^wc>_y;%)w;IxI=_-s zRL=o+)Ji4BsE0AZg-wj_OV#EOzxDX46v71;dMO~Hm~(_7YEElKiwIK9hB1$gqvP}c z9sI0b&cFYhuXD#PR=Ja2isPuT1ffWa!%(6pK`gJKITVR0mG)nw@Au*K<^A&oML-q9 z5F3k!*cjxJfzVxxtZ5tTGr{iMw~y*CQ@{qby;ngbp(s-_Yc;V4X(-c8R#GaH`q9%* z47ya4`5@d#HI|Qhk+0MsNr*5jnSMIC?}_^L>hdP-h@cI2>;w@gTI4?Bpd{898wuAz3LK*l)Df&HTOzNV5o?_-^FG4^m(o}#4JqZOt zhAOdlJGn;Ek#2A)%7TM&D#>Zmy8=Q;?N&P*P1FyCjf7Fk5jNmzPavFCGPe>$}hwiD?U_2|Fn^UqlEu2?R7z zr!1$b|97f0IKTD2!L&!p4frdAx*@!F+tf%b%9dt7t|Q&(xYy4u1ZY?c2-gC&gro5% zY9J9?P)q$?5H}Kxu83y1Otv^M zJM4oL*B@g|Z|^xgj^oINZAutIuEb#u z4>H_)FMjDPab(A58#=~B=ODx!)l@1$O)Gs-5UG>_bObxci!10vGS*@P zAi!BTyI5NzIv3Eodx~mr_9%Us-Ygd_xlfg~wFQ*ODr8M3lF%jJ4J9rlrC`i4F=4S` zl#sdRmYoJc7NKOLPtu|Yq6aZR&zC1Fqc@+C&rShjc5vmI5r~aN%uE}`yPuYA6zn^VN(mG% zYDwWlePi>3e(Teq3mamMJ=C&KXosqyq!&5g6CvHZdLsZJ5D)_Z0{}Ba13&;!Z)6^n zK>*61*(AMBEBpa64`jsR_G;ISwwneu3Zpmgy@yP$KmVW>Q6%7$l0GL1l2rl5v zZj%|I;gyMJ@VxK7y@j{%8Ker|!t3z5=dRut9Lh#PMvIWM7)*y-ZlrgqN zmgs`pUEgg{CBE!iP2|LFZezQJVPSqL;S>M>F#wtw062v!q|ER!X%Tv}-C2IWt?dG| z*%mQp@FejK4+uz%36>dY^CKI6mJqR3?T+`_W=%lT0R$QG27Uj2aQ}$!uf6fL;k%dW z{r7XP?TNJWym(i>KP%6R&}7zvlaMYu|qHBj4;oTmN1A!%zOw>JrHp z{nRh5hk|$F_)DZipY9)Op=*nq?ch3Rc#t`o zs{G_z+-IKox8364C*1TD$H>yTAOn^nZ^bW-^<5Jtq+KRvpJeTiIr7dOEdHhWY(=s1 zX;e`{$2lu%M|(T}Fhf$aK|9|zCj^5&Q3z?dUhs_{y3-Dn$I zI*`pY$E+$MkDD}a<3d#DmfkwKsvOX3=j8L~BWdoJKU34-)=EyAL6g=kDyOP;JbkH{ zZnMIjqjleT8+V{}wt%ouf&dsuI6r zfWrrDPaV4M{hnP`{`@4^557Ztv!Uj;S!e{e2~`dY;CBKfOka4+Qbx;otgTFyfAG93 zo?_modh)CAs5F|_R0VIxD(zE=4tLkXce?5y`}E(3O$HP&R;oJ0rh)^5-H8fwDsxk+ zb%|-5gV`?QQlGr@<8IF#@#wB;I-A%XAf#pRK{Q)(Oq%?u?1jL%WnxcVCyH0S(Ya{& z;(edA1n4sbETVRx>=oj=fsnC{!!>DEte%hm2Wnv#FZ_c4@sBXgoNTI~v<99kpqhF1 z0rwlG$#gWX+NpzQ^X)k_(tCl@a(i0u>xhMvW>~^BA*zzFYPy*s(BaMJ`=|Tamz=Ug z?j6rACh-|}sG;8{=58GnsCNIY8UW>_K|1ThOa|8C0-s|CIh1Mf%K zu`>TzE@%9eQ_8??KP0slrn-^BV+oGgxg7gq>K%yD@!OB zLS@sG8evE426i;Hy7+Ef$Df#{SK&agh8zdVUEirS(Ut33$aR`F+s?Oqi~k&Z-2-#y zJTyCvCO>lp75S(1mC4RpU$Ij6i{CO!SZFPIQbXDjoJ1yD-@&m{a_l4!N1 z@fa$7Xte5Bzyuj(dz~teh<&@IP3kp#4$@)2wo?lEH#uE>W7<1g=qPdL*yj|c0d+zI z7Ta_{r?ClW_mYMgM??s^*ZETA(mqyH`)#K%isEh^L2_A_F~S&OU;_2!$fz{_74)en zYb4L0vxZsKrMKe-7G(wV!msF{2hzaRI7wdLmH>Ft?O{tD>_UVu2qscrJbD;rCu+s7 zw%Q_67^W)}6l}N8=>k5PuQ8v>2U3SpWQ1M@DsnKlzsdY;Yycp$C`f#;ir}RYBiuW0*D<(Hyj&-}wJe3UA65G9g3`i>0Zk5IjHnhnVwLrm?>&tvkC#m7F^bIlI5ADkG z3Nc)sU-3Mv3#Nr%us)^c-Qh5x(823DxO^MCffqVesi{y*q`u+xWIk`WBG_(r(xw;v z8HR?HQ(uv)F9lfE zzSCr%X^xn@m0!C)MgUP7sJCJD4b8n?*!9!LN*#Fd2lK5j*gXCp+Axi3*Z6RvXTF-I z;h5`5h?T)y@N1r@zzJRSA{E9;J6-*2d**``DxYL%2xd}WUwniOG;32(QFz(_{8R=? zssSoO2i#v(Je3<`)h#krZrd3NEv|gky>t1nq?HHLtuH`5`+XNYdq~ZybG8*uIwmLJ zP-ThgS}-a6KKoLu4i%F{txN1+d11C}q?<^;?$t|*PwD}wQn&R^58$xjSgLm2Pblwx z#0rQ%QEe)}e|QojBs(}bv!*JxwolFCYkI(`_u2ND>9vS@N`6tW6DFZ5V1+9GO z13~Zo)->{704Q^E|~z^yS^|WJD6qW9J!uzdp0?C-@)#%Ws|A}T$cRK zcRgN!y}wQ7sJfzzech{Qsq^qTmh!m)KK$NmCXEY$8#bAtOmV3z48}Gr3+YS!OZKsiX;Vbmm zwH#mJ?;JIyyu6AWChT^p(vWv{x;rkVpOR2!R9HiHx$7I!h3&fi%?re`5Nl}jeG=lj>?VVkWoif zG~7iN!$bWdg7gD3!IDAcJh1V9Wo;ydLencdp)zoh@$e0?1INIQ%Jf-GtYpIRjwEMS zFT`f9Bv0}1Tw{FT&aX&sZz5+iFMG8OEQqnVewQ{cFcfEI`89oeOg708<{iPRKHAXH#jd|A_g{wI zdSOGcyZB6r$rR@`w{1IrFQt}OV9g_lff5FGvu24ZzNmRBc^TQ|&L4_yvnIAGww%ov zE9UC9>#)2VTs^&s)CNd`O5J8)@P4aOUa{18Q-;(tK*z)T$#du(MWydwugR~c#l^Drhc#rvSdKs2*vg+L68Uwx+ z)3Ws8giSF~%~vZXP2?czpZE{n3-MM2u$6YDwH(rU#J5ED#rGsnt9SdD-Ooh=8qQ;q*ccsdvG@ReL7lDfj8M)|s{E8r>%E}%Z z$~@N1RYs-~^a<-zFs~wCVsBkpEN|@Pi}h=|z{<=yHQy8254JL$)1-0)dq=4-V;;AS zFT&kA`AXTe8!cZ8k5UQXnS#A0ZLAn1Jt6#P%|r&7-Y0Nm{5^BwwJG#LR!@A zQ@Rev>T$YGVWaHQiPzppMiJgb+2A25hmmTRoX8;anG!_putU z#YS6o(&Yk7;g~i@nU&uu_+Fxnt8j}Kcnyiol2~%bzJ<1e$Rf<0S8~*A<83%Si&s0q z!s#Ef>3mwzg*%6UZm*|1-<5A_XSf+&dGTzPay>Ms=@2nT>%-72OUwfml%{OM>a$F^$C-ds?;KdYf6iIBEzzo;!2s4bW)NXyV-9t_? z;uW~_?=|fPJYLhfXZdfI(Pd916UD?QLuh=43|>llW+Pa+7{bg3k-}#dCPS38dYr)j zA8Sm8bza~hSazk{vzIw;5wjz9A=Fvw6~RooaH|)qQmjP(9NuMQg2vs)L8`F9j(w=d zpKih;rbVon4w>+{Go7W24-Y4)N&Qf4xa61$Tt&Vtio1aXX;~wp!0liV5VK79v;Br z-DC1*EE}(Ij~91X`V@jPRM?Y(LvgPwS0vvmc9oD@Il?}}elNW&0jo@X6*G0rSg!U1 zrEFSxN14KS8J>DEw8FnuHww~Q^~?twz^cVey8~T)3QHUD;kGYU3SrFzxv_xJaU(Z# zM(s%~AHB;48SaJqyqNS1l_?W}0G4I;5B{O_x9?crwM4^9FFrOcW-!j%9w-%-BI+#q zo#hJkL9pZLV#ve07q9xCpLF15w|#x*WP^{^WvQ~+dc1d?oQziC6E7y})a_XFI0@$T z(K(Y?7+d#oN}Ri4jPK{lm<*e}h$x)IlcIX72zF&9?NGCNFARYi1M}fUFILHBnPt2t zE@r#O25jo_q{oXT54G`?*cx8pATM96*fwDxsIT^)Amt13C&ue4;D)lgsr+i{N#QTn zGsdn(smF}ol02jAQQRIjU}E*a%4;)GuLYjMRj+9b zRXSdX5xU{u>e+UbmBH{yrUzdLc~Toc`YBlWZQuuQvK{?#8V9|K9Tkvo6A{X9T%WO< zFcfWvwDX=NUPHlHBE!(becEHhjZ# zq*v1T7P?9{o5j8v`Jc7MxzZPkp469;>j1uOJ=Cgy8y&o~R@blU@7Ulyec^ZR!wgA1 z72NjYUmzyzVvg6i{w|=g#dqTL!oT-o1`Bk5*8EL2Ic%eJ*r~Q)Bh1XJ$!%S1@Kb1{ zeiTpy=zo#r)V1IbB=UURIl7p~!==y|#H#yIiUbe*zBGKig;=J&8*vN^wK0n6Cb{7d zBa89qW6ojs-R1^k;N?>Pju6q-L{sd=5sVfC#W|yuaq!l%IRvf>+L{$ z!=4fuO(Gc?V#k&iv6XP!&{4t01H`r`6jN%lOA$!Gm|W5dvG!!klB5MvgFwKiKl1MB zi87$j7;uq}nEA&T0|fXK=N`x=D)W}UMj6y92#iC^b=II6#I=diN#f@EELw{Wy|vk-`d zV0t*XY|bfG*ki$@jA(|G?5OJqw3@G4Qn}YVxbW(<{k!DCaPIa!>&dd^>l{%92|koZ zVoctWVFpZ=D2oz;qc=#UyXAHR=D_=c7;B%hFd&-dereYkD_h@KY`4MPy^~?1=?jP=p$T%IJd&Dc*C_)`?b|IdQ%m zb1(M+F?Y|;vu)WDodXn76-YG`OO4A2m14ODciL(Osd1EvkuNeKP!mAG2P_VgYNGpA z<45gt`L(XxA9tHSzBCkOHBq4~2V|%7K)8X$gOv+Dp*5UZpI3SmBSZlW(QO z2LF$B=*4Z_cx;=#-K6(VF`Os^Cgx@-T$Gt-d2&o4Ok)iP{xQ(t|M;{E{k_u6ZBxMK zhLV>(aghw%5NwrVuE8#g__iY-m_6Cc%$skikTX~>ph&>wLJz65Mew!ksu{um=cFb4 z*~z%a!{6D-k=Ds$$LNUJIiXX%2VoKt7GQbfF(+ z+@_$we1qz@B@ntFuKPM^X*$k2p=Y+@Odz_~cLXGkXx=$Fnm+ z?OWPg9!wvy$s<%M2%N8Ti9&iIQ~mz^)t`%RH9g+u9ddcK+`9Ip|BD^y%fJvaV&Mzi zTZ$D0@XQDhGm&w@?@h3DRp)bIP0|o@IQTLY1dBM#HN0?}HFV!k=TKGn{@>9hCt_Sf z#+N1~ZLJw4Q&DP}MGT#s><&mPtdXF_OzHEUBfyFXXD-2bSWcg6*q?@esgy@|(ak69 z|5XKMw}2I!%i8HWod2-Gl6-n7c+N$fNMcD8AY{p9ZaV*amnPs#=+V1&nYnHDwVpyT zjL=pTMBpLlJgJye%rHHQi+k+=M|0GRH~G6VIC~LclmD}?5vtb-{znL%>ma2EVN8)B zIe1MH^wgOO>urq(S^vhWd|m3ForuC_i#M2IKQv17d?=RnitmTTCc1q4Htpyvq*)?^ zYE1}Wn}Wm!*ADMOT7Tcu%_d_LN-eMf7HYhvN+N?6CxNpziIk@eI=L@hT_!rY#mhhk zUN~GUVpN!e5qb_}pyN}<46Rk;TL#l&2+1)NX8>Nqg6B|>(Qm4mQEYWtuRrf#cXb^6 zmm)s;`<2f<|BMzX?nx?4+i$IPP(PjaKyij#${1Kmg2pQs?XkHN=C;)V|J;Axap!ro z+!_A-7guQT{-#+q6q3)VOlmCW08+T96dUZcC_(h1PQPjBDyEQni)WUa@+c5%S_;vg zrhpeH-D#Ru@<=5xH7nu@)cdlCgeSLTT5I1w=;rQHdH0KXT}!zKlQ6f=&6yu!Rdb^p2XFMw z(Oc0MOdz%pQAdkwci@G&C#aEV<}rJF3?qpa z>p3HV39SesEil${MTEJDzu&zDi4kk-72(&Yd!?Du>MITye0w=Q?Q4XH;%2c_Q`BMadPer7ERWzUe{a?x4@{ycm zgLD87UMWzHsFJu$O(eDlr#j2w^TW?0qCf~p@|mmE51Sw^*5?Ybb7Oo*9{N{fA8rIc5dUz zsHo~C3z0{j!D~{^cIDoQQLWL*6TvPco>RHz^MX_~WD-!KoI9V8)(QfvpID4jw=>pGJ|=0}uF3AUXDLy&c(q>^#H7}JUrWbZ9m$x(34A`?RD z;g(_4>_t#ISWASAE)X0sXjvt9C7BbP1`%X2u9k@63O=GUb52JAIkc@gWa0!}I*}03 z#4?~BIJhD4*m}tpwTgXhS!K4R6baNIPQK7nCeiE01r}Tknbf1&qmyS8m|>8S1IKV= zNdXUC4{M48h151O^@qk(Q1mg=Cvb@oaEwX3(pH_4G9WBk?mYZ4KJnlzO>T1Qs_k6Y z#r$FF6d$sui&7;?!1ehM-8_s|A`&a(f^af-geBm1`Zmr4w?AwNj$I^^PB+ z!XoI)@I!j>$uXGA{TKE*ZPCZX(Mek&7aYu(gOr#-_|jFOq9BBR`kiAjinf#-C- zwNB_`nfrC2i(8Jx6A~y%Tx&C64x}|2kE~SyzOC792Bvas4$V1oh0?H5STvseOBu_?XAvHLSl{t7~r%?flFni>_Kgerw=CCE^SYzv#WxR zx;T3|_=^-GPhIx+80i!n9T7<}5z4_i!^8(Y6hwZcdS~j=-NheG;EQDFq~q4Fz|hK` z4(mXr_YiRiYM29TC`8*5%c=5=iRu$q!gpooaKsPDA^!A zSTNik2FGviUFVZq&1TveXrkAiB=tb2g6t8*0~F=}q>_b3H`3}S761xwn_! z{5^hczvr(#r~Q^&7>dnAY5)aUi7h#{%Y?0l&FbV9^SEunP3=b z(PoOWDNor6d%2e%^X;1X$^B+B?Ta)~YEL_ogka>MS+J)$5Je0=f&z<0ieKIP%59U} zXd2bBL=&m@j52);y$D-p*#?o)vC_Ga$$HBj*ZB5kT)b`3CaUd;p;C-t#M43R@xc`{ zk^nNCtvF*q-)Z~y+@BtkwrCU8_C%1W$(>(AVKtI1k(GKI;Es_(ZNOugQ>jn^)k zM72H9R;mQ>8kl_TPK;x6c&sQT5L7E=f5~nejZ0ZHiE4YI$yAX_rjTTL6tF2@MI3dG z3e?tuSgrgxw~uGs&%4IZ^F6uqIluePq;@cxM72H9L8@b9T9o)8*$dNp;wd(jgHi!l zySe6-(DA7HqSc;gCe_Fn9*77f3awFM<$5x@C>UDEH+TGT=+mMJRLc`hq}nG|h=d~z zr4&)G=s?O*c`@#&n|s-~H&tvexpDj%$=#+hEsQi#YftUl000mW0{{R3GDHM508n34 zttx2(mEZqU%s%c)gwhfqB%DqvKLCpYxie(k9IHqKZae$8QvCoBL<2@d0AK(GBgg}B zlKpo>*~E3>UHHIr@apHfmVuH%47^l=yUS!nOO>h4cM^rz*?+qP7O1bl;Mpi+WH#9n z8gd%sBioRhZms567~GQFGFK+<3K59$0077V9gP8?_o2;dov8Uuw%yUzb!l#6@0LL3 z3RElF_;xpIuLRI%MKx(XOVxlNftLC%%Gi?hAt>j(Bi853{r~IZUj4aq_3rFE;ribC zM}8eN^UUx3zgF#`PY=zXbLexkD|1e9B5oG*H_Oony5c{{k(+{ z7n7fxqM`ll4;|&v`smM`>8S|0TL4m6X?1+2R9;FX1jm;Ql3O1T~=mdvhaO4a&}{@Y%Jee^k45h>O1oBc|UyievJN`=LPy` z@BH>~_1S&23=I$K?x>%4)jM@)*NZK$A9@U}0PXtb&!hA88hYms*LC~O{yZkR)0OA{ zCG6&3->2T6zn8)u_)wR-4}HDwO+KpFAf3ph2xGFE8U={T)#^~ZCD^01nTd&;VvA$s zS9^yOvqvHmyKJAHygDc#vZbmF-43#{!Gxb3zij`(D#Od$DsOg zw4TmBW=e76^0DW-^vH{CnUBDU*T_Cb8Dqp0Hu6m=5e5j!6{Qzv@DclC96}On8trm; zvhjCmV=5F0^29Ya7U%Ugld?JyC}|5q%}QNq$OM!=xH4S1BN}276shvWbvFM=qUNa% z+4?k4Bg@lU11%t>P>Qa^hQ2Y;icEQ8HXOpD;A&P2swSX&YTdDXtH5YC3WQObw8Kz# zOza|6o|sWaSuF$|9)z>8AuUw`*x5Jcd#-4rC&sTIJ;_utVu~4g7T;6@7xI?Cfr>aN zTA01k%^iL*?4;IuynIG`>Ba0(i)m9N$P>`WoOr96wy<~sAq4xY!kN`PeRE(XPta|W zO|tPO*_b!BZQHhOJK5N_ZEIsEH|EB+ZR6$leeb=$=ice+syfr%HB;w^xy?B-nWosW z;68bw7$Tsg-vTRGMTi~zLl_C^#Zz`r1;8Wr=Zq4uOe(MUKCafU8wSHET=tc;A4(Se zlGEsCtWVt23!rB4^zP&=IPQ)MVN6>@ZhPx+AqsbM6sdT)o+~4&R3N0RDWF3>M zDsKy9*dBQf8#Wyd$y6_G9p^!`z-enuBIY*%7-`}F@VaHtAQdQ|-E4n$$?T2>+W#_w z^VYJUhElB$5-yY-)hk#9&zedx*LAt+a==9gwXtL*p3E(ss5;(O#Msv*8ig{gWggwX zi}FR&dwIe;+uF_+`Ilj=+C&OUJ3Vg;-?(6((ymwq~4kj=SWbUr4!-x6)6 ztOD_7#U~~vqN>QpiVIRv=mO?`FgdgEJ@nz}I4@lYPW9{#%Pi8JS<=>7JP{1>5zZcl z(l`;D=<&lD&8qMbsLt}+V(OWZ3g(efAzutV5m6q7XL#vrqV`JjJ1>n!Ws5UzmE_?= zsPIw$YC6&BzNyT?|BHh0KDKaKhwe}KrGK(rVKydzv!@~#z0$uu@bWyvItpAGJk@;8l=c@TT5ca+P}AthsCqscxZMy%^QEw~6EwqHDUllwkFx87Z11 zcosHPT)E@ZHM1J^uVFq{P(-G<8QfyMKKmFqOA|p9xd2;5;CYLz?})o5K(TT{-IAGi;RBT!FXHFXr*u13!&zAR#DYG+z~6H zgR_N-$sp=nM;+n#JtLoez_shQlA{0tr;}(OZ*+bPTEjbql%#{s+nxH|^E+ z475%@B;3=D4_!3JgUn8qPBu<@2x_~f&bDgdBws|^AhZt9Z?G4ej?F|5C(k=;*H6Wn z^AFub>|u+ou9|L{0;c}UKA+ylIu=i#2$zVPA{HApmdZ_IZfF^VT5t1qUZQ)1KiyW< z*3W!18t~uN!E7E{_EcsIZJQwZFXjbpC0*~nt~9QQOm5Sy%a0n`Vh8P)y-a7j)<(3N z)#k=K;j7T?*o^#Q=Jrc38lE;i0@=<5o>oeuX%gM=v5lZupYL06%HbQi6`izYyDrdZ zD=)8u|TLXc|P2Jgi zqVG)uhT^N^K#&kR`6W+Ifn7 zk&+QbfI9NQ4c7Mee5H0sc5r(#JkA=R;*hK*F}bSD55Griad}K%5V$Kz5jjK*E&91y zoOcLyAgy@L<+huy6$oV%oefSZx@F^^PS`iQ9G)oxjeo|9v$LYKbiMbV zuPMl5cJm`7dFR3`UX*BXr=2n62jWc&U1Y-&p8qYNnIzoZ-E5w8cSX=(QpzuByij&? zJN>NwpmxX@Y(lxY7o@{#x7m^_?z$!?_4cC7)ppp8)EYC=K5SiWUmH;U)fUhJv-J`p zA91Q<_F3zhw%sDqfi^q4xi)=32J*vp7dmdbapDd1atrA;{88Dp8IKiNi3C^AmjDlh z^LDCFxBOI}L-5M=g7@j7gRt5NWAjq@BI{XUlbhyKWtsPVCgcHsh2ulcRVFbM)}{2> zd;p@6mLhxFGrG;(mrDzR^XuV*!1ax^UsA!E^fy*}!`vFw`K${vp8w`lq&)Noo0+Q% zK23*K*Mu>BZZ7a$vAYRb?ejtJk$j27Zi|Pth6QX&OB=hkyL&C4>n?IUthuaN6Nr!) zR~hriy+Aoz_t=L)(X$OR6sz-n?R-IG3o1{x>uO_mt8Uihpl~Os-S0+%>*v8-)A@Qf zW2CLhWTw$;#A@DF5RhBBzB1tUGDL-bZG8?Fhixr^)*QXA8huN+& z3KjgTF*?OIsVA~Bk@4y}p}^Mr)%~d1{8-f+hI1Y_FLtsMX0=0{HNfDhNyQ-g#A9C?p7}c4 zs_l6SXpP|38%?D7fjP)a@*(B<7yrk;>y6PJ{(6d`Sy6R`Bk#8wtnSA@@v!|86xYbb zCJ3lU&I~pauCRZ)UcMGvO)CZApY?AxGJ?&2sch$&)D5ZC@iTqT=~@OqvkT8pG{*P; zVEdk*qt{3f;Xd@a+t^F>oq=t~KDH^)k{{8o?cu2qy*<^fcLA)SJl}le8@oEgd+TcfM$k+-!h@leVik0#FFc?=xZ$ z>oJr?C4Sa(-^cFQWIXd4z%*6mSwI+|^SHQY36p zqo;&tB=JLoz2Hga!~~`y2_>pP!)xX)eXh!fFjVqJqwF6fmX;FY_$s&DJ)?vtP9&3m>Cb*2B%w&#wft$wM+_7gFi3`yi>|5gTY zfx*9#0EG6+gaIIs_)*j_p5@{WW@(G=3bD0ZZbh7j`YUYZCm4a^1U=q)Q0TiP~@wny3BdqE5rzucF0+E&6&WaTE{M%8l=^PmP5pIvmnaF>w`7Kp)XTNujfQ9K zu|2(hoEWZ1 zo_l*dEi^bbFSsf#{L<_kO+lbO&uV8uRsodLZ(?!BrRZWxNxBziBoZwdayqc&Ir6&-!7j_wHf+K`Qf@Gw!#n4e5mU5Fb7!DdGr#TX2^NuF*uGc8&?|&2@Kkz{kR8wkCaqQwmuL zajM%rmLPk50a;rMe*}3xT$JB4RGd-^3>#nb2U=j~CdGE%)%jDvy1s1;$c{!L^! zK$=GJ_xnFIhpLRc9x1~e5oH*=kD2w(lx`w5I_xP!wxt5vx7NWNww)qUJ8P6bg9lmN z!idkR46NW@sj6e-go?)T!_-I)?h-QVIkUpArI?$*8gEt7BQZ8%RHl-VRI(IZJfSA% zL_ethI(?%XBorR-W3ag;bgF~IKNqlaq4@W+%dP#3??YATDrl}_`Lxo;L~?*Aia6xt z1Q2jQQo~{uDb^q$>Xpogre+wg`FjT#&CM}^L4d)mmMz_+X|Q#r1p!yZ>@&%5U-aLe z+J0X?Jp8+a8X0lAatu7r>vIcU%q} zB5bwLzk(F223F6Kk^<}K6NYZD+8DpsWM%$4x%Awg?u7RI<-~Od#3=W+n}E^+xrhdZ z&`1Yy7-@o}eg=mz&}KHFm_P-3i`C7i>#)T_el^*+$E;wmd(3T872rpoE>+2l+f*n!(hur^K+J%N1E-0Jh8R7 zzX||}f6n8L0QeQq!1V>_keL-mlC<5(*2C?ZNqy{dBGI;9ezibGu&bK`qv$h`33CGe zjZxlhorqoEndEr1n~F=xze~_@l|mqqlIRi>LOqAY1ad>u*cvtKbZze6?K&7BZvh>R zQOfwWDY;e9H3-TC3?0)F;e1{`)XZSjziOF&D~kEz8b1))Va`Z$QaU0K`cu_6tQM9V z1-R3Nw#QPjY0V-pjfGlr@ItXoh*8N!-br@C3(9-Kxam*m2qi=A3TA*sFQapx%%^pU z#Bej<#f%}M7!t-m5*jukoq=ZuSb~AmB}#io1`bw5_NI-AL~t{hM;8P*-2}PhM8-W^ zT#UpNBgJdU!t{3bL`M7%-q1uY;;Vj#PtL8!=T8_2sQMi;w{KqYcx0kS)&M6c8ur62 zZTFK9k^&UwF$iG|siZ)c15HS_$O_IFULvSH4YypS1D*g942V+B`bN^UT`8PMMYF&5 za?|*wCcw*cR!T%s{p8QU1>e5(pUE9(18CIol&=!3J}DbfJWf5K|L5e15D+&|q$sT8`o=y<;|E)1H zF@pm@K=hQoDU~6V|GXWYKHjMN6XFqTgN%Zab6@HyjjlGRAN!nteL_)yf)EyTP=SG% zfUsSMo2x&r$gK3=_j~Q=vZL1oRt4MjyCschwmYYiFpZCoK0HY(U%f?8SwFKjpgf9^ z&O%m0Hjl8*zprB$kuaFUocG%}YBdZxK>D-Ak$`}tgECe%~9DE7bFB2!}nW6TYMos>tV$tA3#daGm9I~~=x?9%A{&br5+%|hos z^SeVQritvysp$_cv4h#I&yzfu3RNSD5NRiJC3~JQsx}p(qA%SGqMGk2=KbY*Ywpyu zfzZdyj_sjm`Tawt+VE*+vK<0#X}RxAy6oaqn`{F*=82(Q##|)9f+LGtU0$I&Kt# z&y#$^F{f#0mldVLlVpmzFak&TcVBiP;XpO+aOc(mvyCHd1w%Cl5|2y|j!alP$On0p za>+_~soF>}>x{-)$qCw|7^^kHa^f>_7tCYd-Dm=3vApy|Sf!mBW!wH@%hRW;_m)9& z*a2UehKiGnv9a-1i#8%LjIF(GB*#rzTiHrAF|t^^()&*tYb$;Eg5NFCLEynowvrZE z(>i&V{Kuq@Sc%MZm3+P`#Y{+n%eSt=?*8tU@(zb{SmO3r1?l5ec*|C)M`G9!x!&ubT(ALQ)b! zVUZ?wQjP~1Y-~!#hd39rvn%qFT!@-~@#6>6d|rC_zy4|0wonDhwBs&G4Kl03MshFZM2)>7EIjOpp69;c&Q*4Z)zUA8ihc=oZtDM2DtM&D=A?Hp zm4VyoP%uhTyXZt16Vb`)Zn1o}C^ai zC=Q#dIpe5gZfb`Ydv=?5CtayqYdSmTIA~+(VpQ->TB>(=JsF#VmK)goi>m?nZFf@& z7WajH<8GCv)+cIwFV5S2;nQ|)_qW4W4Z(W-3@9lX5qcF)`f6DvxFDhJcYGJ4Y_no+ zZmQN)@9=O<4M1Dzcwkw}r!b3Qxh#(!qtYKM@S+WNLd`ACp2Imy-*qY%_;PDS%YOk7eknRt?oQfEqM3Nt5M%aH2y+XW$-AfEAX-xubi6`^!`^pk+3=5tW zd}UdIJ2bGCee*+y1u64CweTPRtar7({ax(LSUzbuy*~k8Y>BH;4+@#pe zk?!ctphlQa55%~-PREzazwCt`c2s*9?tXXW(u=z;jCT+Qyeu|+@2%Pc&Ys&NB-8hDsp z^Tq$FP4|UGvu5G>hx*8%d}%vSg5F%vU-fSjl4wRITrQJ|kL>r$WlsiO?1AnQkGx<3 zF23OMr&Gaugd93|i7-YgLu$XnCoNFRYl79K9eTr+A1WNxw{zCsq0*k&^+{{Rj;`-H zrF=DI)IhO5`;^@_xpW6fo2s<cRef+Sg@+JML@!0X9 z=O)vWQNB3%Nbrw^q_1b(iZGFJoQr_?26?5;Yp47Cpu;U~H4{a4wR^qZY+33dn^vp- z(ElnhFgdg8>#OiR@vw4Aa4}j_z&OK^XCsU-+&v1#iqoaW`QT4 zCYN!(tvoK*o1C7at*eOW$mv=a1?~;yjVwog+dN*}z}*^Orpw zF5Pa5zx4X%+bH+BFS$X(XH0%Qny#VBwmFNO$FiIqA`E#`N9~ZQwI?EdX7@ z?|J)1OsZty<--%hwxs5*u-?ktJH{RfN5C0^&N-YsAh)G1nf>;51COwxc;K(8j>O$lGj+MNrt=jXu-yR_=JtK6f-iQ{iM(l zVH#yx8>)2W3chi89HHxTd3WXOj~|~!Pa>5b*dLo$9thTr>mKapN~RC@S4x`&t$iuO z!4vRXHsynMmwJY)RE{GMo#}dTl-5kvr_dRFhGRtbKhw4eG@9)mTpv-qBEFS%D#9Nw z-b{(mO=J068_)lCd&0h7&F`*}o{?YL8b!g;hPG7?%izB&&yP=NpRJ5qAaviMJgz3Z z+dEwyCiQdcOzmPql_qs6Eps3eBS$8;+jnk;Yh__TW9x(4zP9m21pV+!oUvaVXB813 zX6~$GgtjYPLg(^dm~H(zpT2!bpGEu&UvI%ne1>gSgSJ+01+XvS!#OWDnSb zX#v=k?7}t`=#+!-id0Lg5-!s`kg_hn)dkN0V*q9f*%blsUB6Xey3m6&4OX~}0&k)5 z3GC!VyV1_uq720l-9c64562anuII4V|5>J}!%H<)= zXbGBvF$w#4e-$Pl!gv73U@?EX3(148J@7pX*k&eSQ3~OC`RbVAMah~oiGal`5!HZ{mB00V1YR;kaH#Uqw!+n&--b${l zbeLTZG4kp4e&bK0nryRTeTMdsfe?RAYk&Vr6*SpB^X|7t|2SOqXD8+P`coujcioNqudDu{aq?{>~Y%Ru8I!q+$zkhPqJ>X=o)In1v3>cmx zDN6l435&vHfVu_DfW=%7N+gYvbc)5@q6DAGcoH%&tt>ant2KV|&k-{up_V@fB4Glq|)S2o38<}=DQZ8}+QP>btC}%Kz zi4w<-^%VX8kF4AaQLHK5c!2PF5g1>P=tN}jlu|fzX5p1F^KG{w#8U~D2I5L&C=_(k zeg51Dumpu6?#83_J9j$4qJZq9GQ34zMT3^t;0neRiWL9m3>u>WP+*kXsL+}vG{|Sg zupA-AX-V;l?dX_3Pdq-}zQ+9Dd6fjgtoK{OD4reCWmGD?gGU-d@>(?CeLmqv3eWAeIs0 zt~N)kBaydmSA9d{e~q4^80(DrAr4C3nTYr)=P-wFM}L)N=2=!$sdq$O}A$jt1bhlh+q)X2+kD2IVGm^$+82ELD|Kr!sWy-z% zYX^&4 z6gOJ7@(5%MBpk~a*v2?mieptS5y3&;5FA$?L4{;kLTfXq!mu5NY%&Uh_lDef#G;*! z=So4dyACH3BcZItE`v8hfZlL->lLpEhi&sCwO5{x9uGN z1J8rY&qo>(E{oh&JqP6Mkq(J_)$^0h=X$f7?x%o}I=V0DWqk_`k2!2l%*IwoVRZ>r zK`H^|4_xaSP0xE{i?O0n4DMh7>YSOFZ75K{A6nJIx>n~JM^e^$lEO^#1!F57z~7L+ zkAb~L*hom=O1;DUP==^Z-2W^P%gaXu(~}rvSBv?1A5|s7r!wgck zM57{tmzv_eSd$Vu*k34aKO%{$+X*?A1#4Ok9_f?#f8JOqB{Nux)U-3Qz26zetyH+j zjh5S@G3!V?lwO+~G@Bw#v3mr^h6Zk)WE&+1Dcj;gC#mbe>*`2Cgne0bm87hVMS4Te zb~0~IIS&y zDUTX|{iA(&E%$-@6JYe!Qekid;Z1N_9zo5cEtzdfT|K8*PqDALu*@0FfNiv5WJ06DzQ-bEjx13?4@ zNl*XL$Q0moCDE~IY-0hvXv;QzhjKDlL)8oQ@>eDfgf&PX9LU8$3l0Y!w2cK#XN_oM z^UdlXdMi1V<3kwqb!|UGc37ahDW}=jQ(3_NYQu&1@dU9|!B3IH)zxo5SS%fwL%20Sn))YN;q$u)ncbd-eE=WEX_gxf_d4uz zPYcuKhAH3dYU9=Khoi2RnuYa`oWd#p(9dmdPcBYuZ@X1>&{@pQ944=9F*anfdHtOi zGdGvXc5B}nuiL}rC09kQr^(4x#u^?XGqLwa@2Y2!DTyJi3ePoPXQ)gRe^H^o>{55S zOysHLrx9C%o94;~jfa0+rh7A#b?Io|sK>;sCOVwN3Y3K8+=aySa=7SHG?}kHSy=|qo+7<0yiPkL2*V&S_bm;bi&OG%>YGfQh{ezX zj>AmhelwS(C)f9XyfMG;v#&K6^^=RQC z7N)e}nlR>$UI*JVV#PDs|8M*OKn|6OX*q*l?UO77D&#V^kN{~)pn9~J>xnM$r+S<~ z41WUJ86?T90+46T{cm-~IEZkg6`ql@`HI@NcRWXs@R*dUIO~(w&X}3ifdy9f^kHEf z>)Vn)O z-VHDS&T)*iI1K^_24mg1Sb@miuw>FF!(wWV8eHlb^=v2r$x-fIz+NE@vRr+?JitKA5oY=q$#MCx_$Ox738VQ2&yWg=Ipex$h2mb8xHXvl+hb#B(5^8X{Sjfg~OST_q* zmsq2!nHq0ZX=vD0pRn0 z&0=Lrp6vZV%V{_xr-9RF^;sBy^1YW>t`4NgysfX7|ih|EaLJQg(J^UK` z;F)aRDl7ZG0}vp?CYc4jY_>=(f6mv{b-!E{``~pH=DT2~#pW0zj0DR#GKl=X3;^k8 z%pfi6->q*ZjoB?vQ^H_o;d*OUs3VF|_Y-jU2BDrP+q((jwl3`uND|dlR#SfR)@&4J zh1DHF!eTfRzNr(DLL&GxJ92}xWV%uB&iYXnz4%f#iL^vr1`zWc<2;czEbDM8Y5#VT|H z8E{@W*Au6*!0Of;)SJ3MZYiW?rXEfAal(nvtm2aJT_=}t zAe@&$k2J`Gu~Ih^k|6IOHn%RU)kXVaI1Ke6g^IU73FX1lav#vi3lN;szqxTdJXg*c zqZZNQ|I1e+ojYvnDwl@gAdF!Z{vv$OA4&V{i&}hvla`G@23X4xBy0LMl(rB~GjR29 zjlaRF+zz=E{IsU~^5~pwnZXfuWHIUuK&;a)Xo`W`iVU)1^x|T9Z>7h4vDYU2Y*{wa z0QE9J%yk2us0P1kMA4#V!lr%yRVJiHSuJxnrStsJLDVV|%CHZT18xb7)J#wdwoKz! zxw1;wMJbE**@C67@4RW49@=~y5scNWW4DW_c5g5T4;u)>=Pb+Wy{DCAts0S6`+wdr zimQ#4wW;=FX05g=ms)mWp{K}lF89fYLAp)`yNIZqo2tss1mebZICmQpQv z9d-`a_bRfvPr)2T9&XG*@N<0^R}m1^07Jb<`3ph07U`+eV~=zsf03RbpKw?qhuS}w z)!yVfW*?$@k9RMzOLVdYz`3kAg%>Qy2thsV)=m^8IwYRJRw1NsP#^ zgMlu}CvY*WkHU_2VY&!~OcHF6_zw?p0+oc6Wn_ZV{=368;h04a^ZG^K)6RcVcK=4) zAV69P;!b|Y0OkS;5s;l?WvMnCmyKMEr12jT)TgFWGV(AKXZIwL(qNexFpCq_%NnfAQX563ZvSiviskyzu#FkJN(mg%6BC#W;qvAYno=!V|4eywr?-MgNTWQHZy&G zVBx`)rw?htfNeLODScV8*P;Pj!wW%{+RHermbc7uWHL4bai++6@|L0H^!9R{aa%+~ zzg{G+*{Z`phVq~o5bGDiLA9eAO@XY;7bo;9-Mh4P@v(i6UR{U~-o^eU1OQO&X@eoD zV1y)y6J=2vFvRg&th0MQUE~s%{C5vJkKHilVnDD98el=w9-f60jsecL*(b7DCO*wu z$Ur>i4wCxsktRWN&Qa7RRYMR=25niI;gw|<#8Py7Y3t%Zf{(J$Wtz5feRv!e1xiLF zs4@?GhBhMh>sm8sB$LVeHEf%%bF##c|%Ci9<&|4hSakI{kiCSam^KqfP^e z!4CF^eAQ|M4)>xd#Xpq&0CWXnkuh`m*xKxefuk{RQh+I`N>(ibk|9AS3&w{3j&P+2 zdy3a8eFw=+}3p?qs5m#R-A>S>ZOQ~AI;jvzr% zGc$OgvnK6f$ZO^oVqXzO1fT$+Ov2bMSlt#_uk?@_sYk4!{@hc>hZp|tEyenY zqsea;wSZ#jggcNaK})lD_{fIl){=&uy122rYj>y|J?UJ*dh+})wD_eo_O|9S*ii0m zj!IhLak`6vanC%gkvh?0TbY9Ty8`2&J&>*p(=d9u7T>0G(bLvEy=%wQFH_qU@+aZq zpG83D+4DC;_gn=@H9r*84$PEk7&A}Z9_X*X>UAuOLBIukNAdSh0%cDe7($VsVW!~f zBj6x}0nIS&;C#5HGgtfBJo(cEChK8hEc=_IEXCoPNFc)+yYl^^#Qa>rj~F$q%xuAn ztc#DjZV^6W()D>EIME$b8%9;ezXB?}Qvt_AU?Xvxh~T1_6l^&oDhxEXf;puQp)XYZ zwf5T=^egnHJ0VjBayOH)WitJGI`2@yfb6gBUphCgzcQkwG1?0cE;c0>FJtE5shH<; z!@9lxmB+k>moFP}E0GiCr_tfgYwYdX^kN~*gxMdB!q_$KFIJJ)OJW0u!p;k!L!Yq5 zTW7@`+(PQ-MQ~y%zHYuzw?!-tigo=;Of(chgP~h}o)|kp3Kp0!O48M6*$CMrl zd}N+%L_5?zy}Q{wwa<@Vt_t05w#sTXy>w<@ZgP^i&W_Kv*cm+*|NYm*6?)xb&)Dng zmVK51@lpIRhr{AH)I>U0aQic+yt>|gz4?M*rqpKZ^77pkp6|Ku<15)l8n4*{$Aix&C|!WF0DU4E~T$UMnhkPC{6i73eM4HI7)ZZ^|vUtZ_^v>u*Dx_ zX;j+nXl8pxb8-v#j?X5y&fcFkV(5{heq^qM{&Iiedgb}uf_GRn_W9Y|=S7RYRml(| z3=PrzrEqxE;}odU=JAgGa^2GC_2bzgW3GqJSGhBT>)CG5%<=VWj-pv(%hK-stfI3q zQupi(2cQ=p@@TL&boR5l!2`$s^1$im4#RMbH@?9T(e>PQK}YTIF%FY==QW!`HT^_W zt?;-G)!o2)VD~}?@6;!yirQ7csjL2=)|=^Oq~&XRk4G|gqE5PQE3HJB@!J!CNy-s# z^zTjQgbLS|N~SnRZE!K8kZ;&Ta@J^1#?dZ5K+9{xKZ2-veszrnL$m0%vQ)ThCTjv( zW$?QP&N&C7a)%_xiM#nvNzVsjVE1TFw_X#O#HQ8bu?YqH;SHN^_}dN2LAD+~~uIePJH zR^RQ9Zs?@=SPyO|WVhlwLV6C@__`_&}zBj zHjeZs1iu8gWHHWvu9#)>I%8+GFDjR{mn6l05wgB~DLqri-eR&JyHtw(U=I;TPmJhV z-Tb*U!4SsH=wYCLrJs5}RNxbnh>84rw!eh% zv~45rtme1(} zibYSQVQOi~rrnb1&&@MvqdT(l#k1#+YJ|fB+zO97*cn5QclA8HlY4f+(E?ix%cpXW zHZLp?ov=51cD{|E()$753Ax?XjWC7PEv16X!0jYUILCzd1^viR%!JzK4o&rW@sjPU ziz{ZzTO!TV_r&Yr_Bh-T3F&NTt@dX=_XO>7mf^OAG+uc)U}SP1(nyFDL2t&YDbMV$ z?B~3Z27`T!jIq16-PU%Ra6}2(vwrySZJhtBa6&9G-94PQ{xCsD(N|!yx?0+AXx%PDW0NU>LFT|zSfFXYN ze*MlnbLyjsP;%@d;)K$w*TGxj>d;TJlwn(oe=}$O9qL?9%+IOJLg0Wx+((!`#ER8W!)tik>@@@pRJC z&A414)H&G4Lbd&F5~u|wh&Zxxo)bU(g7)6R*`A6FrS9^$n^xOzo*gN24fOGixY%3@ zCHoB84v~(vjjqGN)9j07C(`7n**XqvEBsaR+W<0y;adY)h z#4YRY5(Xw$S{g6JErx5)%*)M*>@{^@g261G{z!)RVi&%`t$Q-VxyiNloy&>Dky_(f zIAx3aEAi<0)be7JP^JgVyA~=lM^p$lbmVLvbut};364E^Gux=d-(VyBWNAWF76<=w z!_I}SSKix<6T4E}fIUEbdY-4mxw58?`=2jJH&D<_FFm6%)z!#{ z;5>hGsA(*qDVSxKx<$ML(mAp6Nd1_3a1)kDX0zqLlv#)kLw4wi1b(w|4!?-@CdS0w#=`_L~!Uy+({((%eK&h8v9*j!Uf zFOObOXIo*MdWe?;>`dXbGr!>FkI)-p zTe{53eUKXR8*raNpyz;Sfd#?gmIXQOHuZokI(+|^EXwJ|CZ?==WVI0)4c}ja{`ei@m$K69EF-1PE}C<$ zo_=@G@nqL^i$0NAcEt0*7*d3+%;aB&5OxRX3DAJ@>b51uSosM-M)9)1%O$$JkDazZwd2ITTJeAF+y;`m84dCr(R4{N!pAcTI51}XB zGqXrR7od{2*>6{GxB<~2bwFg`9y0NrP7uO;wpRy<`P1qu9r_;eQJ-Thx0#LiU_jAb zH>&2C!aj?I)gb%+%`S zp`K~#oL)$O0cXqpwqqg~PX;9n^P0!qBsEvx<+5^5(WFWye0Ntmwn=A7YL!(ytio}H zy#ElFTx!5tg~(%y*Dy#zT=3zFHI0RJPr9vGj!*%tQ{i9(XN@Wg?C<7RfZrDK{+rFk*&NwZB}_jAP9Hogs> zi*FG5O>k_aXmS^1oS$9N#8EwUso_WBJk|1{NvCid;rJ9YOghZ%`qU|{wWu;XnS-ih z%M9XMN4F%qdesa@DuENA(P3LDk9N<|F5+kPlzM+NbcyPn#-+JfC1Fj-59^LCNAtG0_qBXZZ%oSx_?$_%IWx2MwoRcI?*pS~^@;YY#v3)wlVy+$ z&}w_=an+PQ{d6XR>tI8n%b`dwJSBrj1Gw;)*~I55rH{k8gA%1Id*-j}=8ku?#akGQ zbEKF`KO#^VnOM)K%SRP#6@}w;?dasbAB>l~qseYq+V0?>of@cP>k2D96FZ~|Wd4w& z=%p~jFIV#=dtytH&%4V1MwTBYFn+;)O;Y~YnNX}hdm3-G_C6%^nCOgGTUk%hYw5$v zmfCz+c(U#khO8 zCS;w|L%k*Hao{KyWE0c_@a2oZczZzru}O~9`2#V7NIUVDtnP-j_=zr%99^U3Oz-@h zgB? zPgM@t<%piYfTLBz^x*d{llSNeZ3L2JeK_6WMrHi4$LwByarS`Dl; z*{smqNd7_6HqV<9L-k%)Ug5y@K3r|xF5Fdbkz8r{9E=^{M6q_fOgWmOjxmfF-}35z z44EA2E%EQZOSu~?wzYlEy-06Ycl!&P&xc>nD1)!H{ruBR%^kXAM3V|7r$XKlbrBcZgB#Y`{QeA^#H z&f=sWZ8z}xJWGn1FF?4-y#N8p?5aI={I2T(w-zmGAZrR}e|e#a`L z8ukxNDk(ugAWiB2SBZ7N!HJ)j&Zzhze-Ca_m{PdUF~%ocb%~^~f`kSGxfAA(tZNl= z)cbS}b#A2P`N!h2t?IPfcB($rTXyyvc1n!Cy6Z^Sl&>sz51OyimVum?sYRvZ{{kP# zMm|-E1hK*-@ES^xPB$`Dv~^nRJG^#2yie^^bEZPnAmFaHa|1vIOZ+_PPDefpPSH-y z=?y4YCo%fAuG@RlS&i}b=5*q$+kHowbr*Z2&ZQ<5ciT9**xGfpDOlYc$$n~k?#8j6 zIUr_(^km@2MPjG2#q6Ey{e`;h6@UHyT_rokHP>dwJ;v>vQmtWw?$y3wudT(Fg0Ww= ztogc{Nf1RRG$mm5Y1GwERa8XrSo5M)3D2T>mRaTtpbnpI^P&yNtn*y9-LeBML*{ss zoQrv=pVbgd%`xVeN%M-upz+RafcdyZUMpKLGsu8R+ZNf92mnXX;ca02lumJJyxrf^d zExm0PGl+e`<3v9`_3$%PAb9r0<@y?@oDKocgmEmG$$OTsBY|?r2Rwf9HX% z#Dgs?E6Uqg*<;F?IPZGND9A=Iwc1AecEoY_v;#>rR!j;;YfQf7v#;MrrC?*xqKTd>9VhbnP}fH!3?#>(9ntZ|~rqvVlVe8k?DE^CR$-$cCTE6E`S8pfX*ZLje-la9(dLKRXSRt_^;Fhkd9hIF#an-Et4z2vMOsP z%x-d5SR+%HTp>@sBCXA44D-S#97w480)v4ibpd$ zi9BVkg$5d#nFxr<*MXFLjfk1oD38e_F}t?(&8q9CX_!LYzuh@Xj&XETpfeWZx(h$% zZTnlFtNbu2cQT*1r%9fisjpF%g+Ap*;!c6;zuJG_UC(WxB^cKNzL9dr`tN&jJIig) zl&NX>o=e}TPnwi8UTO-j{$=QSUti$1Tue%!v4m4f2ys({(|af%(dlR;!XYK~c%dwr zKh1Y_Yh&g|UP@L7RB;vMPjBlzjz>#dCJbYACsox0!K^%l&ge_7dY>g5-MxHCE;PEj zv0~X{R+$yQc$52{^ZxxOLRu1YSl8_#($7q0MXrXMwU+&OE+DS(BJtTm6?#$YCLjY7 z{ee^Qz)N`z>nH2pzgzBB+^^o?ci)r*oL=$WT*bY2p%1?u=A+QpWz5aZ5%E5J=e40+ zkXk@eYwXmom;#B)zH`fIW!$(S?wWQ^^ajq}TaO=i56;KlO!Hjz+t#ZLn)@yXH!dl~ zlhHpIKJ^~&n^%$3Jp6Uk*S+tV;Xq@KsnJ-wuj$uaLhWk<{qp+UYJ8vGVs7TCG6bEX z7abN2v%*la@8`8N$AhYLJO=^ogCA%_uOJ6fcsZ&!sW-||XIc~AZb#E*4Czo4w%$rj z@ibj%9MEF%Bx0**^3t4wpHXk5G-wQKAL2rs%Ur$sy5BHzLO1PtD%SnpYlP0}EI=;- z|LytDpBW3zjJ?r+WYvh^b(+e);*mu4S+}3V7%Q7R;Hc%$?@u_Va+5 zBZJlXr;XZ1CT-W6kjDLK&;GW#IRdPllI;!18q181x#Yje!_qZ@Yxm&(8XrA4Wf4q3 zgVSix?XwZcOLxF6Loo^BaD!?B@E6_UDQLkT8CVE|xZ2Zjouw0*xsGY! za3$x&g;~?ZMao84(pBf@@U>ACPe1|9$QKmIz@I1v-myo2sm(ECzi)8?+PZj~unupc zvlu6?q%dW2C{ieqfw#L2qhkrsK%%hP)q9FO(cW!o>s;1eTf8v`&@``i;o6LP?ctxF z^}93cbMmzYi{?P87fdcM3(KOo{Ta85R1+x@plhmnr`vyBcccNF$D8 zVcOL@bqzc2win7^5*tN6P=<*__dcNe1l$;+wrr|Rk|;0l8Kkrx=Z*I6a*MUkTUeMW z-_)0W=L^M}%KQ*I)SNFUf`JH4_&S7qN?xzxY2veHS_B;tP{IRXpJm6>y?S?iDssZT z-lH7N6EmL4=CiDY2-e;S}g2A?96a$0BoR_FQ?z}p=|0)M$mbJO3 zw-N_CCcuIBs@OyK*!81wlxj^X>Yh@a!~L}qjfpkju)=2F9?!o|ET#~1-(Ow1Y1!T3 z*g0~NW2JEeDVaX?Ew{Cfzji`x+ZWp2NJIwvJeJ45pXye>#<#$-sr|1)A36d~>%*?< zs!#Ho6n&u6ul=wM!jYwFHy8Hu`E1gjK5ITxn)EVvPMiaAT68TndUk%Ioy(tPvyOKx zpLfJ_&tO!E_aJ-gV*$Ob&u5{Rv|JTAU_khGl^C8a1SfiHLq|`u^ zx7{7Vy~j?^cT;e4B}1OCEoni^fA98gwwEjsvq12+)?Pgy_B+zKjlAkSgZr1R^J^du zb0WytIL_&g2s)PNbDTf&2!b=PBawj-oU9y(4DPK9I`geQ{kLl&m~l6Nrt1EnscA)I zYv@1n$F!0lmS}6hByvR4QQfg_{U=?YBO8jh3h$>~MlqfIySYO8chH{c5wqBS9^~e! zn=HmGv%wXzrZd<4=~X~7zXVDDN$mrV`(+Z=z%|T?fTJ*usWDiguO*0vvt}?EBZq+n z`aI(ExY5mDBQGWko3NwAC=hEuI-juf5r#*@mP|N)KRw4(`wCXjXecRikzYNh3EI)- z%dwI~CMOI;G|`xr;fYLR2WY0!k7GJ>&fiv&V;Y=o1vmWXyW0*>iHIn?6=zucl-d3n zO}_|{!R4i1cUQ7GdZY2hfh-O8Jfg@qKrl5T+u~DgJswW%; z0`xwzWTLN7!`Z|#kQ^N9XqIDZBz@>;+i7C+xRF<1W4=h27zPRuM!Li@@cA(Yns!Q* zl{XCNHtlMm@-Jl=*tdDa0I|QE(=jo0lnm#;OF11A!^Z}2PQt`BxYcxpeBfWb$ok!C zc~;n;9DL+{)o~U)Gw|?1?&FDgVC7gq)^x2QI`{p=Fi`&%GMyL((qKnDF$_F>kLf>( zLSQd4WVtAZf$JVf6iY{kBIy`K?6C>&(@I7eE-=M1aHkm@6R{Tp%M3I-JrAEAfyF`a z4J9%lie%svO~6r-$a&-byhDv!Q?Ub2$+FU`f!x=fH{165lz!>MK;7bvBIy_@qK*S1 znuwF4>CPycj*ueh2o%#td*Vzv8u$%>nt84ZBnGK;u;uvjWWJI^*`UEwjz+OrX=Twn$yj`tJn*T?s(N}kEM`i@Ok)3%BlU0V0}y+d$= zt*-x-!$`G1ymAKMMRc7lBZx^e?v|(1tD6r+_#UaI(KxhvlgA!sIg&Qi3u0Wb#?c)8SrGj{)@?KSguFw zuK}v77PLm>Yskh$rw7fY&x+dC(^x)+MO~VB4J7ca-n!{`W3kb}WZJ1?%Y*!Jk6TyjK3Bqqk+tt?RkTK!=4zH<7B7bTW z$(+{JF^4@%(;0h8rVHrA>TOX)TCNu^mn7p<)W`zBntd_B-8EM1ah8YJQOUX&mVA$N77EWhHt9ihYMO(JMIZodqYAHZ;+cAPV@FV*xULwTy+G z)zt$GL@FWJcLHhNRo6cR)|B-|nU20FK>>Lz;oWxvU-bH>a$nS%F~GG7fCwd>ARhKp zla+>~UNgi^;D|g9fxrU-Na92iK(ZwE@HXn~Ca(N?|2A%sGC&4xHG3$vCBxSS0s%Cf zqXTHlM+`I=RvgJIxe7Mq-0@kIjS7Ha0GynW7zW6=3Ta&oX38aO!_%2i0n;wRq3SH( zsz?l(hD~Vx=^1} zhMc?^BKD5ZwH>^pqz^iu*?ia6$BnA3Rdj3l=k7C?_tSJl;#LgdrpbfWiLVc%S_tYL zi=6iTcgDpFOaKDUDJE(xuU#&{XjfGm7dDKo?V%u`*azV&q`KCPzcu$>&bb?DOY)9W5UbGKG~P%e?a1Ei$iz}DcB%*C*X zkacE9R)C1DAC4nOwjo-@U13&R#iX8XUePkV2Ws%Yn4|dj>9jB3?325m9N8OYB{qh- z3M}pj$p}$4Yvih}p;-q+#JB|ejsj0{+2ozM%<>MQW2^xBlve0OriK;qRh@D-^*J`f zC>kK~oa^GMaz^~JN~+4u=m>;t*oX^GT$rhY3yTAYV6w5<7sohHUkl6q&f$72?O4UB z?|?FC@B2k^?CjE%UrU{)@Ybz;^IQ9OUE{B(2S*t`;ma=D8I!vPZ zITxVRTD&(ey&_Jg?q|R0XX8%Q@?9mwe8^xBGPw)vqHQIN!%Q&g{Hyu6uT&7*f#9S3d7{E$l*g8-^;20t}Oe?FGriWX! z^kXx!v+dcs=SZ}y8kp!G&~|mE=SVe@cR9KIdleY~Yv#%=O(uU@&pC79@l&e%zHjc> zdv990nEt%z>5jd_#*g1w<>&PML_D{d($oM!Nls-p`y9x(!&1P0o6IbwgFBYB?uitK zs<4Lg4)9~|VBeA8{q~=vnCtdRLe|*d3DjncI!h?{2qY6ar@rnfv&*(l37(4@Y&*m4 z?PC^0EMVZe%#|;Tt7`%+zxlxV3m?Qk$>@Lj7h!!qm0G2Tc>!JgeT4S_l^?y1AJ~TB zgv&yaEtsH*PBf7K1|;5K>jo<=O)0*o(Q)Hrtlz#U(-p7>KJj#bthcsb*T5*?1CA*u zSjz#V4zIA29M$!as00YwcaJV-fI53^Qm?MYCut`#8Tg4Qux;|GC+(3J|m1z5L$uQeo(6n13p5G1i5Ws_fxtW;_3i^_rw^! zL+I#6yv`+N@`@OecjvlYH0iu>kUK^*?F|dPQ_-UhY`kL_lJX7=ba^KjEb@*cb;Gl- zO2Jb6kd7`?F=vb{d6JV9uHTA1WhK>|TL}1f%pBdJwmTIf$$Kmw-2nXpM0z4L=g@9I zM71Wc9Jfsfoe&{?M}D4whHp3%CUg{K`lg`}lzoTPg^QTzo#}iEA)$8xb&ere@~65a zdB?gtd4S6#?+MqK-icya07%q?tY=)(z%Aii<9UbqF-ydR|9uLBMB}h(O;pI&HS9Yt zGcS3l(1ryG;vDGuW+m@rB0~cJI!;xQ`qEa0MpPsnt0wgwQ1s*{6eM{aQRw8(C|L3x zQtISnN1dy%tRayUEdfx#O;cHwPTp~!}H09m@av9nR~sAtJLx-KGiiP^oy6R(5N&+1wh6>GGQVwcyOt#imG>J z^%W7`0fb8@RR4MrNsFT9ZlahHKpGzV00gH5h#XVsveOH(i6aQUDI&K!r8(>pu45{a zyvic#o!_?>0q{fnbYIW=D{>`S5@<5?n4Z?3@wIcL8!l~@_3(lVp z7p+~CnyuWaL&5RC!eBLQ?ORrgE z@P=G3o)c1480#|;C=&uRxS%mk>%3QK(mgz^sIeBKG6OWqOHhtP%UTPWv% zSOGNRp%Ea39v9HXLo7g-J52D@cO|;=P7-E$$A~U@2M{dsPC`h@I|%D}XTm$)A&E)7 zbDX7CL4n2*q=8TCJOG(3-I^?F5CWeLuOLu6){n{Mbd9swef)l!%TlWl`#WGb>^}WW z`8Zyu+!V;^0KRty8NMU%!=rZI8RJaeA^u8#S~mZs2jg375cQoVCI1#12Ct)yN%O)o zP1&3ckdsXyqBj!uNon^KksXVh_M{^30X=#PKMx^h?P0BOAj`1;4K01^O@|XNlHAfC zcfs)9)d8Ab+QxtUe*ZK?a4WsCZEHK`Y*WJ}UeCG9)55@cOUD=oGZ zccZ3Y&O1)o6+?J2eLVQTFF&yJKM?4^McQ{hY!j}1y$;gRyFIn|uj}2O=0L)}7yH*- z<|I4N5X?SF)M6y>w0to+GQ}hp(6p2Tl|!ZdE6pn4r`wy=zHgROm6^P;is|0Cf5>GW zP|W0nLUixzm~;;$UQq#(J@1UVw=^QUvn*r6-pjI2%~4@bcaHu4Yj5-9KW|O-WWTW1 zxt%-PwiY6K8_fM^y7`|lNk##TTjZeEnxa5*yA_~x6uYcKB=4BDvQSrcuN_pUGHAv0 z&jVzqB9OB{fQzHYSkA$$mp#Hu?}!6HTW{Dm?5k6pbQf_z`;p#a?jc_Kj*^}47;+}H z8`Qqy;TVFwr)25lZaO6cWW!OuTKyJM_hC-gtbQ->0_4~hrqn=}lfL&`OjGaUC+1#c zN&pD*)Kc$+>Z$Kji+hh$7r;j!kvKKWnlq}VzSU*kA!Pje-yKo&*FJVlFVseZ!g__6 zZ?G+Q_a~_@2H=FGzQUy7-_zD>op-8!uUB@#*_G9woLH;1v(0LEX8@=W5Ci}O05elY zBme+kWtY}kL93z%RS$CScYZe$*}``u0fZ@F4x&bCrMo zqM{i9uml8~N8V@1yr)k!9^CX;&9OvPV&K2sRJHs)UYELU17?(Z>CyvcShQmwV@6VN z-{(R6udF+skYKP#Rn__802-<&-+TjOtfYMLZ;TbG(rg}qs;QO{2Dc42Dl#|5BrMl8 z(*Ohj0A^;OYODb6+@06g?*DG<+S;yVY0bKhw(K;^(z0YdM(J;M6c|YXr1An12rU{w z5@0Wcmq=(4Uh50$i?9|?lAI_v$2stMlv1{|EC{x}*Za-4`r5hIN@q{V^C;LC;gPED z{)%XN8a-$FV%G=nZ1}v92##7_nK5fn+7_#?QSD69P97bBj#I^InksrVH%D4DE(wvb zz#3%`^`V7;sm+Y4gQeHYf#%s&ts?YrAr`x@QC;w<*R4t;Y#XH@`=p3014da(y>-{? z+2cudP{i2rLM*mlqo+gG&(k}-&|a(r1*|2>UI6qW&G;&NA3KI8w#3= zYE4>!7GlVc6lJm8B5ZIjdf(aQ0X1?bq>EUP$DYqqSG}jVz(jAaIPFz^g+6T0>m!>% zL+47)X$&)w4_2(^Aq!3jEZY7R z>F^E}93ii=>-!NJM5-OND#|r?(Y#Dwd!Ar&?$WR~FmwZe`{71)9;P9ai_6^Z0lt_P zmsfSWcDl0&wQF^+yMNRFL>Ott#y3&fP&`#I0*{Q=b>YezD{O1Vp$}MB;P>KFY#CN0&6{s{yZY!gH(r>LV+8w?t)33$r4($DaZ!-}U`?N5gmU=}de< z?5J#6whx`R$DY zCf8+EFsKzraYIu}LDzLuH0hiNQA!47R@a#_E$dPv0~aMZu#}9zEHdXaP^bfHiiw(s z_(Zd2{)7paz-z=VCnOVS4%VG*#IA=a6PXERt7O3$l6yR9hqX`14ttjUhg^rZ`+rJ( zWSzylt%ya#d0pe^bH|j^3=YjMNEQ>DBkHS#x>) zm8YnL^S@Pl6VM0wbUa@{cHGt;(feSvs~CF8q|8Gbu)A;~xr)7z;_YKx6q3i;Xd+dDj_x`F4TYWWciWT>eBr0>>_(WZ$y)_Den*`!CS)A(&%<)(?5s zlC;J*7ts(JKgs7{NY;Ll)QsU)|F^x#8)b&KzyEoE$OShX&yu*yif{pJ^llMJIvTU@ z=>J`9{f+ju>O%yEO%$`%ePi&f#ZxOk;f7}eO5!j74#Fe1>UYo%riAA}R;6V9GH^q2 zhPvkY(ds7s3@XzRB8k5xmQ zaB1mnbX+XPm=;(!sO(h-rnXT@No8OBvfpP;(rB{ZzBCiRM>^o%+4#gFOOwIN97KXx z@*bEA2ZYY1nsEp2!Y3hyNm}l^a7k!juDEOpUv3h@7{n>aB*L+7noL3i3kjX9FFFog zC9iM@&LJ|c+O3K*CrRVueph2X3=&p8x*iAN5rkenS%{sKGRuC~ z0j>*k;ZHob$R{0!kJ`_Uo(zks%rw( zt8dt=j7Vz@A@u!JY_W7oByN@@`7<71 z*z|7V0Fr7J0?-b3?bvgfY@4tB)P(5~QWo<*if7jAP{p~CP-^>p%a~0{h z6js2uHJ@um zx-wt2>UBl-6HVWkS(@&qb!e+0Tzcidc1qFO>c_le2GQ!JJLY}l-KS@t&wM&RsAYQJ zr3_h|y0w!%HSK-V753hqimQfH;gL}y)if&Vc}iL{61W+B(C8BMY*bZgL^m|jkazZ< zzF$?NcwEOO8#e2Y+89OZD5smeFR3Ck$NH!%PXDrV>27b!RG!V=wWK!o_X)P;**bb#D>x#BFRt4f@}8{wh89HQ~b@ZGTo7 zHev~VFmEP7N4lGuW`Mh;U=dkTRr67QNUhP`n>SZ;e{)v6AkZ{Q$IW|{Q#>6%x+fEF zYLTe!Qoq8w5xURL^t1zlUx_O@nIh?tG2}^i`fkVw_iEOYu7;^EuZ=V(OiaP#`zLmr z+pTh*_+{=k;{1PwaVPK!Nt)j25RFZ)J9x~#=Nf0*wa(sdT0-dEH-y(;Z28`wDf>hu z!`NOMb6<23fiO;+wS?IK@nra8PO9Yx>}KtV#(RhVOd&Vg*5CbI<=<725z_>inx$FXfF_@(~wllM%1Lu!tpmloHLuKmjc8?v_YI zhb@eg-2YSbmHdeNJBO40H5+n)>rH356HWKGZcQV~eTs6x6L%8oUP2=;wfHt>|NWhS zwa{MoFUJJ_NC{`A_Hj{2x=P*lg z*syY@{N8K#sCE9j=Xz= zQ-xu_EhrCG*vP571DQ6i=lugxnR{2(hlEV>lYIU<3Pq1cQ~Bd%G=NGQWm3N}QVnoF zwKoj&sf|dFTGeL3*Kl^FHZo4?jkrZ43ja!R+O=EV>B?PeDk7TO72ujY7^VAAALdjl z>1bM68MlnH^Re_vpZbM^*U?u_WB0T=rWoJc@~CuNR=sDK?^iD>egk6vTsK%8r7Z#^ z=74K(Q4e;-Ja3kfrst+sm5s|vb6YwNdd0L{79&vULznY&!ib@je#>nB0S(jwK7pIX zgW)R!mJIQ$5?h&Tx@B&Z%eU)(WFb;i$}5ARQF)GCd8S9WBf0E4eqvyHhg-)-6N(c5 z_rVt2+Yjx}|31;7fmK>AD?&UwLV7J}Ub>ZfbbVeYjA=q%JTTR{(wn{sm!F{aOTaR@ zgN-=J%~Py-E^!E@KL`5Y6pLN(D1q?gk3!(Y#YEp0%PmqH$I)Y5VIxY8Gt%mco|Syd%qcIlk*sZO@D0dy-R!i{Q!MuW zxGOKZ1+Kt+jHE;nVj zn^1JaAGe*Wa6Os^M^)rlPu@uL5g&;Z!zcZfU75NE`@jw{>6UOGT)JQxrf~DiA=H+) z6Sx)N7i(nhP*v7LJZrb7{hD$vd^0MG z-Bj;3*`4=k*q)=0(qkxc$tfWR_02TRaecMXjLM_V{Mbs;x zb4PKaM`rGt=4brgzkdBtUR+;`YZ5eDEixm*6--7HQIiGRI_2KeF2g5+@*4XshCsbg zN^&Vfhe+0VZEQ3smQIzSh6%hPP*fD-SP^dUJ#Eu_3$-j>42439I~EO(f}FTJfA9U} z*QMm9^{9c#+2*#BYHhj?d1^~)hU%-JcsuC8v zC3yJ`0N4scb}G__+T0)J78l6W*m*Gy3f(M|%p^bl_3QWY^7>jd({=EyHx)=O$c|h{ z=VQc*c<Icn^-7!38Gl78iICv2O?NwEYJ}=I34%m!7MV4EanH){Z0 zJi9D@W{gl^+2MC*MfIMJ5yo3kt{JCCex_Xw_?YNA9%11!$BZMB(!wyKZf_!Z9#NJo z1*7D2;a@VVnKG1EMjQ*MzHspyie~-M`Qw0zs)aZ`s7yN)EwHZz;`(OoVTZQJ3#=_` z@kl>?pNnbXmK(nW%e==$F;b?yHurC|*t3gydTM3|H{p1!&^I)jbI%*K1Sp=-3M%O} zsc2;!+p(dSWqsZWkKdX}&~K?wpk=Z07;K9_#^ZJu<&5EEtS@sHkub_EtK|Z@7uS~@ z>JuhK`DN1a^%+~Ui7m=6i>lC&-OHgShVd;&{NlHi=cZQ#SU(Y~m&%26EG`34QSTVQ zX{X}Ps8v$ARP`$im0OQ(ZB5kficwKwS-=rMyS!WsJQR3Td2H_T>{f~Z%SCx*DyxB2 zlvp+#3;!ok#SI`|=gtYAibq8&xhc7-Zc>1mP9a}3#0~?EXR<=AcU+f{*)1c_y_1#9 zz3I9jjKR94^L)v+l_^`uYu$Fq{9AHGCCiqU31Lg3)gVMlN&98FK;UZR5=nw7o8uN- zjioX^lFn9zxIy1jN$gc#?i7a4rBG0q^DJgoMFo32kP)4mWhU#rU=0#UUtj_HYLiYa z^z-&$Uhj&Y*AzOrr+{pEp5wAnCLosJs!ZaX%w^!|-Cg|9?Y*29*^SA{WkS#Lx618x zX~~Kv&9hdQp_)m_%4W_DSe;xi%H(Co?^zMxI9MV;-hm zsFnV`!BWb)A6B$!jI2gfxe>%TS;Hhdbiv6722M6H204RHX0Zo~$$fK-b4}#>r4T^A zlR`W)Ma#)m*wSAwEZWa}#H^QCl(LbmR-{wrpQRgB zHo1(D)x4!_2Gs_!l@IOvXIC|qv9SiaIO6b-m0@Gr z4fc!7M^cJ|8Eh9JnVL$<{nx^O<>u1eW$j>Y(q9ywJzM`oW){nzR*qbIo4NgPnOY1A z26j2I%^zh2+%3SlHZ0crKu}z8&ohn$_Ld>>0|pt7R>JQJSf1!k)Q|YZY()j4}UTt9Hp=5zLFZalj zq7byh$X$C;4R_}LyjKF2lUqY>x)+mcV6$m^#aB&jp}FE#J=Dt0ZFj@yWKe&3^3oQ( z(9>F?_S7*y(vO4`jSKEx7D*LNZm>EsI%T=KZ|z_4sGco2N0Fn)(2L?yL_H-ShqCBh z8b1YF###Gc;p0gDk7HPlWPh2dpR(guz8ox5jR)^jIa7++BLFsZCyGP^RlF7#aw*yeSpGA@(nqr|k z%DHm8RTmzv_EpqvEu$G9RyqsN}mw{yqR|+u|HCx2ow+b1-Hx1Avc+c+4q&h`&rhAEa0il}+dR4Z4uc7>%ujHn>QnxUR?DH1(;T=vA%X3mKttz2P)8Zm3;-2lLm znwD#UERGs6e{m;6Lq^y#$%@&anSsP0>kkt$F+0()4Ay~4vZ9*I7Q3X8uWs+unQUTm z2r|HPBbKou-;0F}F5xPmnW^eI;7bKmSw&BeH1;}V%4(I7nwd~jytO^toF*h$4`$d# zXs{+Q3sjT^Ei;p|VUZr7XegPOD3JmvJ?d8v2H0UJK1K|xg(zsoTB#Byhi8!zEJae2WdV>G0YndSJY9aEa*e=7P zhnxV{d<83rB#9t&mPFMc1)7x&)fKEzQk?L$eQQzew}WlwKTq74p*iCVR&kEaO${)B zCIJVMC7!cUNV6y{%yl#XNK2G7Io8aD7YW=6xCD%4s2oF^{&1R68XG7Eyb`EIihx5; zU}Z5>j4i`dkVGw6`X{=SF;vo!CS`dQHUuc<TO@&EN+1^M5H9>SI zB?OqAc_4Er66h#jC~Y2SJSYl>PYO7n00<8(3WrZ4ljd2)sUmgADM7*0W`M&)qq_N= zQ`{%oo&ooXM-KLkITsfv!eaC2W6`pYvj0-}{}N0@vkE7w)~BD(tNLAT$WvqjlDC4e zMkf+u)45N+VXQeV=SV#i3K|zMgMJN$vDL48FwB_El4G_2ykZwG%fqHg+^sNjV|Qd3 zFv?^Py>LN{zPc68nHw7R|eMo1$PKUd0ByhMHu5Z#YJU zfDMbwb)P|U$6IE(Q0bPk%mqay9Ve9D!-a83c&C^O00Rq!LoDiRvFW8acKE^;37=r& zwH78KQ5MaYyEN}}=NB%K7=psa%|v{jKJzEzX9$a?tS0eZAo1BqP6IB%q=7#Rd_LW? zDP^Ph!2%-mZS_t@*0QY#_GN3EtC(@+&M4)>!UYz1w3h5=kfuO?B zNYx6Zm*UvK2gTAhW!%Q78X6X?VA!Su+yYfiv*8nP)DfRJZa(qd!oV)2m0FRKs*ajR zpF=c>BDB{8V^~lK^`C$pHJB5tjEO82JDioENcp$re~I`9OeYj)^UkrK099kolus-{ zhY7~!@XqnB#0!V__{`7*$we2}|-Gkl! z@OCD&IG|YlxO~6_^Dp}{8dkSBr$(K3m(K}9>^e%C@GB^>=%wq-$^ z)M5!bd|(0*pR1O#gK+xV;N=6vBR~(pq!D0e0hk&{N+ zj3t$lHRC*C0+uEQVi2f-!ixf-Srljv~EoYwF(N@KZ4~+aAZYQ z5!n!3EHIhS!uqKU;|4iY_fb+QHa4M1>!5gBqzI0ApLj8$T2T@)8vu({@&GUkMKf82 zO0)@Cuc4Zt&EVwkc;=D6wsPYFd`vxK{NQF;d*$d7@{Y7NrS!H11=4TInQES>gi3LG zpt4s$(V?|i8&k6=ELetPH8^1!niPu7T2mLeY;)R8uht%P8pvYNP}NZCDKxMB>*$RvsWlsaIf{ERv>alG~FM{0j?7VO`y&U6bZkTWZ7l zRNn}>(t={pj}+iWnxdWoV3x_+8v;cG%p?nslT$S#;D~)x+~fT1+}mccyPc}Hir@TD zFfCFV$J-}!uQ`0q5>rLM&s4+-v=cE!6$~`eI10`N$u`yCYOH@fZnqy-RaOj1UXL0m z#b;Ffrp|$}UtbJ7V|>%O@C1D#bPn9Z3JM2*3-RlMW0nAr74&5yaIg8CmBH86nGl2u z3PME2{b0owF>5h2hC{nPvmWobftU>_D75hEkFb0z<+{3Yh#?*njT;x1-|G9IF=fhd zlDMGyB%gTxa{NG$EcS^64~0A3YQ;QP`q8(nuuXgX4Y!}(jez!~pl?JUacib%m(mXQ zG!!>cn1Ukv-?s7+|JyH7=z>D7`|N}HVjx=+Ab0;0x1##Sc zqFXY}+;vw#lad7Hsfwx|h9P3oK;qJ3raaB7CpC<2?LX88yPnr4ZmTy1_pioxj7;p} zH(S`RcLpYoPrm(%6`%Q3-j1>t6bc_Kv&5rr_@CTx1*yjt(x6a|qZK|#z`&mcocsxZ z3O@mQfxP5Fv5!b*Ht-2F=!Z{mzz(0plX&6?yS<12u=f){~zqReJsDHJ}^&d85vFDVnZGBzst7>0Y z`@h=v|MT4Iy!u^oqvsT@ZGVx(!#lsN{`adpO}**|jRAIf3jbhT^Ok$qCexjhTV-g$ z>iit*>ivGr?p`U=p{`C1x4jF3Je`+3SWW!k_HrI|b>_Ka`dyubZKi*%G~NTB)4l5j zyF~md4jOfBi+7Rk3A^Uyt=)`2vxnmEiHrm5>g{Ub$xrof6eAc8&rm4nXzjSiL%&`c zM{iGl5F=j^yz$>SxuwQspAza8iBN7b+S)7bk4es@^bFK<0_aG%R6TLS+#4kyKamQh`u zgOWqH=Zj-&^A?pvOnaXw5BBT+8T%cNO$Rp`%6HAcU&Xshot|aKR_o{4MQ@sGPGPNo zl9|zesoZT3o$qEXd_ZgnT?I&Ood67dT4?NnKP`B-oBSWFjB=IhAmuo#M8~t{wf%d(s-N z^V9Q_w4M!)#KIip~N2rSOmNkP{kSBe$w8HL3G+}HT<;@e(zUTFLw@s*M z;9>Sz{_gB(P%OVu-`an6N_T?wg*cZ2Ud#mIb@;YR@n%(UU|-Jl@$~Myz$8}&x$b`N z+j;KvRzB-Vfu1D5JWxR+frbo$}Ey^tUJ>t5LuviFdC z(*Q4N1<)PjX3xHpe)aZrG~xJDf3W=(Bd;>ovy1Gr1S3360VzXH|B>G*8- ze_j3eJaYFJE7u8oL&;O<`7^QhE<#okja9s2f(Uea9`{+a`AB88neStwFlCwz^y_UB zNTmu2a5*tClS@>04Yfu&mo4YhbWg?*Vrc)0rzwJW84{ka{Og};bsBMBOjiSuR`IPe z7lCFGP%zz5&#o<4w4BgAqL)oz*D(Ibi%7`(R)lDvqo9bpQ+}SUz0`iX0dwqjk~MlG z9Cps{B~jHF!?tqw**uls?9wZOIDA}CLmY`G^6pj4w7|Ezlu=PWR7Ifo4VQa;r51p}f0kX`a|!DOS6?Y1$`Mc~|^5 zZhL`leP-FcG5<$|w}PhrCz`?rGG~QotCP*Waj;%A!>vzat?W1{=PrT3C2?epUCE#)w*7O<@H0w^#H^1v4=jVY}Sfr!% zimiqmOOdP7#KF>WTs-|MgL4Vn<%bsQKFC#@`bR&~;ziqw{fw7ro}!(f4v!g3<3{;S z)O@-cQf|OFTR5(CqcVP?cy+hdrXfa&^T3Qo zcG)!_RNeW z;R*M!y6CN0=Pf7}6fWn=Cm1-_)vR8^oi>XmcO45&?qgFr6pnlpXg6HOV{X>~-rrhf z)U@_l>f4`q&||IYd~Brdir_p7a<^5-Bh+|yRl}j?RVTP^i)3s~%?c=g(+vMNlA~?; z(6%TbJ}!HAEE*Snd3b^%rjM90j{NfM1%*5x@npO6z@sQA>+aAp)9_04p#69t3@Q>Fb|tIZo;1mY9B`JW7(p zZo01|lBb?a-QyZmS8idZ-e}0?w+)qP>*H)>0QGvuGsuRl<-Nl}hLx&Kd5|FG<7uCD|qE+p?A|+r(f)hS(q>#Re1O0tTQ42Z2EHoP-647wTSsc>&;szZgPT z)}_=^>rv<^Rv$iBQi0{OD(ryNvi|d}_xkYF6f7P1tEd(E%}TmzKAdbJuAQxZUilXVCG#%u-gja6W_ze_Qts9*Hm(%?jpjDm#tcgw=u3OTjD7+4<_@X- zy`A64o&5Or|0=j09div3#$k0mTVDl_qh;oWs>0m`sVTT4evc1VS&xc^aR*IYoi$%| zW&Nru(xhs=(Ig;u|BTuUH|5$ouiADRYpK<;oH}8Su*A{uGhTm)cTdEKv$Z<($;j%c zekt0jp1bd!!3_O#^bJR`uqPhlpSrdaWd(Y49co0W^8c>m>Rtn8B@R!eL5aX$vvcY? zA<3g@AMJ_}YhB7#lI5yS*3?kbYE)>aNW9hyHRv=n^whN!(GwOOcAl$y;->0s3o&>* zKg1m>LLG_2BuH7UL1y$7&I%g>Hoxi z^)%!QOM@D@aOH5D*JwUDroz0fruR3*(r^#q-?{OU@dAmEmRrXee2Q?d&i^}2*9G_e zB?Mh^qjT7hDsg+iMMbKGbC<{LUD}nzA}Ni-I@Q%s=iWGOZQbfKs%6lx!GV1#ZH)_r zSI~+xKz^mf0=~?Nn^jluF7TE-*iNmdMe*!zqJ8!WqwvXFa z>K|Q0C`k`8LSahkS?9YDFt~Bp_$+B7*SD&zmReXa5%BG=_nAH>lIn*=&k|;-gooW} z&C`6_5=Vm1PJadd)glGlzGIAsS#M!gWi7i&o0YSRsi(eVClVlS4s)L+3&XVLXthm z=Z4y;A;))@69)Dm4;-2sECw(fUok=35{G)HHa6-(9aA|*vi?*`*S=_EH(CnY3(GB0 z*@iW5fA@LDgZcSu4Us@rk74@C>FwT60$kzWu84B=M?Gk>Q2u$ zB}aSzsJKl2_S1YGWAU(6?@Ih%#w zd*(;owwwNFrq#Og2^7o1Fe{RNjw5<9(zE(#{$i@Rb?R4-ZhOz78 zao7s}6|aKRu3Gr)%b>#O@7wrs9ud3G%j81HxMVtM}ims0;a~wQl=m z`Ey?xVcl-@=#3Au^h9^m`DuOYc{@d|zSxBgsk#2J^e0oB-56c<{k7NZO^w4f-<=Ri z`)ilhq4ZhTiHYD>izC4UFveNpHBKUn_OF9+z*z4j*QN?xVNR>W9rtIJvqW*&_bXrO z0-NC1y7hq+5{JFN3m%;iS%Avwh20l+n98&dPD;W)f^(YgR-a1!&guYRYP4$Y3Hc`C zVjNk(O57?-Xa24@jKb2bgJw7m@)qmkEW-5^m_Dpg2VTluw>jEmZ|g|pDy+l!Yh3)= zY(JbM{K+bx+TVOjcKa$y>KQr;4{9A8E74?+4dbK#*eHpyzl!q6S#rZpe9A&Q;XZJy z_kvLnjz8n*3J&oVu9p9|=Fa{QkYweGZ**LuUK7tkeyvlh+O!%dBU z@}nkd9#JG8|J8BQ%3n+DG6-8+DX%UCB{=F&w3y(xhRfhD@PdvQP$|S=B)%)`z~ldo z?+DS{FIGo^=zjXw)BJPqQn*!MY{beqSeGn%Nm;jExGA`*`cclvE39^T)olP59L7Us z>nMcou_hJ^(A{DVJj%eJ7JIQpsmdwgA=TJT^-n{0Fn}K8(CB2bgjtcr@ob^Z92S^P z7wBXC?}t%wTts(T_Zaa@VQbhHvv`ZpcqkCFf{T-)s~L5YHL7E2b+Hcjq%XF9n2%0$ z^Ww+247pxBMc9j*@TmL9D*rGlYa08$U;iM-t`Ct1_A_Gr2}aN~AUPEnjYPVvjVg>V zm(xc`FDz|OYu*_DmwN3JBcA0~X~=3(RJ4MB>LDMew`g+|ub%@|(Wy>Reon>5zUk{c z4LieEY}GP;VBDMzcX(kJ=ng1AS^64AmzX8FNesXQr~zXXP&p0cI7uUk!&ST=ebip2 z5TBr*p`Omw-P4-id%;CFZFen2y9dzL&r$1pG*Z)#{o&H4Q zTz#|Ue%!RhH4s;^uyI)8(X?c2d(#%ZETWY-CW7J=Myv`kGahD+SVIqm>=}KNzCsRj z#w9ZVDnfg-p%84a1J|Jt8{-)y3t*uTMB~UzAtuH{8)~0D?;89~Q49>~y*L;*XG0E1 zW>k7CuE`R(Vn`G@P|p~^`+k^KwmkC^OHb6s(9XTlbYoZ~E^#1jtRw>g>=56J`B^B}tzvS=)1%!7bpk!7i^GFaJw z27OB$5se@-3E8WB#A}?{!wyQbnmOY@VGhoiPnAPiJX5M@(F1Etx}2tm>#9&>h{rM2 zF9P&5IlCF^v+F189_Y8R(99U8w|Qmf75$;M=c1ih4K;zdkkue_8}p95w?jP&d5{B- zTSR2wWFF%Le2arDiOgLdGT|~007m*2gAAI?WdJt5=0QeLA_aU5U>d}&!ICgTN4rr496Htl@$$N^Ma*P(md-@ zswb!?Tesc6-t*5;DaOJoGY_11=3)4n%!;ku^V%{j;(%9d7Vzdl{8Rp-cLb0LlX;HQ zWGx37E16^ayuD;qgKUk=XiSGWECS4ffP@uzJ8-jeuif!6pfN1wH5r(Y|I2}G2PP6S zV)<5Rc6L#W?CF*`p&M2Py`k891jI2@0tEykHxvORymq~_hQgz22Jtkny!2)*p0;z7 z?|SSIJlkw^izBEF(G=FEg~{-`4SIUmnYM=&VN6OAqypy z%6XMvAc_tXP&r@pbcI17MTmB^Rc3}l=$#+m$Dw>Ts3G+=oUyCe?@_K2(0>fn2+`iI zGGAy%nXTJ{Hn;cL#{72L`!LPlNBip-{UuJi@&BCv5Mv8Jty+PvymT+034lwE!||L4 zn+7}0-#ma|5>8s{2nl(`-sMV~s;*e0uElxpFz?L`KvP)P11U4<0?S!<8t9Du!V80M zAM(CxfkBt^>w$$E^uF47dp3RXJp0u%rk=ph-P&BVZu)RN1RgP?!A$Q0<^#pD7q=j& zsg1E6G*n`Dqn)6hsHW4S@6!Fx-M8*jufJZ9VIcR#gMdaiUAXA;oj#Gk#Lh{J-Kv7fed!x~?U z;0kl1tq@bcP;iJnw@=fBc_)INrZ%D+s)#gp{vsxTKy(^Dk@&SdHLJT+-n;F2{jM7g zch5q*ckp;*U|$zq@5$9r;=O_HaRh3(>i~z)q=~Mj>3w8M$z@`hIA{FnFCp$&eP-=m zWP3r(&|H)*IcZdJ_+|16K~iE<#F!751;1Kn_RiY*W-X(pLsyDD(DVnHO}6D8X6}P} zJ&f~gc;@Y1J9+klJ6kY&4GhdvuN@0&UtTSbtk0jHXqcC>s2ZFvQB=3ku$W8DE zVYHyak)oFnS?471V}xGOJhR6oz_DO4#bLg#qToXoV;Ae9*x@iHf2sXlSC~W;m>g@0 z+TUR;|1GT;TDqD#`x~)n>Qa^sFYOz=nJs~P*|H#&Y}v5Nw(Lk{TXv{2EjxRevP0R~ z6kJF^&NAk9{B)NhpEFEhkf(&_zDZB4i~TVv_;_bfJ!Tr842I+2V2!oMf<)b1kXN9X zh>FMUNo1}VpDaVlhn z21!31$WpG@SYt=eY)dM%%#;9&JX*q`UyVsgA|!2+18z+iRz&onD~lu ztmGq*?`v(chxB3cajAiF(jVHr?T6K0BFBj0aae7VF)>MbUzb)aBDBxt zS~xAb{aoGO&9{08+Y#j4K;prMmm;Muqs*U=oUAg-p ziz~|vX*&eZt8Eupp*6s(>GFt`8JK;e?to##O~&3SZHuqpQzT*0Hpho)0?toJ+dg*p zZVS3k>EHFWho>wqGA^|@&$a5o#)^R`!nlppsmZ=E3FF7M0jidqrZ%thYgxMc@h9Co zY;C=p3VTlgNOXm2j3lzXL)D=O6#w!Oo{m3MhK0CR8KN{ijuB|D$(tyRC9XHO+7-0` zF%@-wa>5Rx0{K;uH;(;FBhQ?(t~|>yB%CsC<*KZF=NEL=FgpC=(4yee{LP0N%0l_^ zb$WWCMkg15f5r5Ay1hk118_AaccCyeM9e&gRS!eo^(?g$MQ<0&`sqat^!WNzodG_b zQMdJ|s}WTFiyV`D1tXb|N@Zk6GUIpDJ)DbBICG(F-WI%YE<*d^oSk?mAGOhuACYwA z%3LpU7xR0@MpsyanQ@*paDKv=qb)1No9y=b)tU`^LB{^RaWt&4f66o4y zD#o-l@dz2L`pNL!t^LSd517wdw*Gn`{4W0Zwxjuu7OittIp4?BfGOfI@mi;A1S^h5 zllx51Y#FX@kL!nCkt|E1js9@Py&SZtacbwtEc5>Lkvxn0|8mT4oSOa>)n74>yLP&S zx@+94NJ;_W+xViFj2Ul=jbzmMAgAj{RQK%iohe>kjywt zrp(OIys(Yp4EoGCUgd2h->pyKp0BE{{ee;cwvTLp$vB117xiA%yQbT>hehfVkEMov zl5xAZc&!-t8fT0U0oBN-K`d7L$pFSWUQclp^((r)+qPWbStZC)Qe2yF@33|dvcB9HBG z5%(ozGidQOwjFY|IK$DszBsc8E@zCR+Rgo(#J4Q6=f~VF+9EkWVFFwhnd6~_M|%^M zPDA^B@ZusXM2(EYlgn|Y!hBdQj`AQGx5$qF2)U=Q|6DN;&GX=7|5Rmx1;4E;+*)eu zRCj5*VP?kp;}RAYV}5I?ZMynUDR%!1toV;q42}-t&#!#fR+Rk7@h82IbcHKbWR6(k z!*|w!BgXC0=cm15b%f&^xS`&b6MpqvKO_Ifjg($iWTYuTx+t}P=92u4S)2!v;&Yli zQ-1J6p`fAu&9EHd;%?3>qzs?eE>%)$W}9xf)wPp#vqC`gJR3NWMPH%h*r zZkcEWE(4SeJ2Ajlf-?MZY&hWHijQVOed4F{_U= zF+Ed>Nfkpgm=LvPmH|D_&I8+dE*XHfHuCJg%cFP+*w(F`eUKx=P-z;8a4#cFbVZRS`l4LD_n3a>m)_m;2vgc~IY0~iQ{>_Vl{TKx zq(n2$iA{8s(si>T$TLQP9;i!?{qFG(bS} zLbPEMr?=DA>3eSv8ySR3(MYa#D4ZmW?idlBYNTq)F4o^)dR4{?AAn%eQ)*)s=7?_` zB@22@PZy6%8k@MPsQ(epri(F#I}C=Rk(?;&%VFIo*Z(U7G0l5F?uR2+AVsj8u|X;{ zcpyvA1Q?`siG6qJB)3qEgX|IeZRDtr!MU7Ms0IKkVIt6%a3F%h1?xa`;ir$7fMCLf zl#i>rBbX3^kS;?~6mU?~)y4HRXo5^pMG9j#*qGV~NnO(nf`BS2rm2%*jTK;;&a6^L|QU(D-m^ntVXAT|a-aDc$;%oNj3CLfA!oQV%L zK*lG!KuTV^yJObnxOLqRpbI6Y1C&I9HrA89cR z6%%wlJ=AbuZdU+iR02dNRf7gVqhk%_4IP&}MzPmM!rMsXnAE4%T)pIZJS0k1DoV*G z`YE*xBK>-7RN(j5+p9}hkp84D0ICsY#kMx@DpT4spqf)fG*M9G59#yBK$D1eiPDV% zwY4Um1Z%$#utEubY`n04LWLRmU~YD`81@vpa`gPM+hsh^r=%7*owcG|hKd_$UTpYz zi8ICqKvzb%27sub3Q%&%Hg6m#PXyUAcP>EuPJ~{UKxG*!ZRC`(u<#^c85;#y3B$)A zVM`e@mAqq=G9rgT=_8j@elt#O`^6_KnIvS0k!`F>&X*+75*d{-OBk^9jT?^muS$Zw zATYl2kqD=?`K66#N-Ccx#nMX=NE2h*CW@SBHc0N^8S8vbV*f}M%e(z0Dt(bBsI@ri zK>}Xvh0oz!zyO-6g@{ETBubPtEeH$*G+7IA8?cftq0!Z(20aiNw~_E>k>Vf`E!-o} zy;-~t7WA!xk`bv363Hz!oX4FTDV**yMt>ez(hOH|!+>f@5X;%BU~QYiGZ@-hoNmsA z9BAzG67qbOs5m$S&gUd0RJeHj!*5af!sc@R=bfKM{wS*>Yu8%hQvRt^T#Ai=UAqS8 z+m+;@LBG_12~JCaTGJdzSc=&90Fp=(0_6T_w5$aC{xNoLH?75n598cy^J5B>4U1Dl zeqD}c)V1ajxTtuBG*za2uMU5?D};FBJ0<>@?s>CrKfXT=biD}KrHxqTj%)YdP(vV5 zcpz1j*CZTOV0*;nK$pLw;>h#A^+5R6vg*v4-KM$5L%pF-O~J|^pGn*e?fmXMS);2< zd$jvlAWaajYa`0;(Zz6Z@-!k$HZpCzB)aNpCykl6m_|EDo@w;mSMzgKXhV_%P#U3o ziGU$uqNswVIwpKtOu>6=_m^7v+&3`;%Sm`K4RC8Cg;H+N6v}(Q10Ew!#Zv8PEFetb zs^cWhq*8+~Qe^zo(fPLp)Zxtg#o^5e%@F;hbdX+8&+AsApT4`<>2;#%jQWrnOt5_FX|BVz7FjX+}+QzImO)_4O{Bat&!`gae|kT5D_ z=3%Ch)up`Vx9UJP0h|%%D7OCt^WQwxp8tnhUGrxIMxHp^&|57%ZH?%M-<<-N9ewlB zjV=*^qqKuGZxX;@0zJAm{yRD& z_sw`684q?FJ=3QVAW!%L_)Og*E9rEnUPLW?G$20CB>yt19B}b+jYK@Hu#_YWy&0EY zIX3{Rk_J)>XOhGLVuK#`58xOiO7I#1>S+z$uWvp^F={Z+9o&Kx+eY6!V1W)0k!}Qn(yZOV`i>Qr37$M8qs@5eS8=$hgAQ5>;?Dgz+`PfpCp9rAZrO zUl!F#Nb&Xf1-K{pwh`DVA$v>gwK#3aa~%5RnE%>ghrxYXBW?WrWFLqCrHugUBT)QV zlwOPg7LCf)Um`=0a5Jf?^$1y4R0DfO(OTn7O&5VfkB|d!^v_dzm9g=)vkrRi&27JD z^66lUgb|c&a9|^i|5<#8;aqUmZ=a6~StAbr1^C&|hQgS505|zLA8nsMF1}V!C2mYS zz=eJeJ&XR&_?#I6N*fq{ID1xEQdw!MtTNOx1_|2~6D%g}_NJ*Xt*;FvY$LL_4un%9 z4KsREQWla2w+xh=MgYX5@x1W*aSF5zvtuT10CEjVl6$hY^v%=NSQ%u@zL}bjpqtP3H?4czq~;9oHqsHzGbARNPj5|rI_W&avyEE^ z2pC?`NEq$YaN*X7^KU~KjXc=}ewBvLnno7(CovQ3)jmt+$q+Xz}8gtH<5 z@Q4%9F+nVP4PSd)_^P1HoQoM^xqbCvbJjh($I@}NdBqbQ)rbVbHS%~bM4D*?zOF(U zq(+m)Sx2V=W7TVwsw5Hlw-E^eMxgknid!QiGDVRn?xJ%Cg|l=InK|S1whm1r4|Jhl z8=TdC^Z_qla$P5JKC<{%-I>jLFVQ$)SK;B;N*|W!8*%k!&^URRiyC!UzrOSzsGpj3 zyvo}Kl8TK0t)&3%vFrY<)uEuhy(85=Uun{6zt>pTxNGfBy^TWS4^QsN;fQP_DBct3 zMg(e$I_2MU9407cL5NhgIRI39AW6UzW0Dv-G@UciEFA~n&o><%qKp@l_K>7$Cxs1j zPX+jI{%H3!E*?c>uG`TYBqxX!aoD$bk*GKueo!TZM)U4cy`Zj3X+~{?zH8CQ@)JwN zCW3muG-t1kg|`vMd#R*Q+1~xtI?-G5SAG5e@pX{w;1uL>G@9oOnlKxAcuE$Sp>Uhz zM$c%1+DODxv%;T+s!LWX;8P|`l|PLYs0q~){hJKe3a%vSW65bFi%_8<3(*YCt4ziT zv=ND?vyBdgPWX^GnPK*$VX)}MOoFd}0@^=ffHb50_b(;|=DOD_TDBDcY5%pNtEAvK zwGq;%YIsAvCb-;xn0Dv|Z6rf#M5ZuEN}us?P|&#FoRYhFQIDR|liVOQ)<(LdGStmM zYQbBwjxI-WIROVNjYQtDc^+tlfVR)cjWpvGBhI%^$AzqsCE3v@{vKC3k@P@&WiE?< zV^cK(qlB+tKmRS7C(rE$=svnuN=h_X67b5^3XHEmVDzKUKbdP%^#7_Y5NNcd`}*kW z;wS;GZ6imOwcn**$vmdN38y3CRc;-|#80k&iOUpR9e8MyhvXB!$60UQiZ9;a*-}rq zjX<=x#$BOCXXZ~RkVK$iFd$)&&c)61HUsWU9;`#ip>lv^HqwH6eYgzqoK*vIe0b_;FU(05U#Q&+)S`jLK1e0 zMjp$iLYg!JTU$7b>rf|q+2$yF*8A-*@iRG`jweR$n40*+#xD!VJAwYnC!M8Lfk)*Cm{hrbc^jJYz?Va6+jO9-YFt z9!s&FOrgE{3{zo2znFQD^i1VPiL!|(O2S1VB11@NME%lqfoP2gLZyZbg>OQJls%^? zEMjej8J3Vl+hLGI$zi_iGVf;J#EEmYFLorV!`VdRg9O?RXCWoXNmayT%{`)EFf&vB zJYAA#_Q(~1+YSS8=b7E?qKt}@Gi9`IrTND)h-%u1B2yZH;xEXEO3@^Wzi4g&aCV-d zHYUW)8MzVX5r>+h`w5G7Bg{qsor_eT_o+;>5}1`XBLc}qi!%|k5{Q%xj3O3|w-1?+ zJL8#!jzRM<*Rni*;Lj275vHfKjfnxcDtl+{-a$?yX(JO)XCG_|v&hrgZN^$eKqFO4 z4DEW@y&34@{Y`LD35`k{n0NqJWiL&eqVIC=5D)_Z2LLidMK=HdUuAxk7wB#LP-A2i zdEU;uk!pdpSxSIZ0aR-vDi+Z0MQu)nwh{WFaR0^{q*bY-re2* zO}xJ7UjeO%3Lu2gZ*LCBKXjahS!t1?NSDpRGDf55ZBJ8kjdk6!a~j%cjBm4}jKvnq z=T@{8G}azXY$R5E;vteoamC^uH@0lW0849FqRZ)^OkvSy^2(c)Gaw_&y z$Rf}+i$sQ=_9vM9B02X;u@Wv@+UgsDI^6f|G#l&>w?{7-kFCLFZGU^K?~MjC7#X+m zk!!_u$iM6Ms1vC!AnF3cV#En*2vxB|!8WbOapNUi|HL=OpC=j^#r=(KXNUK%`*rS0 zBEmcb%=Te{W6DwRt)R`tr?nl@PxRYdq2jj46=z8-ak&Uk-lE&YCw_HME50&(g3b+v zvh`uVYiq_V#|O4y_X#R1ZNJqjY_4gBID6N2wqoR5Fk^r{up%v8M^ig)MV#XR)lvCW@}m7NXEEN*|ZRIig| zMbEKTLlQ;R2c;lBjj}!`sG!05oEQ(t4w73_LX6zl+h@sqD&r7VS=vo6YZw*7vEl~-ZT_Lx{mo~z(SwxT}SILhB*a3S##SfZ(aX-<>OR}Gn@D;a%af?pw2XlYZaIc zvLGN71oW>NE|fgw=c3$CjnCJpgJ~92>O-#0p$@|++jQylPlu&fsvyM7-CN(P$+xXL+LiF^y%IXF z&xZLKYe$GEIN^>Im!4*Jaw(u%5NUbFPo_aR@_A4SflA{i&In%tD*-tZn>C$XiiWhG zSlqSj{q^Ub8f}!7Y>-9FlB~-uZw+y}cI^3j7FQ?O)@~6uuFmawFt0?X+g%{$-(vjD zXSY?%;b)~E&o(M8F}w0RW|Nmg*Rgi?=QZr@{c&LP7<##QhM{b_ucm+mSQHq5FP+Jr>uA>dYR#{_BD(hJ5RHbY9KE+Bubfp%gs*$`8vMvcb?(H$NZw>{CZBY zfrHLS_sMi-N2AZUe$00S471aMXU-sen@{-uvp>wa5F()_L1)e|=qwl{I*UdKn0pY@ zTah{{G-rp(ZFG%mcr=PisU9E9Ch7rsW$C#`3N`$D15Ctg*Z_4Nn5i@nI!ogWw@G;K zHkrZ9W1#qL84HGaS3;pB$CM)A+Z+KPDVH#`?5y);3OIS`$h~WIT$_X$ZOU&Ly=W{mSop?=4A+xXN*|+`N z!9-|oAfhtcMh5BS07;z*d3&h=zugI?`7pxYf}-9n41WHsof;`GW-#dE$!$00d`s+^ zJog^*Xx9`JvprNGnJh|q6Y-c!=9!o!BW6k2bh)qMO_X`Lt7auTb^7Y7mR1qU>9^SP z^oMf4dzf<38W#G=Hj=iBF;8z6Nm43{LI3xOQLJcg3ZR*dj|7;3KK=VBf(-tcSt`)Y zo_>AAw8l6Kcs7aL181B2MU}7GA5Yf z@BJPVnAzw%ge)M#JUqvYmEgF`CCtb$4-YXXIrt<8nUIx(h|i(qF>_)X%Z+IXk=!K* z88?xLqh#qv$nuhdA6h#PbAXkDVbait*T2Y=o(?-(p(aI7cda%}eN~#fY`y5O>tZT=6wr~pW~42WMzZvS z+w(?};Il?D;hRaKd{0LTeByE?AzAQ|A1Uy0B)i@T!Bp_J5`Pm#QsARKE8$6!?*&MK zPxaM<+|0#&dyQ$F4t~^*(_T35X1>PH ztt2+<_{**wr0XpvaINoX^w+_v!W~<&P0wE8AP)-5gB#3q>v?CmKXz z*y-8;lu7^BkAmq_TzG|=5=71bi5||! zSPyXSnwS5xe?j{BC@5x|p+PUVVv6NPjnk3t-^?cgF#|UEBgvVL(Sma%FvDCw&gLJF z$T0L`$^5~Or?VfZ)OTO_NRsCBxL_Vh%s6xqNW4vB6rJV-(Uu57`a>+I3~TUgxP^o! zjn0W%fXwCTa()zQbM>p0v7Dx@=%)mnFT*@>%8s9A^jjZE_o0}$zfIn!i5n9n3BHab zdC%@03u2L^U;2^+XGb}Fw=%rU(yKIRSO1cT=|YW|jxd!5S>WSNNyLaBM9d?Lzq1gh z=x(B2LUpM}YQJklRXFlCa0J`*U-skI;ps6Ar>@9*JDbfc5fe+^ijO3HMvo%+T}Kyu z10xVV#7OCH8p7~@a+#>D9b1M7+eI8R6x2G5KlsSEZPT5PuSQ-A>iNx!S)?9AD4|rZxtzxVbe5>e(NjS=(5CZn zYJ*)qP&{PalLBdG0V16v9zOzljYkH2j7Kzl21$WW0!f6gORg#;1-=O+7ruRD!^f%7 z`_51O?->*#BDu_flLoHs7DnuOjNYVT&H?H-acMXvVVW()QL9oI%Kzg z?juy1dbK~&nmJY_Cr7P**1?V>{je7jYa<*#JYDpS6!?aXP5u6kxavQJZ2&!U{r#Ci zb)$95;OsjS{`{>holknn`|2x8ca2Y)#lX%t0bVh~#9VrS7#m5L7n%oV)uFltT$loO|7auPsHZ!rtvzLDs;3F4?<0VjBgvWG zrO&n{+h=Ck_2+kF?`5Vld3$%~_J(?U@C=!F6kY>(QNcSzP_tcsZ_;%&%Kf$(!~) z4SQ#Ow`B+Y)>qm@ZR*9DKY0-x^lQ29J&+t3}BZp1WLa-%5p8R28Jhogh$IcU%zr>}C*B|RBM`l!ZI?J_A#NnC^~ zP0f1MlO+72DN1ybso#n+k{%@e&`Rpq?iSY}X6pV?CYe3cswDS{ZO)WNyZq@*Ns=?> zj1rzC_=hQ`6}Z`BGVC)=mWsVjzk=NwAb2Ul=(ny`w9{m$%Yv--IopYc>94Bovl@c- zPv2H~6iMyZHdzciZ}Zw9c;jDWma3KGCRs)Zg*r7ZP`!#+wI_A!)YV4mjqK)X?AV2x zT|Hr^S5{{^q+8kSVUp5}+C+j$tGs2Om+}3Y6YuakP-yP%1pV}I$lEbHo0x)rdN|~5 za2Gb)4gG96niod=o0wODvfIe`GtHtAz0P-o>PhlnI#CGr7nFW?ID&0@dFS-#;wre= z?Di&lNmet#JpopEpFJeQ@z=ys3Y^)ihW?EsSa5UW2d|jPeVe^xA=f&-P4J0_=(pHb zU*xR(sCFa;JB+OMC!2YOkhgJdGQ7|es%RRq1nHY@vcjw}D~lfB8>@+W)1RC+YK__E znmj#)$q`=zz(?>^@1>kC_1pa3uX}t3=4E@Cor!;Y+PRE$#~%5t`QcayGTS2vQ-QNW zT2T6Jq6FR@JN%e2d7Ie)0D$M=LZOK2&=uv=nwCcVla^C~tlA*T$XgJNc4ehF2t+_v zP>|HFS6b06^BglGJ@(%A=(=C#?z8=Uw4aqPQP$lDZjEEV*kS4O$XeH&;zZ@bq>xuc zj$=eGy7EN`x&lQDx)LG~U6Jbtu$*OzCUj*)EOawzSTDnmA|1j)h=f3${C}c zCQG}>0j?8OrD=-9d<&==MwP^TK<4FfvW}E#R}5M?%emMZj@l8@L17*VLsv*T&=rvs zu`7J&NRolBnOsm4;CV|}|UTLu2nMicyGzsVm z&_zVMg6fuNI2J^uE7D1zSEl`CK5iM7F+{>JA}G^Cr8z`~OV(V1sz)n>dz>FD@^wWu z20~C+I5LqMJ(0^q1UfP(fzCj9DD;FuUvu!%rr|1I7)2mfmd7MQj@Xvp~%nAGZw zt_*F3DTfLhehA}Pa@hFA(d2*D!59*x*Tl|?o9Jd`VIi9CiDgwV^O zkQ`&@8HQ=H43xV>C9UX9Cz-8|;#&slh_WM@X=Y|33pJ^Akem>zfUa-PgHD7(=q!E; z6b8T4xB;x?iO4`AqxbRuH{&eu!#zDB&?IC zz>b}${D5uXhZ*py#m%(wK(U7X6r;&~6U!3}QM#IzRb@TexF#0{%o3ZTU`MDsPZSQ7 zB(f$_P*}Jzw;J4pJQLyjIS*DPmmriyT-O-&g+*;W$TWeNm7TwC({Zk_gLzk<*xXN8 zio1;6u1aAc)Ic?Goo=G&orMhsk1tYBm}y4|YNsaN37$X{fv$-ts&1cjB&DO0CwL-J z<-(+&?#eHfXjw7i`a8}tHp_4XVl_uaSb zyQl~ZPVX0pK0Zi$qNTF5D65+>8b3K@2vJ|BIg(hOU0LM#?Fx-u_m+9}Y>wu=ZjG|l zqQ7=3tDE1Aa^!TSU3NY5_52d|de)*|)8GF@tt0&IzzuHsMB%ltbaq2Gxiv(VCxd|t zNh6}OFb?w?mD}#HngBQEF14UPB_17H|k#l z*SNOqZM)x{l#_f&VHu=q`yEN()sJe3Jp5x)YWcvaeoTN5DU%{ZfzCWarL*IAE0AQh zQ@M(ZL@9x@JNj(I12dIxrn>fiVvom($DV@*q)5n_J*y?MkqBSykqkhcH3m*ymDk&| zde|p^o|75R`_6l6e?f_?$pID?8jbEbiJsjuG6A--4kR7-$AFx(a`h8p$6w~ID<}`OHbLErfARg zlK0S{-Cc1Z1?YNnX)2G`JWt>re5Hk4-L61LgV+_hG?ck%-kO-bDm`?F^FdeFtJFi0 zBmOS;o`{m@iW4dA%BR*v9O-yrLbaSlXuA?I#lT78)VJM}9O6uurG~DC-%byIft?pC zcvM#&;v7NEk-Fcvn8%aX#BS;*4;)XmiWpD$_dneTB)QbSz2-RunP2>h41%1p>*$I# zs$EtnVQH$l92pjg>BOJeUcnkBn?RX$#qmw9?;UcRZZD@Z%FQ%GButW8w|kw(^=n?d z_eV@S089A_J)a4BlNof_@f3Q&2VNIW4qiJCg`Z9=I?1Uylo3N_m`o$UN$jgEX=ZeY znMToSS12zIbV=`c8DpJ+BX6hpMf7wSDD28px;6aeFrVHPhZWHgBS2w!hK^l;I~8a^ z&@0igpjV^;LRY4EY6&w}e_CIWW~SkI=Q6i&#VCZ%oA>HxZ8v^FD$@4g-qFsb1M;JJiCa`lpU@ z=|cIK(j#U~Rja_wddO)gCc-i(ffz>>so^ltQ(~aKED%pUw+C~J^)`E;x(ENPF?0L> zy-^R!Py-jwFg`8E&p`2yV-cXg#Zqxx#1{w;gn~{Z3>11-D;PN|jxeDsjs~IZl)Uyg zeg81V# zpo@KubI^-Epv?$Lf7^NPKwCkw#|BQat^CfKI*DezkzICsCS2Oh*_Rf6J=u0!5Xm)F zNJI`2<^*LtS#jpj>^&4D6k#FMK(Q-n$8n$pT_PY0y7E8}x`7}KU2L8~Hyo3S7M2Jm z6e2+nx@Y}i^nPY1V3upswKZ^EZpVewJij2}i=~mX1UW<%B)Vg0OtK`;%%y1^&Pd_* zDJ1N3HHBSFlVYIQBxc9+z@tZ9t220_tP~>6Y)B+Hky^KRy<>1SuipE0Chy=ZAjU)VDO#An|tz!No*9)-n7 z0=h-w)Zed@9K~M{OR_8RyOqej+HMAtB%mvH{FIC=lPc%~)na&7c+TeR<9y{w(4bkj za$}eVs;>KP#c+eHG_1KrP*HfWNSC@3EIh~K*H?t*Oz7pZFrU!!Gi>X=e^RfjtGGP0 zx(~K7buvu-0ry-}1D>wy_%h8C_uwLb2WKfjp%Hw*P1+005}H#2X4y?QwS-oMMG*sb zU3jhhED^kX*J2C#&6HO76cg!JfnCFYRh(mP>V6%+()n?FPT4+QwY;C|st6R8XAcxo z0A~Z+vC)FC2&|y=06*x`?2R2*Y!2?p=Uf^v@$z-lxRpgo*7Ob{LNLg2qQ(WA#kDA~ zt|vkh?Zr1Dhyz^$!2g)duzm4TL*Kqv((M+;JW~vJ1B3tM z9Zw1`EJ!T^5yiViG3c&NQiXb93}`}$Iz=LCzSG7bg86s)DbV$ZSVC720s6ZlYwjru z5Lp~d(2JlIJNogB7AJ=(EjHC+Jy5UR3P6*~6HW{N$!^FNC^&WHPb(3xp^;A3@1yvO z6&-%%^VYqNVl0v*EmR4&OmkIWt1FZ^igrxH5IdQ zGgur@P*;SvLzsXH`~?zEoep%w!aruxmWuR0?GBXW!awF|%as8s-U^97?HnMKc-1Y% zNb_vy%6uaJny9DelC$^AA19%1#VpWv>b!|YBk*IhKMPl1w;-lMKbT%`KO(UJtP=>XUCttp~WiTINA zSm0NW#zCt!a|j{~0hS!3JhUz>4<^z}}PxgjSngqsiVy|8=bvaUD<0~N))z?G`^ z8OC%Mhg>b?0Qd0!{TLn@0GXMvq5}X%0Mm!w?p>Sf_9x{4scD!+{D4Sk21Wqjm+1g0 z6I*5JP9q|KWM>Xj8`)}fbE&jc+Pw%4WUg-bCKhQHo|Z#K77O1q8jXg-w@X^2;dm+A zS~Pt7v1oqWWWcJf0Q>yAoV)M4-}lbkzq{pIUecv@>o#Y) z)osaJcH4BWUCh~JEv!nwih+Ox1Ofyq2tbGkRD~>fQUORY0wIa)3FRAzCybwOOLld; zwQCKJx_k1X^{rcLwfCvWmXIR%6a%01-+b$_18qC-`1TUNC)>J`V-_P_%VJ#@3tStw zNbtLSO9y^7h8+?*GnanwrNY;*BP24GPWdOfS825)yk%h$VP~URRT5ukzY=E<*ST8T zxvuSP;;Augn_nxll!uHSO}QI<#?J}|rJE&fb|P+VT>I|$f2Q104Ky81wN`fSxP$+e zao*MO(x+^aAC}uBu?ovN1o3Eh%PrXxZEE5g zyRw|tc9xcPR;9^`)kDatyf^DLj|<*;#?`!=_KRz9nZg-6HdcA^u9f^>kGr(n+TMF? z!6<(+Fsa1wiP9ELAeeNOQB;^p3a~QMxIy?q@OOIGV%clmu&Dm7-Wk2!`*&0~Du3{1H1D;YMTX>SZgg-pr`?cKt|aVMoBruGQ-CW%JaD zjI@Ba6~u(#f`nm{geEJEsywP0zcxc@PjTsd+DlumR4}-6V_7?UQX)=N8)k>2mKP+w z&PYr%mcH88NlnLMEkRZe@Q&dn#>Gu`yN10Xzs`9(tXVeG&g+Wy#O`@7L&%-!b+>G` zovb^GWgq*m8*$rvF6a4O|Ix?Y+R&`c(?*l;EU!~~RX~Fb1!(wTfhQtnz-9T(<2sm1VtHW_ed54#oFlx7qr+B+J{7+s{rr@>kt4-SUvv zKc@0BKvO4zEVdm>K?pw(@6Wk+j#MG{*I2?Z&WqchpOO3m|5Vvl*3{P5S=rbt{JRQ4 zPAEg4t#?xWAq#(4d0M>3clHnhS#yPsn%cZxt0Bu(({)yu$fUEp&XwA&t@>B)+6lY) z+wTlTrDko%!s;#%$%5o#ud`9Jts%-n=Xsq*{vSp0+0!02zAT$ndlTfT^SsWY)M1{^ z!8_KPk&WBSy(=E|yR%;=!qO_;xpGIXB+Pedf)jNCVqGQv)q|!Lb_UORJMclfWsYmN z&u_H??EOQ-V;*5ykjwC$QMZUDSe z=^gN26`_(HQqIa-uR!99M!V<4rv^{yQTDjob*4--=^+q1*HLUp6ol^Whh1CrHK9pm z-&Sp)fF%Ud*4Nz?l*W~rz>ryKdKsqUcRfr_{@3|TrFCjx5kv6H&v1~h%*q<;5boTs1J0%K*S$js7{+v762zLC zmj``k{rgSGsP~7aPg9g3Q&&NWw|pVtgmPR!W<(hII*f>>m*$^Ho%qmtA&Q!fMIBPP zGzOyQho`$t$BqEa^)KmUcOTY>i<<+y~4%RbkTjWq84}4!n+MN58&#mVX%ATcm zeEcSPcC*{G^j7}#2miJk=%4h-r}eN96I}!J6P~(ZUe;f-Ybl2bMe4@5OF=tw-OeYf zj5QWK_MbukJJjsbh;z<%cE^xPAjT4Vk|1Ykx=G((l|X5%Kb^-uOzwI?Aq1V{b+J?q zrt?G{fSNR$ZgX${Z@*t>tP5m}^T|#!B7A)s?8SQ3J+Je8Y5Km7o-V=iv0Afw>8O9R z*EO#T`EkD3fps@Ket!e$8NO=<4-@YWFuF3y^NeGtrb1D63mjXG`)}&yhr0QqX)W6f zqD~QuTp+xAqzxSzhE7K%hdA%STG{qAX}=p|e0Jb($`Yj6Snn*y`C`6AJU{Q#SY3mi z@PqM>@+Q!~Jg%MTXh0NZhq;qUL;`!KsDIeNdZQjhApPb1=45g{JDM@ps+#LPCp{vm zw`xV(@^P9@FiJyL^05}an+jeFe(N0)iT0G&7}wsmPg>UFOE|uuawB$`|Q*DE~k%QUz%MLJ*WNs)DLryg`3P} z?*w2YtQBG1+Xghk)q(jI{RkTa(~l^$*groP+zB(tU`lqfGtIkN?~~<%CzVA;ovO;l zqSC6X!>z2atjMyeE~Z0LMgG{_*zH_gaPiHB(mb}_PZJSK3z!beSWyyHrWz1YO1U-m zMSD=nFg*k8xW&W_(e`V5_up+rF(5qI*h^+ZeUaDb_s2$GF8+oQGNq|y zZUv&+f>Ii*>J@Wk7*Qa(b-R>plsRR)?d(>$b~1_%krkO0Hox_}^zh2kLcg}iucj)d zL&iqu){QL=hW7H7HC8qXdpXN&T^Y8O1#}4O$gu3oUUQJ+;~wPwdb8fwW#d)v`+9^a z%Z!R00{wlIl=<`)X-pesCfdNPHAI|eUPk3u)z5xf=h zI#*$@1BFpeR+zl(R88#U_=Mse>2@`<{?()QW@i}b1KNS4`33)+)9la(C}+JhX2&={ zrw_|^aBoRo-P_Qi6K6drZ-!}~P}iYCs%LJGUdXmEe5suE+4yi}P88ZW(pgSH(`FgF zS^K#BRqjdE*JoX?+%_xRQ)jMmg}Rg!KC?8(PGsUaEQilCbLP|QnI`n@U`P#< zx+SP@Yt}u3mRJ*HOfBt)N+tT6rO8lb!d@r&&*9mWq5J4U;hB7?345K|KQp@tNgWTU zdW+GsW!wB1{t!$IHY59hki8le@gf7V(&xAKE7yK{>X1qctb)Re;y)3^p z)cx5%AGE|wmov1_Wd9J4#&4SOx;o{MAN0QGolvnxIgJzXI&VT_=Ms6?`YtM|)eVJ5>lVNeX`fcvoPjWc_waipc1kqJoIEv#{t1tvk$+9A6|RhF7l*lQlx z*LB{ORu&Z%H5Aiv@B>0arw;D1(dH2^Hy5NG$A*@)??3Z4sg}By4_Hp&NL1;0pJO9YSF>j;%k`0z zvuCeiVc8zl)uld=kc{cQL=QGmSS!vpMCf{bpZ^#BzOv&ch`_SO#1*v#@m|tZUhidq z&9q(9TPu1($e5?CG=BU`_WIn34lYP;VGbG9nCT@Yzf&R4=!F{gj65S>j4=vGNsCgM zdKN0~^$0b_>pB8Y_x(XltK&O^_9vu<@UCoaqnD(&J!?~dbRT&|Jp-O&dLU)ZuiBM0 zuJS}54Y)vbNGQfWp-%LpY_B7v8kKfOa1>H^$}2HUq0FrnYA*#-L2V#xpYwL^C}Wvm zZb*)G?9x9@fODAEm`HmG9T{{f;9tA?9iAqZ%x-J}I{&5369@+u5>kn3+9a+~+o-T2 zn`{bWUKY)>KR-MR_YquoU`@f-=N>qz)D6sQDMbU#y-SP9N=>{qWYIMnUz@KgjCT+j zGh}tDC^m>~vYsXemQc6^(vkP6tJtkc_MdEW(m2LuP%d6*%ZmqC<|oZt0571)ld=Va zjL!j;Nn_OBDL&>TY-~DbdPF)0Y`P!QSe#m;-|@Pymopxbx()93Jj?v&hV{)6W)R`A z>2=86JfHyFqD@l`4Lv2@ES98g8>xTjIo}Fzx==sNromC^kgc&w#w4$!$jf}D(RCxw z9DtuH5_N6R<+S7fu-<%tRStwQSm%{p^4lfG6+*4J`cvIFvos@-#K&{YkJ!v9=v zu=0$7LN47Djw6EyTBj->5bNs#wNCldBh+b+-#qR1C`W2DGTF}{Fea@JCmCuxMmc%J zU5&f5%dqaVEpy2%%8lGt^lvN%(;{m5HDVs7R>B%7LqJ<4X^m~pg z=u`oXe_7UfzLwg4>-^>T}M9f3P=HFZetWb6ds1K;Dm zMjB*9jwiRz89Ot4$asLSr^m!xautanH>Dni8n9*9>|;`GHu@_54pZ+@kEEr zPP399@TNm%=Q3!Xov|Q!{OX;&fzir!Dg`u{b#CmprleI^k~D(e-bS zvxob2E;~@ZHvh0OR#Fcv9eF!y-ZI^<{T^w0-S?`}$3PwPIxN5Kv0)}yX^8ZvE;g7% zuG~8^cWv=RTB`S%_|;d#RaVvpKWIrEGTk+#T6sgiNMjRYUxHmi`y}61v_L3?Pr*G2 z-E?0%EO_ewHA8cg?r*gOyaoT$Aq;-|Of->qA%p4JsfzF)ID4;*Kc-I(8HCTKCQcW& z&?CHb6&1wz*^hh*MyJk~rq6PS*>{!jIM|OrpQh1ADY|f3Zw z^qpzf(WasMZEw~ftKu&B^?Q`ptN*|2E+g-qdgaFnL7EN{A>QZae>Nu8=l@#`n&relqL+kaX|FeU@bgtL!jzOde5ud_^reJ4Yk3-W< zSC*EI5{af@hhUG9P;; zO;N_{5-+ypjl0=UhrEG(aq7XFXwvQWA;tKCeVUG)1w($4aTfPfDY%z#tSeJ-H@R32 z@V?^SdCv~?=Dg47+x`cCX~n)%z_TKsuPHbSjk>ffU1JKl&6A~GV1oANm}&0UWWU!_ zkew_n&Gee~_ht&Yb(5tYUxEG&O*UP=I8)GfQ2uX3R??2Q(CWI3tu9x$rcK+9LDv~8E-Y_g*I27ezY8v}I7rF(ygg9DaAMR^P$ET~1_ z5&wx?c^zqQCBBK~r#CPP-cM_9y(a#sDD8+33@g2i)MyHJcJz8?n(dNz4HTTw&BffN zwytNT(YP{n`YE*(007C->*><;QEa#kE?pQ;E*y*naOaVq z9jUZ0Po@F+R;w6pnL#RlOy7=R`1u+KGXtsVtk#d@SbCQM3rt^Q+ICz@W2~-rmS@KDj5;KVYdZ4Ao@G(d zg+yJl1jAbhOrT3x$b3Zm3YlW$F?JLT8=l6(2&W+tQAm**1C1;%1hl{N z7X&{=30@79zMR1ZxGc)rpfKwa6+vu-UD2axejw8r&`nujW!aBVi{1j%rONGP6aLqc ze*&YBiT3Qu;>{IVTtjp9cmz;`cI8Z00=6KLgSCoR1m++LhP56+UDuIXU!*GKI)5t4 zhg&p$_AfQ^i}|?67qf5bDWCdwDMu{7LXl@hC0kD#N%FZL6P6CFjtGG5kj4B0PIg38 zmYaPle8>c|>ls*t0*E`f6oqxs|Gi5uwpy_-l?Ji+>hkLbEovzC`tw5RaPFkM+_I%W z+N1*Lbz!vQ>yx+Ff3D^QVB7wPHi-hc4jq|@1mo?w{-*FEV&Y5 z2cw|?7OsdvUf1p!VSXKTD&-!?8fa?h0#GP+<_gDi&1q@eUc+PiJ>w`XfEmZ1-MMzcS?w?lu$%S~l46Ftd z-wi@2U_&4uw8JXjyF)vq(F6tLikI`r_vbsFU+R5z!t!ZQn1@i;VE9H0+-B#fFy>0L zwIKDOT!=_6?UC((AZ?P7gbQT_##W-ZFx?Y~B2CvqmG{)EOK4resuYNaexdbYTEp@V z8NSf#)*elu03E5;qZ+??xLzt>{U!&mYQm0tiTl?2KtvJ2j$w-6>M-M2qRq|;R__v4 zT!ktoa&Y|Q3cMc<9(?V_>=Af^To%k`&?CyQBS3QY$+vGo%N+hLGOj>xK|Hh3#D*)U?tGdTBnxPwG+-)??3pIEY0((ek=GFIo~p+M)?YWVLWR+Y zG}m-y^#B{0rhOerepje(A_B)xC0=CMegNpwAxZ%erAsL;X|LNM}~M}m`8`2Y^ZR~T^LfiGEPSZ1ZEl9bONDp z1?JM+^u*n_%fSEW>0Z5+#~-VE+~vKyed=w?O_6xU-|()ktu!zt&Q9|AS}iLb5{{#U z5)}!l%(g}0s$rG=adzprMB=yBJP1<`nO>SXf!k|#*de)Y*aEYX)hu8q=?s;-PJx?g** zb}i-$Z#_yGT7f3|H}f1Ls%%PYelhyk<@!FpbYFhIey`-tgJ8N5u+0v@D^~{o98fqw zxR}qHhS)WXWby0*SzLjnpHZ-C{P%|s%iHGQ^_C5`&f~X%*@b)7zw{UfNQICc5+gFV zh6T{%RW7HGsF(m&d?t;gYfCpW5) zZ6VVZ*oMnop$~(j>eq$@3V2BUFF((aJWXz;h&2b+zCSs=7jMt6rA9lZwkJ;m< zENN344ep&O`qGWR43%EEvJzF19V*pd&WojMH8t7AX~a{}@I=$}<%cN8mA~sVrDETw z>)N9XqlPAq#%R(i_gtAOHsLp_QZ*KjCZJk|E1_DLE10k4iq{@gLU3j3#B-(ly3_i% zY9#0QCjijy&&fQ6(7FtX9UQ-0iHx70>|@S?M2tl^_JX@ILCnUgEXfs^^ljc*Z-=O?2InXmN`)$kq!|dC5eAGdv|Wi0o;u8wnR^WvBYsBB*KTw!r|x!YHdrifKoRrboB&&0gNgDAH2>wu%F~g=dqtYaaFdTl+}`Lec*>6i%!Qir zj0^=Ga&&uyNgudaqgpElK09HiXD0a$?qj^KBcolKX&8z+p9Jy+qVQc`t^& zP9?Z36O3oZP}za-^Ri!q3a>6Q6m}5R3di$>V+;*UxK|Spnh?#Q&X(7UpzeV?;SFV> z>5)N}*QKKJjDdhbW24yu;&3G>#>Hkf*!>#X#tjMycr=#i8YLrna6S+qgwYV!832|u z7LeYt1X!L&1bkk0WMK~iW^knn%5Vk2+qXn=lvf7ZyC9%y!l8x7GNBzbgy3;BCgYPd zz?lSwp2AkLI#hki(ARke)yfnp=7ow4a>TL~5D>#xLQD-SBB+Ly5lh3>V&B#VYh$UU z3iga3L0(5Bw(Cem)i(NHB5*cbQzlB;1R-5yjT)0JEnyzEkt)iii4xs-QP8CSCbl>w z3c`~p_)(TaCLyL*DCP|c5QO0?LF9&C-SRpzL{Q+3y>vl|vN}>m@*RQTdM?pN2Q&_L zuq?|x>%}K~B(H;MBm$St3k$M@Wf5wU*B3DK13y?pP=+ggOm?`^4Kc#Qm1-!%mHSV4 zAYwiX#huPudlZG4A5~)=64f%UNYWc+s>^UfRb{vWDsH%;(uOOdQj{w+tD^#jD^(Sc zD;#W63h1an(4Mge|KGbd9SePp`z|UaXCzy+Ls+Jufp3|zAfDihsx4zPUkcuF}|sD>SO`qLQehY~q@rO`@_Q zX%5C(HG={OP!KlfHW7}px)W%ee+E}1gm&-<4KzgFizuf4^4>F~Vb5514Bmg_rbQab zaIcR&;~M9TMMm;tnQ%RpY2P#GXH&i_@{5CZ@N05elXCjbC%b+hVUz%{ZU$yS7oFunJO9 zTCIhw@r77+_aW1GX=DM%od2HVzW|~$12r@Nc5ncZ4t{<8_TJlf-^#b#Ux5FAxswwb zKnOv6)9C>vL?)-!tu2lMs>#haIVD!zcI}e3y7i7rw$knVHdbklpZSeDWARgt*4B9Z zG+=es@w_Bsb=H{dhe&mF>=Mr0L&cK%mIKm9J8*y@3!x~_u93t%iE6D zr77&PHQPvAwsjlb+FPzg8>X#*q-fItXozvRKnw-~28tQyrS;Q2Xhf5JC2W{h^*+dlle=^a<2 z?yYcoo#6gj+wt72YNiI4;ah+le_GnKiZwl{>46EPY;9_wzN_0dH6=tXa2w9+!{h z-h_i!Dz*QlhbSvbR95&|{Q8jiIrt6?e!R=t|M*%^IHm2lyX9HL4+6$is!+3Fb?z1& z>sj;uy++dh?)=!3$f+XRzy)Jef>^h8<%^0t-;6VdJKTkgOYbQ0Hd(5)v~i8+!k@K4 zwd@;jDGI5J*XtR9oFy(u-1plwog(_WrRwPq!K-I8<7RDE%bSjLRL_8z5xUlpefc)$(DiFsyVZ220IE>WCJuCIqW z=Ts$t=I`SEnn1_I?T>H5y%trkviPc4{g020wr%hqGV9HHIH?S$ZrL|Vb7VKI9H zRx^=-&MQLsi4&i!F+jv!B`v|G;2CtOif`ZdYt_};buIfv-Sci?fuL9GQdBSsy$Upj zYz>u9EIP4PHKO*#H4(PG+XR?bYxJ}6EyZah>h+8vww!wI_8awm+Or@W#q+YeE%^$e z1oBc^C<_xr#KGhX5OsGNp?!zEQLVC#1)!JI6ZqIIJ=nW$a-fkqbsRSF>}rIXIsabD z#Ui1@*|TnC)q3Gb&lpAfjjh^g+`paYIxRJ>pQB~wQ0X~zNhKv|^HF8w$HILN-AW00<6?po zF)C=@I5Jj5p=0f5-iVXgc5VM;xs}466ra^2b&r2UMtL-`~-;4-h z1`zOtDtP9^|8#PV1iYt#b0zInv1!`=<(Y3TConNc))BKh2koUfF=_s9B~%(NF8=L!nw4g=0^2wK z##XC&)~~c2%i+oYG}apD(sv2TIPu)Dl!866?KK`P6FjO};Ew;SW7bo_62=d^%1!*d zqittYKUe&lZF%wwp25E{je)v$Zj761bldwZnjo(Nid-qEkeXm)>;H$WF>59e{pl7!++ zz@)px#)}(3Pc4jkP5Rpk43&I{|3e4vexv8x$J~4WM$aYNCk;(1-~(D>=GuPxAE1mw zkoptG(gX6&PZ~w)&>6Gkv@8w&q6%^VG#ivB}g$>!{K^;Y5y!g{#`TJS$1g~6(ri_XG=%~MUH7AB*2sH29w@`Ic;Kbu4?Ys|3N7N zU|cAj2F|q;PjZlnCpUMc52kdk&XbxJa3ksELHTN6frQ@lFY{enLvYAkd0RNV<6>jQ}FH@#=m@U;NKwfr)!)>d%Ht?Fu_N zdO5uk*Ul0%CXw6cMii%BjK@kdJJI&PMw6so34%(QxANI^3G3vP|Hhikwu-XAv6#Q!R|jZ$zf+Y4m_(ZCH)&u@Ifp9<>%vmUdGx03+F)UgB1S*A88mG!KD1O?2K@f4qiiD*IUWiIC5rouwr-Y||>!k)OAa3=g zBDK^Z6V^%Mw;G)wn-LBfNSsoRmw0OSlH|1{<^W3)mLWmUZZ=N_U2<(?&OChO#X9@d zPAU;tI^=%d-}~W3s@_4Wj^56Q9J*v%ly!y2t(>nDDka}f{kTxpK`q_P&6dU+ zcT%5sd;iZy=a_{6U5TF35OC`*If477zj;MI>9yyPCUt+YsMbpFC>fTz>vbLe%EF{N z^D1)fpDyX&Te8iY=ASD1m(N36Zz;mHGj5AcC#(%sp)2GmAtc)tOXGvH8mc^kyG~qV z<_^!RXKjH?COiev53McIJ)5_l>RJC((MlwijL8O~63`_%rSD)_=4|JLONoy}}){BkT^H7mCEC0g~VrF@Qf3*}cv6N4p2N1uwN_pcAo z`_W_blk0un_2yN+%2M}M?f(t%F?gz%wjLcFbcrpJxtG8X??cY%AbIgT6o_(je_M%E zxZitpWHt0gP^VP!QbWzyo)JG+2fNJwgH?KDVb$A1+{R4iCjv`;Vz7iob14o?V2)6W zmbdwic(Zlk*;jOuQImy9bSccmiP*RmTQ zMTH1!M(&nd>#!|X5RP5QObA^Vd!dorsB>;;ER}(<#ceg7g8i0y(~6POL!-hLf(`GA zqY)!vL$3`)ASe<`#GyGmF)6|k)fF|hTlHgmqG^PA@R}O=WIVx6>*6qDfpIwdb@r>*{eMMPMmXOqM`#4AJ|FMiW?S6oRGL&wJQK5m*9V zJj3}r)t{$_$=F%N?g=tXV7gKamiuu|@mLZR6D8xdqlz?;SjBY6EEGGAUasgveJ{&v zS!4IQ-{#UBuY24c5QQJez3rb(GQtpFDjz$+Ov||s)L>H`(9qIK6feW4D6Y zXusWGS3@;=Tx`af_&3bVF##i)=!w3sTED(*p%2>#M4*snp)_Z(UVkWtsDt zv{Wv^r+Y9GdA1FddL`Wz^oz&n0fK>% z9+1|MwQF9pzIwn@tC{s-Oo>zJTPBWF(o(?&pY>~#18*ZMc3DG$6n6N+Vv+%6X)oAR z-To@gxsLa&+HA>n@z8B=7FK}=6!o839foroC8ardO2@sl3sXBngB1UnI+pe^)t@!n0K1MgKiU&u(o7vgdw;VTKUM*|(wc_5| zYPApKK%Z;#)^=KQeYO0V(rOLvkD5TGEG9kTp0Cg5nl{no-wP#6& zQUu4TfYe~y)c=|eUj&);%Zo7`uOfg5iB_>R_as!Y5R|L4v(f6cGfu418NLUxFn+COMe(^9cm(6)=n7)L)bY;{nB_VX@Jk+(tkhxtP8_9GQTYW)?=IxH0> zF1HZqXQbr?BFOeH(Viv(!T{$I5?jsK{vz^+>eTiU{OzZn#7z&y3Uy1#H7WuyIpO`jbn~_V|hBCy+aspEZ_?FWV6$8$BH~ zv8P76zRBc8KPfEjvVx4;Fz7kMNM0eeIY#a{mr|0Q zAKIMOy_!}r{Fl2o0g;u~>aj=Hw}(mo`5~_XEq19M$6xmw+bh|<$$arCdrtxqFkZ2IrZw&^(R2As#&4ss^Oi zQ4ZMGYcQr*RJk)QDJ$!aO_deEW#mnbC}`LpX`N?tD(O!U%|$b*ybEY8l0}m_E-jKl z>@C7W~?tHjgVM+y`af;AYU0iH~HZ7t-#mDd$!=NII=+J=?d~#;#5B=B^ zhY9F}6q2y|L?5Ip4P^CLTLhM?MQQ1gTFK%aG-MGrdKM#Dle3o3bFa6y=3)M3`n2Bv z@OQt(_nuMe?BsrUVZvX+GmPfcSZbC<1J{ffyG=SI&SR95osrf!N-TmwD2n6|&}(?s zBbthKZ}c*qn<#l&rKccJK1(@@>W<OInu|i(YTf`qp`+I4{VuNB{WcYYR zMVBsEjd`6q2R5l{S1ch(DA|c=FWTa- zw2D0O#9=8ELIh27itk9_R;ddrqElLmNXo>T$Y)<8;{TBqK9W2@6e;d^=|sD@vRPix z?56omHC%eIYcwvMQ-3On*#*stp8}SOk|tNVJ|T(X7+TILLYP;H)zC;Pd#A*wNI+I+ zwQq5K`2XM6UA*^E>dG{c#A%71Wr@{LF?V<)UGwYw4(V5P-Mi<-N~{1TNeh-G@mS&m zCG!zIvV$X>@!v0ucLLF!SRJCYQ&|cA6VWx=6LRLIf{1SYCM8xql=#$))2;n0FabSS}&rO;45Wc;3MBE7j? z{ZUdNZ2BTkOqae*9ro*U6+F28K>nO@%-+5~aB%UDiaB+wtSOa<$!zTT_p==eyqJ6; ziR3JaZxPLar-_nK({y}U{zlIswuur(-p}omO>ym!cHe**q^a1Ip1gM zg(Y6|Hs7C0&54e4{%jmaiOI4G=4qBB0BLgp?lgi9s7fQif+~$f2~cTPYPv^CBYcCE zMzjRz=d{Mb_D6A}Fo^C6*c9agec^FP;t*5-+RKD=0B~bEO`5yZOW(2r@sHw{!#4qu zm8P!3F|y zLveN*JNT7#v4{$~5Jjc+I1=4Zw~P#6D+XM4zjkJq=aN^3k^KVQ12sR52 z)5|>HD!R*2E@2y@PqpRE{gfFl6%z{rE+KC!EB1BU&(0L3AcX~z34`c?0WFo70l6@x zpI^tpFgTw>Fl${}b)>@QGrdGAc|{IsNF7ip`HrR8X>Aqh|9?&3-~;{p6m)Vy7<@ET ztRbg1M@7$a!;)fgmRG;3=B1n{l92_!8+ET<=0HAY#({d zTFfkS;khsVT)H#c{_Ur0z9ryi0Q|j^^0;K{?Ic>3sgR&%s=ECdi8~d5&s3e`Gk{m{ zOazvmAPbv`!4hN*fO|z$8APZ+h{{te{%5DRowQYfl*)kj2CMRXnsv~ph%jAm)(LRf zJTA2KWk(j5SakU#nerBt3ZIvEn@GsYRr~Cb^zEM3lya1i2;eQC_6LOiL4 zY3YCnLiaGk#nS2GQ}mshJ2$~@Vh;1iKOL)>V|s%*tBlqT;ARU6+^>j>`mCX z-l!^nf@o!>mdeI}U{=_`Z{!RR#QBv5%mjF023GkfMwm-Z+zedW8+%ZXHM(?d9&WZMB1|dz4&;Y9%TDvG zT93zf!yLcXpk%Na$P@ShbeC&bpV9PJ)#++|+*?#saQdF;M9rgWQXyBI*HGMA;B(9c z!uh;g2bC94s5CDTz)6Zv8jkX+bWq|islWMbXRb@mk(=7JC@F~m(1&1jn20VBN6h?L zs*FDG|7|S0!0hmJsW9zQ+H14b6Xws}!ogt(8N;1Y$4l2XlPJm0)ImQ( zva=9`LlHGU$St3#(%JVPgk86-UiQ9LQ8${~V`h6}$*2X>0?0b06G(X9oG`q$$r_|Ln#|?1S&wsMeA0qJoeFM1`RoLQw{y6T>B`vY`x&h)$P- z2Q|wK^s~*3w;vHEOMug;WuleU`ξ<2p94klwO#H0W$V;-fJdapeKdpB@w%D{k@ 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

)Y_V>6ZQaJBz&_ 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

?vsEKw0Er|2o=2Bl2CCxM-rZ|rI!IYbgk@}xK{ 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≠~4ir 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

o24o0$K#>og&T0`VssUT7#EFw+eH!DQI zCM!Y7G#(q99H1?-5MC1q=Bx}dAeG-dP(mlxe7f1!dD^X`yAgyf@OT1DQIg3RLK3)h zI}Sj^Wu;gcR1_bqg327vgNGIKRF*754*;{T%sQk60VHCY?KH6mcqa^_kDy8(rdvBJ zR1aLsDRSoJVcNX8;fmlL$qTLHg!FyQxSeyd2yWw|*s_sF0YMO;t0HvPPlOfra21xs zhTuJQ7->8gtTG~xwQU@4WyPeDDC|N)X{a2)SZw2lV;xL;p}{uU2udXK-PlzC&oo{z z02L6XjlBsa*J)maoI3RE&4itOvbfw<-Dtv=m^=X{V`a}2;L4Op5KNTBYM2-?nf^70 zvX76fZ6V*kj*DT-2p~gb%ZAb^AcTNpqCRk^ZO$-Q z2_`+KiW(SIv0+vE5RyRqHCJ&p#T>$Ag`v4g>5?Z>ToZ_Z5=aKB!IaBbY?G0oG6dmL z{s530J(2(;R1SahiV_{fP064jo%`23k&*8yMIz(0TDrfB*?U=i)6U#P!0k~Q7Fo? zA)!nPi+7zdQv^UvOCcRjD1Nw|Q7K^8piFR*%JDNl-wN34snM6O2dPr;WmJh~zH-%p~D^0>&vh zfN(|-I29r20TyqmL~02z;DTtCd}shT9F7~!u&{z8EG7v%5T}rwC=~AsjLsCu>@~t5 zHPx}9Rr+v}Ns5i2uSba-U zC_!>8Hx?}B5FH}mrw|{NY1+8qqDl_Ajw{i1=$SCv*1`Eua44{tW=4sv)o}cQcSr~k zxP>rPBT9ZSNv8yhEMeT76$v9ZJB)lSWUyc1_-w|&8Zz)HWSCPt4VyG?fnM3R2 z6j8iY8l?CcKn#sazTM&$GE zXDZ49%srLIPQl1HtinLeqC!-WJhFS}G6s$$cma>5T~~wQd%W=SJHP9&k)V0cWhay` z=jb#l+Zpj*o4>o`w?@lk%-6}M2<~G$em0!%Eco=Xdib)G?J7fE>sHF=c)(uCLZn zs3bw?6bwPM@f{t3>Nv1qO*{M6^|Kw3T!%B|dfJpFC_R>GDbzvBWZ29(5@Nlk(T5DrDn6%U+_Ls=q`mifx81>I_S$>6E+S)Q>$>b{ zIt~yR=9S13fmTQ;?$9=v5-U%o*P2;)cF1l>8f-U_3`cid-P~TJ{E3QF>MNWRUvZRB zi{#nG;Q8)NXnZq9E0)~pV}tKT>R(WZ!p~^&k8Y<-mk2e~5glPu(>eGQj7o#*$-LYl z9JK&W)tKNo0ypYd5wS7kbF{T_?F#!eZ2;n&`YE@(Hi;JLzwerF_W-B4pON! zP>c20>x7a5E`eH>+dF52OxkKqtb+K$@R4sMvh3&zPbk(BZnX1nydJ%=RS*K%zgNWZ=;tyeGH$K zX8IZ{&kCGAbLz~OqUcm82{-BO*3@;C+&?DnWhEfx?b!kc{}Ak@45e1g6!a;vIh~+iNj>k1M^2@$IhFbwAs>I&Pm1W%``^@L zLnT@3VNt{ce!OcZX(WwdnEB|ud?^(d!6|?g*I9v3=fRDcIt(!kbbe+7Dk-nR)Sfb>S>bu_%icm6U3MTT^G?oG7<=A7a z7J4gFit^wX#UN7obo9nKyEK0Mu>K!WXdk-AviU(5r z1ZN^Z@F^hj6cc**du#CV1cB362DysCUw?E-7jK!Q#9n^oyyJE8|=cUrRaqT@K12 z6_a*0iibeFe2Ne!pJGG_rzq3I`8b3eIEb^U2DysFw|Q}PuS$%c6a?P?!xm-UidcjF^OTTlM z1Mo?m208b(07JUmos?{SZ<26Oz}|a9XB4sCd6IQxRX#GnA;AHbTJ?<6MX>cMc_dD1 zYI(~La|07E$dqd$nj~FFF8BZ-0su5K09OYF@AtiX{_pMX_S)^;ZM&|kZP#me(~2&m zF4U#lx75a5+{r*BWMM#Hpq3N~MJkvUpg{a8@gw{QAcAIqLRdrqppm+fjsS@$00LwD zp73Kms|kfYNrz3KuWq_lI>;Lha||x}MUP!!y0~*bJEMmc8{DgK1_16N;XX&7v25XTT1cfDI%tzPwdSFl-MLiJV0s86Y*qUo!OMqRnOD|F&=bWc(f4D?r3@y1ncZGCl( zO-)5TA}gEeY^VCVo*ur{O%?q#t}R=O99=$lQ&c^u1AOM98kVRUx;l@)JE{sr1KNO1 za>UTwvUL)vVJ$%lrPxEBS``V|sX&sif@kax+uec|vbGGuV3sJlZ1(_5sFINX#!W?q zkh3GPMrCY-kmh(V@~!k}%h9GkqM)g#YSVOSRFv}FBfof}4cplYeReDBo=C;MZ!j%J z9R#jze-GHj^eY~OrVOBNOqP^|WEnb^%;U*p2T*ZvO`O-ZAT99PlM2fI+GmK50UzvQ z3I+t3Wh>*2qBr^H;7_ABqwDn+tjm#RC?zt@BD*`C{4}R>ZMJHQcoxy(%RCojC7s{WV^x=Zni9( zPsgEOZmIQsFh-{a(?j+B`5pkQ=}#11+wK}X6`eTS6&m}p|Ct*m^8>6Bter7G$u1U% zCjFRdPdKl*bTTHMi;kKE#L)>v2)97ufIu3i(LyduTxt<;aL;NmO!(GOia@R&?FUQC z)f$H{zC(3w9`2o6j0}-@jP`?zOnTL;W-+rBKY^wP zq@V5jqNdT(_Q^boBdASE{UlEZflrN{v}awmzsA zGs~L=d0aF!3YilEHYbFG`2o&X2CFVFHId0}9pormk19e2S8mhKkkSGb?+pHJ+% z0x8Pg?w787-l4I_O<$*bQlI~;JLm&X=Jx0+t+1k(W>{&^$V-ID0*5W*YD$Q42FNutbne^@ZI=!KRE?daO+}31l?Uc%;HM;TZ zF*mhY*(xGi@D@?1$5-LsNv3I;uXm^#-gcAcLN-eV3ON7F;nN2lthvsN43iezjm8m`tz6?=DG@jcG-<3n;6cJjob#z zyQQ+0ELuuyX-WB2N<`~oVX!MOJm!LW1*#r*0ffS!xZ9?&lR~r%Y)fZI*^P27{4f?y zt6GvuqgEt*sp7A(ZjVPdhzmA0y$_`?8eHFf(OyvK7Q>t~XnaTvPHJ;fnk-pd+yqWS zP24NdAyXf{WKdb{Q{jMu268Z}ct6_9Q6DAT>uq2@ylvHA@W_(K6Ve7IB#CkPP=EuG zxxXEXW;ecn)pKi{{I&+g3bS_ECL?P`t`v@^VZ~IK9SM8J0e~VFmk}fg9~2UFN%8+S z=}%ehtLuiN;V^(P{i7^r(t_&lcbB^~ewdhyTj9hmXw$3*wp|xDrYA7cTg0hl#dCil zF5Vsxv9%l~PPz527;o0o>s1e!g@~^G9vwTrBx|a7mSRws2=icQJy?mVR;aPdumu8v zESg4IVa2%ASzNV_o*Ma3TOq_QD00ML*08l%#pzNWHo!CHjfI+gf$7_laRkwPio6j|a`iFpKPiOAno{SZ_|3=2AOEaq`6S}4TN#)PUmIN!dCl0mG; zWd4T)E7Sg`qxMR6XQ_#w&zHAK+7OkBr;>sJgM z9#{8EdORvv>~5wW&;*sk1sMw*#+u@!Ttt}6_#%{{d_AUW+?wAO2$1W)#ari0ZuFkG zb3Ne^?$%L3&I(sMSbp4}qux|?nLB}c0&?9JkHs|Wqn>e(qa)h{EQ5Gcb2L!`#}w2S zdWCpF`p~+?u%F%rW}dv0uL~81#axwcBD7SM)OTu@bR%oPEffpc|NHvgAS=A#tdMxVH3n-*=@VAo`N5I4<5tSYe0 z2-l%TF6T1z2wv!ugZFhye7n9dZq$iseb=YqE_9lKE z2imyL!nRd5oHex-X0oE<5=sxyUX&~chu5r=xE8xXdmFk95A0wa#+PjE)mUrJ>}X@2?gwwWn|IG)cuU(}VML3T?9H zj3WfjjCkYn7z9kA?V^pftNW%WcxXF8CM$l~At>B!K3I;I1++$PTxUDdpOk1=tu{DL zQr3Zc5|dX`t*23ceb4M?J-SNlFbs{wn*nkp$qp%jgZNpouMLfB8;XgRs*#V;s0DrC z3fNmH7IzpkW$p1b(72RHXf|*|T&^PR@QtWfsbo4ybmA@LDM_fZD`O2==(j$eS4FzPk_lD|;BS+7X~$UlchS{=Rdz7vJa zo3q9mmOpTq-enT7Jl#o3!uH z*nw95Y53Rk#FQ=69h~gZhw>x$huJP5YnE;(=|k>mnzMF@3JZ7Hh`(~Y6yk4!%i0!)d0PPk z48lWMxz-9u7xhdp^H_1oAoNY~*$Sz43xV!tgOO$nW9=3S+s$>EbacYZ|FUgo3Wvwp zYNynUn=SSjm!3(LCG2yIK0Ra4z2_1`vK5i;g`1hP2Vb$7@?>~;mbPYFsMuYq@`9ej zo_&uJaAs=z1FMU<^@mR?wQv|?axgO&63o+TwzO_t*WmoU-Wrn&ZdItdnZrHn&cz=~ zSG)8P8@;f;4Zh5D!n|c0+>XrKvH-=)ciU$={^r^CS?>0wr_WV4{1)G-N^e&(3VDW* zr&Deei8V;N8h0`AQrm?lEP|u0l^&FYEhF7+S@M?heCZn-Y-#E7`AgZQvb0ItGv0>5wHaHNZ@RacrCmSuS?1JU zaLjJD^VTdjv7LS9JK4-%ve>6~au(XjRoo|=g>+xVcCxsz7Oc}w6&J~BqS~zDJK2h3 zWWRpx1uGqsvAKsK;~ZdRs=rfeS6yLa3;bNBFx<}Ld=vStSb~IM!t;^st9Z`V&Dj9^ z75!`-T;X!L0*KSmY0!%L8!V>Bm{(dx?=2emrn&gDjgLJ&PRn=j_p4rJtlc{L|EgEA zYb)1q4SKy5`yZFUGq)$<$gB5)r4bale_~Nsw8UEa68Op!Ofbk8et{Mo7P>KQBZs>M zlN~+OGCwgou&Lj;W@@i-Yt;Xk$2S29N7445>N>%o=&o9Hwk|@?-Kx889aS58YLrm4 z86~$~cGERpR|C7Mj5AkQFQyXpv$`5p3`a#5uXyP>14M73O+tPM;eQgDcKerGkz=h| z>UJvl*ZHBw(9?BPih4UH#w1gtq@lp1K*mivM@>9SNm=W6s-M)J&(E`5 zT~}X>uOdZ$(NTtU+wO&u=IGT*=Frvw+^(ByzpzxZ3k&O$kQdUPOUL5^8* z{R?WjGx30pP)?C~s#=leZq5ekr!%F*UZ;8AGGO4Qt zP2(D;w{K`5H9LP@v;))J_ZH8=^6>Yb-}kP7ss>3}8c}v7qPIKU?;lm}xnEE97Cm!w z&|o38-tAv*N5IPjmHrQ=l$=b^yOy82e&C-0j`GDJ?`?bdUnTyd%@^=BiKRUMoO8G} z6hdEr4^=~ugw3+y9J?HHNY<^FgAUruJn}<$T5hk#9JXZ?M+JY<#!5UI4Oq&`*-P8&PYSqTzUsZ&?3?J7FfV?nE}ObWzrI-LK+AFPaH-L_2D&p#NoGyl zUo)%~=8gXx;xp~1(s%CLt*;fqO8WL6+V?-*E-}JyJUcMSxY2M9ASMlGF3qP~I=f<@ zGIU`3Ea0s!Bg^IrsYb6y8D#85;@AWda!bYr%E%$(1j%*D%5CoEuP|kv20Ua}JuW=s zKdpJnmc*NJ^-+YKgYWU94n`@B)zwx^fVi;iiP=Uw-r}2OFIjslWg{$ zOObGN6BB*EdX9Yk!&)Uni3x*akG(nz*jhu+_-Azrq}SAEeG#qez`vX2V_dUdY;kg8 ze$|cD9&GiAUiB9q6@zL?Y^rQ4mnZ!zzJxpSkM+DwA}#&4 z2pi1DVs|Drsh>3LMO`EnQAbdN`NJ&d<&J|jK9cwk0M3j}IORE#Qn8gMabfyY4+}Z& zj(VD=rKg{y$I=yzMMat(LnRnReszB;9}OYngwA>vd7d-j@R-66n1VlG4~6J5urE1w z@0I7BaOU?3|CU$Dnt=~h@+f71hb(X_m4cKr8Cy%8%xclISsMQ)aW(3qHL92Np6Gw& z^m%)3@SS>652tiFw(%VLu4nh|HgwMny|=HP^C1)UcrNGvnfi3|W=lj0Wie4GO&Sd5NvzD1cHxM*?#$mO_g6=J0T2m$)z*C(~$2jMNM)0zpY7sRrd=U+yAt%#}%3$rEatZ%mJwN|4(@XB;Wn!U6 zNoU6_-RcKMO~d9>-!&1xdSdqm^7)fT+Yntym%|qT$H2bbLO-l=BMxewUomy z!vEvt;XZjF_$$(|JI@z;Apys>yol9?O2#k|8Flen7 zJ#3|ge{*F$#i!+l+j+0N)=7N7?S+-I$_;~;TrtbfZtQ7JMRZM0PwZWdAIDheLzC9` zJzjG67@Gq^Wt`_GYaYUk>g0P!mh@qqey@d=7JMseT6JKl=AZCfm6EImPjg_%`m2doY7Z};q$_Q?CiT)$SK@0-Sa zxia#@N^yQoEIjuiok4-Y0gO$;Ons!ujnlc9QrrQ-C>sSO3^;P5%jH1xT{#DPR0I17 z{H?5{Mtzt^!usmR$92`6>5GJj&T<09heNnNfX}A*7?c@VE;;!|EEDnoIGOSB`CqeH zF@s>+$M(|uVeimF-g&H?E*H~JWN&%tCP-|fyQ4H8j4LS9>bx>)aBj{0HRX@yUm`a2 z7U%Uo-(McLYI_!XyK0YHxeMr+oUEP!T|jhfne||N&4)*QIRP0&8HP#NMRNyy#LnUp zoT0^hQF&q+mje*}l-I&>mYKFN`+mn$=-BD<#+OA@m}URHM?Bu;JYEk=(lq~e?hTK6 z17ReGs_YZ97$&yp*mpq?%v#lmYQEJlB3CM>APXjWvtO)ttUm-Ay~G_|!1xck7b%wHXiQ@|i3dl8Rn? z!y}qBBPA@${fDp1Zvy?4T;oj+Yq`pAsf0Y$G`_h2Rm6uZoDpbi)5!5?;LUGu_CI_Y zm=~`dk_6-+E(;|QD&Z=$2;;BWzMQ9#fr>@^&)6m(%iZ+hRcw`2h$9ip3{`ScTh&9x zjI!x`PWT@><9|8c`)>W00%rek^#~m2{8~eh;#9~};6K;S7a2L>@s{OnkB_r8%^Q#V{KrNQz^?#aK%u|! z+*Qqf@1RPN+MlD(>~BL`5oK2?RW02M1^E+B!$O@k<*VMEwXcR)e#}8lPw&%z!f!%t z%LDm0UDx5hYh(TD9PfG6cXq|o$8q($*AJVPgs+Qc*4I;)gvO6m!aV3-JK;XPViB*b zwD_vQN7ZU%^F+3(pYCM#R^PHCKg?;$?lmnJJu~$h`g1<%GvQxaN6_z|g#ToutkN~S z9AksHN0rs`yLKN=9BjRY3l`o6dR`-36pvA#-JYkXqo(^4{6IhZ=l2D6y@GD0s>vIE z`OGtf@BJkJ2#AJ*$v|EI||IQ{t{8eGA4_@@Q4y!gv zP1{Z6Z@>awH1nUdag7aE|C#OWP(dn;n&M3p ziUR#hU~waJlR7Bk#F3Uom0~NvNflJ=#SMj_=2PT2Zb;A#$k-I^fVHKqSpaDx93F?5 z$*FVXVcIAyBfyoy>lDg4fr%KnQ5X>^4h!SqeM2#^$iAtN28cb=3|UIcMb3<%1*fTv z4B?PA^t6?oQIrfgP7Q*Ymat{~7vGH#hi=;mXxi#xNN2cq7u9yX(j;l?&jmI6l-vxO|9 zw80$nMeU>Tjp+r->XrM(du_3Xh%Q_0EGV6qY?95z06|jpvCJS4GS$oD#Vt6Bq?QV+ET%yhBb~tSZslZnMHmW$Kma5zAnYD=~D53K>&Eu)ERgrsbN07(!fRFFpZR#LUhj4M&YaU=x`+bB^xb&SnF3|$twpK-^tQn8abCHyi6 z;P{*`WoUHC$#WhZZ^r!4ZOT32SdI~tHiS?h>Q;u$$5BlpjF~E3Qjbepr-z_;;e4%Z zR>`(@kY~!RITX1{A^<`O!benVlC{U6X6J|1&9^OGl@PkSv$;1YP7FWYB>hJ%Yf{RIwle*Hf9Nw zq!F$l4Ld?xVisfc*J{FwnoWyU;MT&u?x;%=Q8&4k&@) zURavXzXyy30&S2Z6^>Y`Q#8V*VfC-+>GY>s+JYy#aQNras*h#|Ysj2LLJUw+BO$hT zaK?pAUO!tXxC(r&^MGtYLhL;zsW#SVOO6U9Q`!bvQwyHmtf}`+ORCjWf*YeyLB$)@E{VsR_ltw_-)E*& zYW;x=wV1OEbJ!s%I!%mu^ovkj~c;s4M7 zng4qFk28WA`g$i1{|UnS$C<=w=sY|>PyDIb&1vX7+&?e;p_$EU=skR&$NtW|W;OI4 zj?e3V>25O`dJpgCc|Z5dnGHRMi+R}3{(9y^&*5jo>)-rCd@uugre_=75B_=PkI#5< zL+|1Lyy551f?DD#URuZy3J!p4G%Z6y9b;^G>~;*$RveZs^!!!tF0&urzaV-Kp_t@M z`8V_)%1et%ZI(!=U>JxxS^%06+GyEusAfig8b2c&<9DuOx%6xT4fP*S@l9ew)IUU| zzAE;|lZnLP92%mcAt4$cqM!RQ$WL$a6ViKfB`G%x{#RK2l8DGJdvBaw&aa8cZtyb~ zjFuMT+r=Haozi&3KUr8t_=}bc8w9#GRLO^Cq8v#Ua8raYvz@mvNlmRHyv})=WHLRD-m8SUoV@Y`L zlQ;IKjacIGYoZmVtO7x#BRI}L+F24YpeSJ4r!@62rE&-3SZ+pX7iZs3l68H_F?lf} zC6j%7e~Z`{Ch>);cD+c`nV>8XU~84ZWk9s?48oeUVj?Hzi+z!)7=P-t{8--q9RFgV z{xB(F1@1Dj%wL&|0n<_@>f&pcy ze@16bt7?~lf82|tP z1DaFqeLl@b?{DHsZud0HC3BWu@J%BQKT9qf&`^t}=NY++~E6NVn#wbe_HtYVBXlOK2BP_Qh zlEZ)qaE+oK;^Q*D)QO}WExf4k~&80;lHosKTQ+Y~Bmn>P_}`3pMohRj-2#=WVFTf)AL^Ya#%}M+a>EI8sGWuO#INADcyeO z(EU)tc3p{2c2EGjrUjU7o7o{<*EH|Y(xSNPKkwN0X|#%I)2Q&|#rFn6(!%i|?Whq} zmVIzWYA!ewSlP^Lj#|MY9jK0SKq;1>rAlqEr7C8%Pf`Am^!DJNz=&7^)1_tRAVPZ5 z2}~2C+*BeWaZ*osk!+x03mq&P#V#eEzRlvD9c@Y~{uk{vUA^X=+Ofo7ZA-K$Ta;G# z14>BKHX+Ae#5T2^5S=t?-f*^rg=eeMVUx6hX5;HfVlS*{iru@nplAfLFKIk>kkhSS zK^JOvGpv}N0LOTSLKLtJ<3R{n!`f=dH#i?K-jeFBzLOPbpnQffe)O4)X(h&)s?}|p zr3oNvdEImq&bm=Z6MG6Pe$Oyi+w4#Id7sDh+5r2SMr~w?5YRH>031oAhpE9d4m_HK zS$mGFexi84&w%6jSz$ZKGZ@n%A!Lj-OF+$ZCcPzzGf}`$G&C70ui71G+pe5u$GrS* ztthOGd_+4j#|a0L*U5@W4|Pc74(tv%rJhP{-;9+W{2nEK!l%Ci*vK@_Fg$RZiD#y} zm0Yc@+~;gEH<#K2VaW>N1A}TxUjEjR5Od7;$Ua(5FgWpTt*X(IOG|j zu%at1kZfw}ELhuWoGziU(+Z;y(XVY3&PgkRLxbQg>}47fyea_>D`Iw@McbLm!@ONT z)Rrpr5E4+!gV7Ll!Bir;rIQ4#6`XOA?=o~VSx&r zy^K<#GBjl`THX$IJ*qhY~Mp+(@vi395_5 z`cGVuGfW)gp;CA91SFI3%s9_LAp#V1(Wwg(hhW!F+wQZVf^1)cVU5^WZ}zPy{r8U^ z109kK=gVXT>eeTWzP#c-!aKao1n=rgCCpURu`Ez{>I+8kP@rfBS5ugSqgAYnt9{!e zj8;q;oxN3K;9=~8nP?2@z+Iq)&>cMC6~5W z|KyaiA?OYU;ja=SkW6$0iE1{V?nsa>BJu9d3Askv*!w0>^P=X<%U}Ly+b&W4T4GM; zc3fZEny2^bX_vP+2_p*q6VI2a-Ma}0T1GJXM03*Iq#rlWV~u9Z;-fR^tqvoAn6r1F zA0jtJF#|=S&W>6M^4g%T9v|TX2H`hHOCk78oJ2CG?1kz$p~HKFm4&91D~v4Ex2qP++57j7Iq4MsXM^)yJHQCYA!Qd)6^3nH6bA&G0xNps>G?X%JI@ z&UfqW$9K_Y@l*c#toR`E=UkngpXzwhJB{G@B~xEp@Ln}8yABvUGv*Vt1h0s8EX3}C zs7U9+V=_}V44d!3oin`71bni^4-8hti9l=Q2D$tPS*kbgZqPXt#d!=Rh=Aj>Q;WMk zyXW^7*2IiZq;Bk9KXR)N&DNVFf>q8!G=B1<>6sk;=XhDz@9oUn#p1M_CEbO)nngN( z+wdqrWbYCY2tzYZw5&`>YG+h_vXsE7+0^hTK;9Yb%3*zcs{Y-J!uhF~IZt_Is1zHX zBavt=oPWxMm&fk%^X!l3@vxn9y7lj0!uOP>uVmqLnK;RfzhS1tFGn2EX^_$=s*gr@27L)-@b&mGqS&9;aqYgu%$WX91wG;q^WtOYA6>;+sBhUjjummDC(|9V|~)O zVcpx|3V3P9ioh{C@UQ{q2K&`RWK1cRO9qrbp6%(J{y-OCAKrL|E}2hGc^zo14mQlm zzJfQ>>@ziR&VOhiK=%|rf2mR1+2Z#GC&@qqoT)a9(z?s@>?CiGc|kU&>q@($xd4Mx zhCliXF0a9-tVud?w?MkZDU36!+=HeZ1S|9=GR%#4IcSoDoHW4x@S!}rdOnHoKQ^q; zL>qefdq-}H{LRs1j+Z%anCH6d)Dls zslm<@bQTlJDeXVcKjrUBgD_HSeM}=eR^Kui4CqTQMLwuu=GRn3m`N@ITu)2;^e(tQ zlex9j+i*2xwq)p!T7%EXaA}@VZfluOw{9iS12qZ9Kj7^^y3_h^=lvfH!*x6ibviE0 zuB`Y8a@o+CC2c!E;2i0vZGHJ2oEK84>G04RIhWxRB6R~nFTKP3gk_LxcW3>eg>8n9 z6aDF5|5OL~QPE9jkY-OX+xwZYgc*#ww6;?!-#pkor(`q?o)O2|mZz-!^ru|X)0fyo z;^PEJ!;?q~bY<#sk704>L@nm<8u|5S+0@uR_fwwq>6w0!_&7nC`52yp4l!v7J`e?W+R$5KaZJC^vZaXw~=PS%xPfnc>%e71qDr*f;M&5 zd}H$1JKm^zw-#LA(b`*TayM>ZuuIr$2gk_mqWdlZ$Y%u7BkfrrZ+2RGJ35P;_*JoHT?2GZp_bjl?^X&Ea<45TyY$3l|NbPo9`;rXV`g~6;sKiw z=jFQad}%Iu5j@v<-8`d%|1{5^SMz@x>n4}D-Jio@pCj~{C4Gl6KqH>4Wb8&bnam00 zDOvsZ%4_`gB7|T6B&pX$mS(bEoNJ~Ko`F_PdE2RnkXci^A4V+hq1FsJ3iOIDo)Cg3&%p2J4EgLq^!*&TJn2w$?$_0YanZxke3D77crvn-AATNMSI>Uen3-^8q*vM5+K#8oKiBZ;3$YFxPAVBKRFO1G?^=W; z_rK^&PL+ntSKv$BUIQJv9Q#DTK&U9Ui5-mWlVVo^e}g{HT?j1Gzy1-z+{p7kTHv-D zVLS{cb6_F5eR~{@FWO;R46(N|=(hO&i5Z{#vpTp`B6?Y-Ix;0hf<39%j&OSbc>A$R zlIFRUmz3)Z&_0k=XX$#>LaJ-4DtdNJ?F?u0@4-)1F1zP+EBt40^1I=V+XYi?$B+3b z*fb*@Wo0H|4i#p75;a*fc1Z6UCOY1e<+GbSqmo_yF*1D)pJApj%Lm{36a3Nqog6Kp z{kJTQ66QC@Z6=~G%YUpdNCkDKO=s8t z5nzn;b0=_wP~7%H^{RAnIoCYTAp!Fy*<<*5IHo_4B6%AgdkEs51*^xKOt!bhSS)5e zappA1VtnXHp3iv6CZ1f|FiR{;F5wOTkv};9&_V1M3UucAc*X)L9*DfLk({AmNL$aJ z;|L)yb`R<>$9>}&PesRP^D_1FXU!q4H1Wt~De)rhaG`zf_-Nn&6nRt62ysS20Y8|JY2;b4!Ny&3CDq?7w6C2lgjHNATTL&vom25MIVy zZcF-c=3)`kR-e#kcC?4|%Q=>aS;a;sGeGaA#x=pUV(r)=`~Y#0i%2ah9)!*mP!m~ofU?77~YY`4G&H*$?rXHDhG#A5Tt?Hlm3CP+*av=Ypf@|Yd z#3$KPVU%uONJm?R`@=c*Z@mSx^^b1i{uA}yWOTIO}+4MZ#(|&<)K5{TJl+Y*#ck6O1|Cu-}-8nP7uzO_q82(A?arRJD9r? z`ix`Wo%e0}rNwDcV8=0QNo9&wkhWzL1c& zZdAaAvoN!)9qrG_bK+6xC1}EOToz;EaRC!&|2!2PuyN)#(mYT$PL~oiWxg0|CEGf< zY=+Ms~uCDvRV6(gCIG!e8 zQ9HUZ@t3Pug+8jc7W$>t2P*9L^=7itD?AoV856eC4QnrSS)P{63A&V44Zk)fV6v)T zv$I)i*VXkXU&;G@zKwV4ubF}J-`9m+Kzz%KsPWbeT|K+?;T&g@r7ZDT4vA!fFO|YDs_OrL!vhZ6v8GQ5k zjy%J&neraAMXs*G@-2Ad36f%4pOflj5iTfQ2zFt4m9Cf`~q(yRM_PO-p>6?F2XOO)@8@eYZKTy!rK5p6Bie`&gmQFVCDXSV*%*8ZcH)e(-tDpN;9y7!u#1$^+-h`s!d z;DbJZ@!yDThM%k*4`MGo?HXdO0`jp^^R3?5sv*-=H0o-0>%2ILx>+yOsdZGoH61hG z0Yx;mwC&q@_Ro+Xm}_avyseB>V}Bi-{C*282jlvtL1VHqNXN4}L>+2lAAx%yDxoBw zj1#(yC6D6(#)0mkXin1-i~eEs)FWk;lh5q9*8+dPmI7aWaX;vRbgnqTGJs zog7`pIYu#2w)xa{c!jg|exM*k8BFI9BltuVOx*>xUy8&F&n@2Qn;GLP`8nVQiK*dw z$g{KW#9O~^jd<|)+djAL!nAGsPq3_w>v7(+7p%aQEdY-75-c#Tnkd#AZAr=C{BBoj zm#rVw-0E!FwN8zyvcaeFZzB)A^?jB7j_$_b=ZpiK1B-yW*$O<>(;mgxDKHu{(6AVn zU>hJB3}E%08`$M%5#>O^18jqYfNOBR>j3t=cLU$n(S?8p!=IMAm!0fMkOt43zY`Ph zyl8{pKQ}1h;IhoF;M_m(&4JB@&q!=&Ab;Iv{Zx5+s8n9PBN;4dvHP*eU;-E(xfUjH zh&OTTkkt5=xSjn0#<4?U)V3bY8ox)^tNd!3GG4EeE9|-zlH83f?xd~a7@{<@{XR5& z8YkV|&4#i)lrXLAOhJHuIhU0iZe~u9Th~Mtd8-|gpZYezA|;rrgU-3%B!Y3Y{R4mP zZ~#3L`IPDY(Xn5zt7hx-Z(firpNVOUAj>M$h-MBe!Ne2!}J=KNuB>> znV5#REA`DcQZ2FH#A&<9 z()LijlA9s$R!9ax>%e|{VcfZXdeXu6u~o`XE&j5vly`ll`|5k8w|()IKBX1*$G63P zI+dEo-ezkrY#@zQp5vF)UN3V3?RxdU>p086hZ5!Wkq)dWP+u}yz2Q~f3z?(?cj}sD zRoS~@rM?47I&hZvIi#)cca8?MG}|Ag;#5ZTz)LYwI;y>2R_ZJKq=BJ+=_HfY>&K)* z|Hy|1V>t)0)uJHxvzp|rTec)?DReMQy8ag{?XrJr(iJvMe7E=Zgz$+sq;?Zjje%oQ}5oULj9#@E-n0?bHv*SzeO0kL`IztXHmVB@ zPDT=u-mOmqr5?+l@x!YrG!x|zo}YJ&;ad1&`Y{(@B5zM%N}m@~8ov-Q!1Qbr_1rav zdXi0Hun?Xu1RQu=!@SWF#A7?PA`Q%Oe7T$RwF|~_NlUW{>a5?^F<`iPqF3%?U9#vw zwiVvY?`Ng`jxd?=icQ@l$AWMBQ;7}E zEfy?p_3Yy@z+v}pE+1tK+n(XY^sK+QMyiG--EUnWN2YYaQe( z-UM6m*J|*@?+n_R{-Hz(@5s>>rXz zkt@Htv+AdvLN6$(gL|xPb5UsP)zQI**Omzx`p<>xL~;%QirZ z7A{HD4@DiP-cw_$3nuEULtNjz5Y(rb`0uS&HCVbvSZp`=K8=l=X4`K+xc@8ZA03!ZfFfZy6jRi}&3N$q&m7wYeSr~b=z zosQVaHZ9w$j(JFMsXra0RchIuG*r12;$IbIfYnvhds=VA@#);t=hM|fWBYqrFZ#xt zBmLQP7dcLvJgcY1@g<_VR^e6As=;!uf4Eg{&7P?ww&j<5>bv%qGiLoA#8eks&9voJDQ*WSu$^Oz`rG1!*@hine{XB75{KazO^?1Fz zr3TWli%U}b876;Tp#$H?KZnh}#5;hQeAy&5McI$wH@>5Pkrwz&%x9w|QR z595l#GIA{1+?UH8Y$q4RgY@yehH7h&|6frnlqdUH*-s;cL?t>&7QOyw4En#YbO_wZ0D6wL(ut(kCG>8&V!3fyuTCVcxy{8x=%X{2Pu*Iym5Vb#2t zG@6b9@4a5@^%n?)p0+zP$ExXP?%8qTxRhgDL+7DB3Lvs`w*x!^gjYKE-McdmOO;r^ z!yo9cg_j33F#_fyMvC40jTD?I7)y9ubD&|pU*}U6i5}=zJ$s1%SL~Xhc9*}q z&wf>1bL;D-aG>veAKN1<=1(+#h}h^G+5qkw-(-I0&pn$6@w)euVe>81RuXn+RpMRO}(7owspZzKY7QX_S$+UO>v2|UAD(@yw zZ*cboc?->`rtJHy)y9X@6YzKzxVB9?uulMRY?+e?~}jAf`G1tE^|R?(ftSN;?kl*BfQujKZRLnoxip$N4y-kFVTM{o);!A z;AMv6d$f0sDhszByi)9B9R?Pz(IPS(YR5TrD3=t3|lVBmBldMTwm!*u~ur}W?fKqPK#wI-K zCJ+KB%)_K)vBE7hF?7{tR9qxHPYNZmaG{`35FB^6%9LCHXCWnlF-K{B$A%l+M6r}D z^B@T+L}M&h3Y{lIjWy}7QK_u`qr~5s<#|EFTtIBp4LZf~n2{K(sNi#tdioWhj;`u<9yWPP$nHn2(i&zZ-+QM-$8?Pz%=A5q$$sjC)K6q7h8+D(JEp zz;PENnM@+N)mWrr6puC6I0+8U_i~H4SWv=-B*0KZ+}63M1yg`>0I3DSP|ldq1RPWq zZdM{V7Li^!amAyaK#jUsf#gQP80iZbI)tw*0!v&}BdM?%4FTNEs9YfoCPAfg*pab2 zTsi8(jboxW4%d*WIRjl?XE_;2Qvhe(2 z#9cOG{Jhlx1W~DQMVXKq^*_7Yh!I)=w4J(Y#>P-c9i&eHS4YwV$wH>;BPurcSTSUH zLjg}1LV47f!~~T{vXlS<5Yv4WV-HmtFKNDOO3boU%*sKyrseT2u*3@gbz|}g`o>*c zUeFK@v<|#2dhHT7leJYIYqC z_!v4a6e}u^WKIcGqZR#+9quj6N2>e^-onJzyu}F+I)t%6V3h!gxipTNG5@20DipGL zY;eKy1i8-x_$YZkdXhq8OCasWql&4daB@aQ0BeckX(OQV62&c$N+m-r?xO}bST=2yYov0`V30yR>jGfR(Ai%-kH)L@LB7PHZgTdI<7$)^c&STwrpF8~`cE zVz!oJ5kxylg;Qi8^r~_MLCQ}@m{xO~VF3xp7$uo5kgN29uc!PBgBH;x z2L=xc`J@|4@^Lywqv6Nq`*R`1QfFOxlN$1J5|>xYon<#;p+a;+||UA zT8P0y>E8b*3qvF&9p804HouQ=K`yAB5(jbIXpNdwkFEUD2&S!^QV}v(3i4F)941g5Objp{S4IE{=OCAkU=$)mNaFG*joAg!(S^~bH&zWz4I)r{wlthVB&(lw6B;#1AO)>-P<5s&jTo+@qM zYStL|A>_=Ov8dw&gh2oR2mk=h$bc1q0p2@(_xA4F?(LTEyK5Jgby-$51t=ob&h9Ne z>{(X`ZfX`>O(n)al0uA7NV;Urg$u2h_!aga6{5tii9zP2({PJ2SpfG)fB;Cx|09yd zZVAwN2lAd#3$Cr$+iY2E?O3*2QPvt`!)sl!wQc>4z1ya1+pQJn{u5}m15y8mjeOJa zq1GB{(`jUHztV}V8yom<-S)EX-mzJ5nenK;{pF%I*Edpbc8z>xL|a@g?rW!o+3>c0 zZjm8*cb-7F(Qk?Gbo?CfC_dSO*Si!Pxw#Gd-FRi|6hMr@cGk9T>Cd(AfPE2HjJ$cWUu`dnUi+=ZK989+)82r9S}fnC}P;8xBP zy*Na)5X;W`YtPVMUp#G8mmeN?f5cGBwF$-0B^=NyFBg(RB@foRyk6EM{fGPKs);<+6#&PV;$Rs0&2ap3;27Ty@99c#~S&%aw3 z8%1K~0N^-)8xZp=xl+por+_iIf!~Q+SYJi%XK^vEvRT*i*n8AzKcx)aQ&-#CS$OU8 z3&&1Wf&}0}F$xf|5i6p2;5f@RIx`h71c(1)xzFlMxFZu(^T!jMlHg7?Vlr3M(wu zwklhScnRAKF(c-B-W>!P*bl&NNAC%fdKlT z0gy8}jS#tq%HB_!SVl|>pwN$Ci+H4^TnCIu;4YNp1&A|40!1lRJmi>w`iJ*@mMUdJ z0xgNycyksCq!oCQ3C~T1$S3*1&vXdyjE7^AlC6g4d>G?`i=Z%5o8aCkEH`b3w7(rl z%ba-p0dND$0)h6NJ^)Y$B2q;R4vBhMR__l_BvbDD$tifP7aiAd`f-7Fpp^0nYL!u( z_M;dCK^#WkGIPMPWwWuP%Mu)x7?2=%7YBk)A*x`dcu`Bql9Gz;`9g4+bqSyO!LLu- zvmXMg;g;AyIBFTTiHfxdV7D_l3n77_LtHz9%t?l!KFqjJK;BbNWd)E|E_l!pF9X>Q z)(o4@e8X9hB)GeHk4&!QB5b)-E=m_1fcxa8>#=Gt#xa5K@Xv~`Wm(?*7H5(64X9Gy z9&iD*F@ce1YumRlQlihLbm5Y`)W;MJ!Z;6dXF=7?Rj=J zJhQOCJEcEcGj+l}zS<9IbkY{_${Iy<2fRQ+cFSvgX#qXlXd#hU>r>^I?W}wHija{O z3{{1De{kF{u}qsFR%|^56k(#lN=?zERQdPS=fzur^&&z>B{m9!llT=UZ&JsaB`=|24s&;GntubwlJN^8PF z^IpZ(NoPgQ1Aa+zPb^2gwWLdJ$JM<)E1oBn=1{K$q|&INVLAZrXg{i7l8LJ1FhGFu zl%?S@pMC);J+i(4%6IA$_m$z!_Hk!emYP@MHAP+r_7_S@2SSX%U@<^Zm{cJedskOy zy-6EV-(u+~`a1NvN4UGWzJQAUUVNg&D@EMg2)*!CmxR~TL=uo7XR5CTKOu0a0zYF|Y}xlSK-QN`AB`DgpNW4mML$P0Rqr=_eYcFs4iv$XC&q zH`)%Pt0hEt-~dK2t;Yt1@%9?xcp<7w3XMt$hou0hm2yMJqS>QW$NF}CXjocPL`pz_ zFH=Kd6@(q4pO+LGl|T%3kI{!*`f*6e?_uWLoWR}UET$%Y$lJkon?OasH@K`y0~cTm zZ&lHR1NB6RB(A_Is(@9G21=M)nZVxN)ytbGQ+gu=ja6P$xrAb26G|r)5hZ~{9yfu; zCuv>Q5yq*HkHR~F6fIzYHtV_(d5-q`z36@gs7&xaF=->$?r-5l@w$Kf72)^yU@zkyvDJCOTKemdeqJqGtwxRG^KgfHW=Q3X1qKbronNY+?2ZOO;Vg$lh91 zaKqRJN7Ky+pd8eOQ{ksm=c8mu{U38KH-<(2QQz-RbXpR&d*OUtV|8B#(#!&@B0xT? zsWN4XrP5NpZY2gl%pl;Hb-|2W=%8s9nI=gprn|&F2}PJ%UoK6B^gwU0GpwPrc^#*8 zaLim1p+jc*!&PlE5>)9ja;fuQ=Fwhw(p^2#Z!Xj)!i1uLV$EIq53Y*cLTs@R4l7~8 zIYl^p0P$@#tIvnoP4LF||Z#`OvAv&Bb`~mtv@WKp5F#}E7&X0oR z`gYN+$EUbt#TSm#5|H*M&_WqkeU|E3CBqvBR}?^5uQCuvOav1*cH^_y7aloBCdOSZ zCS;f$DWxmG6$(>Dj0#476JDPEyji&jQwxrvSec>E_V|x+gN@4L?uK{? z$=;){P^0Dn6p4_?Tqk%7+#7b&;{Nfr&GG6S){6*%U?**iRYgsqM`18Zu~EEG%+jeC z1eSMWH~-r=S?+7uE@<2n8!70G=EC>Q*YYfl6t<}px3+#TlNsZ`hBtCH%>^iM;jd)F za8gmsqd~*gO-sb00@%|=jE_L@99W{(U&u6wr<_*4b@&mNNapf${{O5$fc}K5bL*Wt zS5b~YaSM~Pk1hDinwVt=2=8E(-vLoI-wB!OZEYBv@X}i}ysbp|Om-ny ztcnu==jsl%{0?$dcfZTAL|N_AKqR$s!*v2>ZKd7xUlt-{oaCfB_Fkv*yC1-J0Psq53@br*n|1t#rC| ztRKeiGfv-<0Mw1-WTOA(9Tbx&TFw6sj1egmqtM*?I@Up5x2bdESUiloR+#-a0@3IS zBykQsM>M@lDRLgITB>EIZ9z&u$Ms)}=Wg>xr<4vGB6qD|p^ggFMZhs=aKHwg9qv~Q zn=z$aFd9&Qkhjlq`T$lTg?r^PG|YVFs-c0I)z_vI^e=cL&L30ZML!t;(S8Q!*EY{R zeTBbq(hOk5qx2hoTHBocx^EMCC^oOyX?IOU7vW(8i1srs|KTc$u(VEZGiU=_fM?3p znVM=4Owe`7tZsnIX^_L}2>~A0&w2d(;)&Z2N{H~JZhCOQUF3WR1A*wv7`oL_U&I51 z&O}TcdO=D)|KZ&7=+R<>*UfO^ zj;G+)HqUprs__6e0egSq?Ln-k2z0IR|6vkW)Y4K_)T7&u6*_S^U8}d@wvUA4EPrn7 zf6wBEA&q(mE?^@BCul;YaB$FB?6ZaVm`d%+>FH&rN-Wi80hYNC2j30^Pl0+COv_Cr^}g znAj+LXPBRjeRH4Z=|8{eH+7*>6qygCzlGdY3n8JWc?6kK8xMUphiQ%0kzr%&XB_=! z`1;dbC>0loP(Zc;Lg~??j4S5dD&tJko^oW8fUeF?na(uN9`m;e^ykm?e3CAxihf4K zwo`N~HMZQ3=>U%4cyvxfi__Ri04~wWF}_a!lveQa*>k>zV}p&}SQu;TBzNSAQlIf(#rYIsYJ;_aNT9w;i3ezz_OvD9 zd_679JZ%(PF_LMqj}8CR)9J6TMPEq8p^x;`IoM8IUvUxQ{zIHBAc~X&Wq%+y6R!3+@>9tY2 zG+JUD9UADF59hDdus6akRf>R=k7d=_OklpgpLQ7iYfql?^qNL}LzEt^ z7_S4B?S|yayW6Wgim^UeNuiEvFbp~YGfbqe-8c?_!BdVF@Vd7Fh7dJdxig26&>)Gy zSQ<9Dgq>k2DG(UgCDaQgfiN*c;q>6v2?%wyac0=!-UmI~?a%&>`I63I6*t~AHapG~ zG^88!x~$JnROep3=-nZO)L{C9=bCr5-MqEWcw_K!5W+v#4GiFWQ<h*WK&y*A9Kp5Ul0J#*3^=j)I)x6>|gE zZvT5Yw%UyNC&WGUSwDz6m<>0^ZrWX2ucE6E&*Gb26Lmi2Z27L$lAFeI-dxWoe~s8P zJdVw>X_qCnl%L*-YgrTRZFOrJy9)c>3tV2YTd`cW@r2#qQF{Zp^@QO_B-eHPeor!- zy|*yI44t6eee34So7o%Mvk*ou1anpadiZA%pXyR5(B$o?3QtmmMis<158^$g$N$1;a=pTKVjZt72+#<6&vdF!t=tyWf8 zpD5o4%fV#%+a^0FT+BtbZJ)L4D?8Tdn(`EH8}xb0q>b~xwLj@qQ~Rn;B;Ufg&3&)G zi7Djg_)W3Z^X+@H6wPMsER;m3is?02T+#S{H?0Bwc&6X2H3()w=I)-LEH#SH_Lsvd5Y7 zx}iC}rQ^JBeV=kM!?f$M+ z{Gd!>U$3)%+tbGGBS!UY+S&E7AsV$1so)8W)_%K;+I}{{71bM_>nm10{IX*f zpp7v{?#T0P+nsd@*ZINzA62)4Bcoh~w4?H;@k`xNU51lF${(B?408VPo19y;sqk-| zYOn4#vMTV)zpB$o^p9G;4gPQb;-y3X&&O|~%4cPdt>i(bJ7>eXAIIswY}@%wbl0xnnOuDe9}AGFnJ z`4zg|`mJ?MXCF7JoIG&6b+S%`g4h37A+bxC)5-sbk&BT1pWe{n4VW+H|BlU}^xyA6 zdyFN0qGk^eH}M}w<9QGU>9c%H%yNLZ=N~nqdmqapIb~{8|AeDU{C{$Y-pad39req} zFw^&4KDj1`YI^@D#+yTU_1uqS^GaU8=%G=+&14!GoZ$9m*`G{uiMG)A_m)-k06ph? z!K(}OnYUDU3BBzaX>W6p-wyIjdl&1g9l2Al{onKP6ZO*i4k72CmgB|$?sVg`@bma_ zkJ+ykHV&^smaA$iW=cC@^Ip35W=0@leB^E4?yX2_`7!?i@p}c3(IgJ0?>~L-sg z>u(6mA_U$>K_7^dd+*?gW2wSHO+ZFoDKt$Jg*f8h+O*hM_3r)uP8IRjOBL-3gsl!U zZv*b=nsvdLBLE$D?YGoMA?qvjiW4O9Q>IkN0L_^cN(TofkUEdY8UgA0iR2%&oTzw` ze1@qJal%H5)NaiJOo-)>ZmODRX&Ghli)Utt7c7SD#x@lm6HgOP2E7hA7=bg6q7n&= z9s#VU_WotNXIwRTI?p}nBkzb``hi=C5FjGb5BzQj;LBe2m~5V z3Btg;DXf|yyQ-77QZRYjz*no`d6qh^!P=}1fJhuLOQk`O-z%Ep5XMbi54H0~qIq0M zyzl}}wH&9E9vhYBA&oIi-WyriENsxW`WH3mJNteea04{nkwF0NG1y?9jF(xW^~`IL z8X5Xew*6b1N*jLuRT4M+kBDUj5E5l6ErAU%oV$U*YOKI%x(~0n%Ckc*68=m$fZ`L5 z1HzGHWR${Cf%gf;&*j+NNmqjZG1ntuLd>V6OFQX=MnDQ%6IOZrT_i@g;A#G_SmcFu zQg4A)M>))5Zq~j0)n-!&+&7USpRn^S~Pw5qT1s&l`iAMycgNOR0#co#E9l~aCy%amL_!Nz&h7P4ezYjQJLK(ZV#NR_ z|4q%5Yp!%}4-1>U{^pGW5sk$+kZDP~`n=w6R|bh&(H2KMvd6hHZ*7mA;hVI#%@!`A z{JrTN_uoGp#|^+~*k~f@hp5U3!t9JHrVYV~3`iOFSY*eDaH3`?aV(D8zE~b|%GF(L zF641Fjdd5Hp|$?k`tD{cLga&1tSrDdJn|ahLU5TU1Fb}Y?|T~1$Y1MFRUT%&wa{zM zS34WfR^6a0i(BmX2T#^@`s%$yOd~mtl#%_k>0L}x8=4^;s1>_m8vfQRARtf}lSjXj(-alsjp&shbaX%bmkNkL#Hs{VKaFy)K zk~7A6nmfiP;Y+t~75I1JFBR-ruW!m#D!MR)eTrBp)VWl-=@3W*3D7XfqEulh#yAMq zVh@;>cYw6-!VmwAm!$Yb{geN~X&vM1=dW=Wirb{1dm_HG?gy1lrJOhyVkXH~VAzUb z6`-LrW5~rV_D8>?N~Vxy$+o1(jQy0ej2-v0+St-;Fuz0MZ88-K&KV{b1*B@{2g*({ z9U)tQQU{&Us*5yQoH5sTc+R(a&TB~FGh-wQq>aoQwU-E|CZ2-5%wdC4UHe{}D;dex zlx3&MX8tFhsDK*@M&A0j9^tZn9Py1!m1)Y`(^hClZ`lMoThU`dH2GUR_u68dCL*T zC0bd8<4RT;faVT_ZxC7ui6cU#W`c&HQ#+DPO{m!x{YT*nKQ*zu!U*HbQV6Yp3jhGv zl{22uB;zmxCYVmk&a{hI({vW@YJzfoBHT*X^b~Ahrv#V)oRdf|K^AHPPBUvlH3)35 zB*1^XQ>qkoZsIqcy|y8#U-qY#od1up-x}qayH`kuKJ(67yw`nXJ8a|p)Wf%WOoVuJ zj?CO42oegV=ZMaPj7Si{ovoOr^HcvqsRkv;@|RQ4>$W@AS!!{ymXh+8|JyjGuCp;c zbgLc-MJ@Ska;cD|Y6~a8wBK@NWkM3+FjON4$kSgon$|3xkhFegKYvn6+6bIOBMOAg zP-C=4c1$J}mdPd?upAGJ{HM=X3=Q@FPc<8F%h#*eis|XBL*@*v2?ucqC8gRL74taj zRtj<%8RMSn7(&|UmIff@46de%5mIlb39l=_ojzQyuM#qJqo&aw9l*EbK(t#2ETh+>Ll=Ml6 z+CH$-w1OS(Qqm+KPpaB}q)JMvs-&b!PpV6wLiV&>^O~M6^5dqW)YH7lk#x*ms=llF z>cLwljpLrB-if><;9~-OnRMPl$d?I@1$a{FuBLSVN1n7L)}Ex7zT)M?+R+WCn66;8 zk4XqQW2AQo*0aXpf6q^ZpvFvV?u&c+6ds{g;7H263^JheSOTX=z>F3sI0fB7lAY{H zj&ktj*iW7E3da~(IPK=l(;+!fV5ou+=8VK5g>sYv{~v-xOd5~!Gt$I9Ip;Jx7%gzxDuU8|wmHv7JNP*M`D^6GM$cS&l4Am#m0C`>*C8lVELcnMkR!|8fNG4FyAUgIo z!zixZ@rEtZNh09R;|!T{py#UajB#K^zTw`9`>?o z{!&(GJ5>2e-{h&1Nj>B@PpV2ns-$F2=$nKuI{Y3YN8F&I!T&duPL zsPvV5a1>b<3QyILXs{G3gV`pI<|WfBTYx@FQZ{s}5@@WlN^0_?z-|x_0{{R3GgM?F z003WQKGj@-SQ4^AMZh?wlK6X7(D%x`;TGX&-#PvFAW{PWG$R03 z1_15=PhcXmuTN^?2Z#s(zk2F{CnSqZ_5NE{y!xj(xY zzH>4B(8W!mr)>F`L-4rGRqJcJ-cht>yUzkLMbzuC==2Zl@SUNowQ?+ zVb8js%5iOB+BV@mz*mj8UCePuZu$*a~1fyfpIh9PLKElEGzR5soD=aG0k`hBGX{ z+~;8Kid!+zF!*s}Jjq`6fdQx6w1WI4o{`ml9Q^jPFpuEil*R}IGtYsG?vSs!lzY!3 z@^CZ`AsxEE@0=bGeuyE`i^4t;o>5;7mWu^rjyb91aEy7Z)KCgv%r9jpWbIwa3aPSM zRYtVV&7VmSO5c=6ON*&01BgjSapczdi5kfP9I8ra2u%!7-{*&^1Qu}866s)c^ZPU9 z@4x!^v_6+rFv-JQm??iN$ydmo_t@8dQJA*9jLei@=crcnT{3)6_W=k@Rw38Eu z_IchiC3~BF0Kwuyov|4wE3XY_bjVAHP$skR;g?y=f(yYVH7>ZUdCB6CTDc-OznAf| zyk8KS-sHVpm?*m(=ZRSw#xhG&KeTBEJdQWM_7=C6txpMg9{$YEuRLN}@m#qfmNPTT zKVwuaPDvnf+urQtc^E&V5{B}oc;TPK@@UUZoQv)u-)!4h`o8$)bEdTHyxEeCmM`Av zE#wURVdyyF>?v$4fq3#@O5P%`YtILv4CIlT7^#Oo1w@p43#s9pZ?%K*-d5m3caaPMyO@%r@T zQ(l>SFpK===cu^<^u&_7joNDy+O+#_CEMbmH*d>X%(Cl72WhvJ>J!9o4pQp|u0Re< zeBtDeOr+NxNum9XPHVj)M3*+SvPY0L|9uSgd69B9ZPJDm^R|A2yE@qWyFGujUfuId z6Y$H+yzQ6J7M7qgNA4bJ`}LdG-kvvHD;(p2Df~rh@A7A6S|>`~L<{a_#>f33)9&RH zKREv%v8CgUk}r(*7Pp%}NIaM9X4{am-lf3&dvIyc?suF9=XtCL_E&TG zAMknDzw7uUImREqXUiAFB+wU1B&4jXWtl7x>NnUVb^oWpSDEMIZr}P#%{N~Ul+Z{y ziKg0#U2yT|KlLL1asP7cI3^1g$|A#i1I`Hfsp)e+{Y~BJIc(mtd3>+;gG7h$$)|h% zKKWCpKi^kX@7{=fx$I~QHY|MT<~{Qex#YAAju)L%soY_A^RPL(IG%9B4jY6QnYdq$ z5g$wZZ6qwHpi8GQ(rdPC)Y83^g%f+?tf~Jy3HZC5Y|Rqb!_iBcM4BCZIGaT|do-qt zVQfyl`cA$?&T+vUco?!-xaNW^-(Kax z=F_mU#!NRCx4sNSSNAL)J2eV*i5g_WjhoT_rJ$RR|HfCz{(jK{{1PG38}ZXv#-jDV zz_=P=8sj&Fk$M)`Vz!G!V;%v4kO04$yHCS!dL93Y^m%SI#Ecxen1WcurQ&nLNC8a2 zRpO+K(lE~#+?#wUmh0I~7?6u#f}{Z^JA)ic36g6S^}D&qb~)CZ>OZUpCL0!hrPc8`qSt*zZ$*60vWf98)zMioyRJ=IT2`5x5}bEE1EmC(1jR)hm(LC+X(Gq(m2Algs}}oDWG+z;#0mJWnAMzYcSgTiBj$=9t`ehJhg{#FfpfFwMg)KC>il}5ARgC0S;||=1zFI}|?ww>5OxGUf z9$1WDMgh(-K?_c@BJ_w@t0TDzxV~?HyCbx|-R&Ii#<+*Lqc6aXDd;Gc%M-=S=10aH zlM0+g$rS<#Z|m%O0&%iu)o0WD&C8CB;dl@=z!e;jQ~;{VTY}hLw73F$&*HVZfV~z7 zUT@moeZI*-Ca(Kk9m?R70XP+ONQ7dD!l5vo!j1xA0NGa6GfFU{W)_`^Nk|cbYQfv| zp)P$#Zs2!iuATK^pyGPTo-m4EZ`XgDuIo> zM2)hMQ$T%^d?KXnVMwuT!ae}xO;&(hOCs1#(yTR=Qq1Zq@53&4B<-ZCGy<)K?9y0L z>8eB3z%-Fbtio;_Nv!7n(tbeoiLzBNR}|r0v=L;C3Sk6litBJsB&YY2?aqN7C9FbH z24eibmqDUgK-gL2_fu1bFVDx^z+3*Kijk?O*Lga*Cy3~=Tv7_;Sjchbh9hAXbO>Ih z+1%f|S2JG7Y!&^F7ExTZ!?V+c-*sH)L1IUgu;lp3tIOdKMs=tYeUb?}SHz0Lmz&PH zVm0O^T7SH9NhK=61gqxfefFN5?~eLThbzQ^IpxX1Bl4;Bvtqnxs^EMnZg{@@69<`j z)=lTt`})6ZozT~2MQg{{1FC3j5l+J7th;3X3{|sKgUV&Ygony;8h1q<4XBDkfu4r{ zAs&BW@JHXuy%Ps}3^)QA0v#uAb#&Hc8xOf8*Q##>(YwarlHhH$ZargY6w z*IcKwGoB(ruC*YZJ^|4f4deTtblSF)2kj`Pjb^>vpSH4FIGDKRv}wHa?f#Agy4L7; z_!KyN$BwjbJkJMEXEMDp-sbxTO~GXk6R)%90?*&vvNighK8b=C72`RbTG~&0#fBO4 z6Ks8*WBN=BVDPo>+i7iEAP93YtBKQEHB9$hZ}>BJ$RLl#LTzJw=(7Z>(^4_r(U=nSS_|Rob~z5ASuj-ef(r}R)Au6IeA>F! z`Iq=)kwb=z^n9YLqVdSGAhwv#*UFCvW6o0wYRkug;o9G*^Ix>$LlP=m3FG}ql5*aw zHOGnBBo>Ss!GQP#W4?8&UBX9M(~d>n&r_i%N-)@et4^oN`V-3IES6DoFEayVtI;xB z(?lnuG@-wSpRJmJ^=Hb=dZRu{;;NgYU`m?OQK>lBZMn3B^Z6*dx@(!XWjFhl%IG&Y zcJ)RwIL@CZi43YSnfekgQmaU6`^Q|aP7iBGK8aR*B+9L}Or{9m#w>4c?CNb~b(}sk zq8L=;xyz&{WMh6gsEuUrKYbC=Zf@)-_KN;(_#{I>PmS6yuGOZA&fJ0^+sfmGxj=-& z$K*`;`>kE?m8_3xZ9{3c@o%P86}ilSS&hl8I;kx@?We74`h5Bm2KrGv%hj``AJP<9 zQtiOgx~#gb?I69)j!n1b_7X#rSDygZ~OnAW!Ste@t)A^N8+Yt00$r!gAB zHI}wasIB7F(-Si>$N6Akufv=WiJ6(0n2Cv*nV8;3SC}TYmac0hXqjJlIjsL!j>Y}O z+)*6SrC(Q~6=lu&H_Iz%CgGd+cxdKqTM2pLnzJ4Xi?u2tWy9J`1e&|UKo zkvITB$KnNPX(~*BmoGO&pX%0&oHb*D?A%ltJqnm?Xe@P$ZJC$yK^Zzqr3yY2NO{x}U{?Kxeti zw#IXu^I0o!351#)NrgrQw2?!Y9iw%9UEKFwPB&qo(U}w140>@j>g5_EToRcpkAP;b zw{G*Z0?0$_(LSpNBcq|Sk5n_(EpsrbBiCMpjhGb(heISsLv?{VlVvE7bcQ4ty!B2= z`c<3OEZz}ugCQ^_dN24Umv(j+!<`hUKa=3Hl4Xjm2D*!)Q5i<0p$HNcT4KUPLc%m@ zoIBKk4G2jUT_J=-0DgYsSvpGV;4i*Dyu4qNz1q@sRdggQ zFe0R22(U+BvMgi{MFlKGN_dqu58u}P!Nm)br&~y^i$HP=1L>&tm zuPAFv<8Suv0HUD5Uau1SXTz3YhM(g`CXIs*{M4si-h)O;{!|kggD>9Dp%sK+YwVR8}DA zw60lCc6C~DTq+XMT%|amTos|%fmk75(HIVn5Ju=O{>u7(3-xX9+Fxqg7w$oaL{&h7 zkSuHh2vjP-T7(fmp)Mj)8fOj7*Ygc$DkD`@k&3X0WKcE%MGm^kBBG6{DhpDnZle7? zo$c$>1~=VXf$AWPMRl5rs!9O^1TzU)xIlzT5*=$|ix@kQS>x^A^zDC*#SQ1%$j(J4 zaZI@gL6}Vw%0#N7YXC+XBn=A4Pz>p)+R2rFaf$b8YjI&ZH9aIhg}}lD4eEkL$#jH_ zLe-H)NJ&7*i|I&S-QQi>JKUWxKsA&_g-NNvBt*#+nl1sMNY@G?N$gNX}n#3~0HNI4)GD8Q1Ah0FCAVb=`Pr|X0cdBOSX zr4-vy*jL7gfA)>aDs(`yy@~spLwuPCxnJkP=bp6=+fU&(W>5)P zXSU7miy%Izq?(&qrR@^*S`&1slyaprZ!4X06RUow4^gLWEUEJeTfNo|?@@ed)QR2f z9>%LF231)b11Zybm(+QE4c=>q7bv9PFTjftyT8i-WMl@6z;xf9K>0%fm)flAFz zGtiFWl#ivvtOB7S+?8)>&ZOs)P^edSr_I^eaIF@?;Vwb?&CC?$7d4^H2(6&{#leQ9 zL1N84Ga}*xrQ>?4m>lDhB<&W3Wv~z2Jpr? zp%qYjkOQ2pZjs$^yt)&|Y9>nYC6nXTfHym!E@yXT+>PTT>fmp{M*=a?xEcY@C<4tG zh^xKhnGminmIHbAHRX`h^`r;VEyw<1N|L=R?eA@uw$;9A3*8(^R>a`0b#6?MxK9kDB^Tp#mrMjyL3Ru7(z6?jiT`67@!3Es2QA zJCfckr^7l*DYqhpn@sK6De`yql3RfA$IJ%dTmN3*hV6nI6Ql4ly;~eWw~Q5U?YodM zPRo+t00Xt`0;36`Vj1qz>gv6BGbXl~JK>by(ippK=S~QfCP1s(D!3+z&tn4Qi3lB| zZ?1qNxaf_}=_Q-FAcjgZmNnc)(jg>6DE!KO9r(#}r(7ZuYU^p!cT=3!o{h4RTh7F5 zDD`6xx81}L-(>3PZD4f$x8o>nEgN6jqruNd_NmYmWC)aGC~BND2m&=3>B6Jsq+FFq zh7P0C!$!ev0U?`Zt#?YkR+1|1)m`gKy=4^jWP+lf=r{h-ab1X!!ESO?SM{6V_10>a zPR4;3;@g>!4mB`6LPA2ey-z|YvXSfydShMSh;IqTBv}gh6N*B%m3||o|&Nj&X zvePz(aYr?}=1nQMgCwep^L*S4lzz_|)~C?_LT5GaZ<^ z1x$}juTmOimDADzDGH{uB|nEz%EN-b|1FUW=5M7ydPVoA;OYkyre!wp%b&nk8HAU% zH|GTFz$?kKZ8w6!lp)h?8;z=j)->g|Bm5s_PXAh6WeN>l*~Z-9oSUhFu~g2mZqL`= z^1?Yf?v{bY+N@Ud^-2|cHWn|h)k`#Z{+liJtLKU~?bQm>d;FibM4i+aCB0+sf!S8m zqnwGcDxQAw*b%Lv_AIXJ>%Or4W0%(Wv0DX<`RT-|D3*P-YA;^D)(u67*zBlhY(lHd z-MaqN*`y&_GfK1n&lVEsqP4>p>pn0)G(xp90Jsnk0{{R3GgMO~003`gXO*{rOC!9A zBw73Kt!;_C1V~Jf5G2MC1peDALvQqW<}{A(oJsdw|NR&p0RSP90ILH4W&nOrR_eO% zSyF_!Vv=M_{?;@T+>&ieZ=T`+BiksHEa0FV?p+V%=C*FPJy25RmHpF0Pc2oariTyV z@Jwzx`bI}&OHMgmbcsWFN<^S&NzW!JS(f=BfJ6WQ3<&_y6aae{_qy+PZ*OL8?rdzA z9K_)wZYQ>FWJR*O+fCbTw`>aOlH&$0nF(Y(5JNB!fhrN6Oc0!}KtPx$0YLzh5&R;kJ#QXL{*Tzh; zDKyidB3qKdQMO5C!mb3X+uDA{0PMigs_7FgZEb0XW;;LR*>MC8nl7ECRUEoaLarNv z?#5T1pwW`eYqnjADC4-NRGxQxny!a)xQlkS?l!(81Y+J^HLS7#@5wnvBR&D&=*-wC zV!_cpi}

    ^100s;t2K-4J0H)$81yo#W@-R{#*_7l64#JCP>K1l}u04CMjaQbsY| z{WoPbO+`eNXM5QqC)Ub%dn@ohmc_dC*M=juN8St9Vcot3w`1dO+>b#M%XQ{wI0(^$gT-lyp1!X8KILo0Hj!oVA0qs46#j2TB|>UGAq;cfIdkK3 zpYFw+LY^{~Z4=!lYdBT5(j^h}5yIEHUff4$M8$&1LH$&9BCQ5`i~vR~p|b-R+esXQ zQa4a40H=0X69wP>OLH?<=^p%!>Vbf0^U~oA*{2s z_lQ#j89K>XT}9oGXbTFi$oX(wRsA|4F)>G6Znnplsu&>?cy-6UV18kM^!7U}Jz|%k z`=$PZG|F^!t64q=5O8!LH`#V;&Mz55YS&-vW0?9!`=b~dBrqqK7{(GfVU`)++F&b9 z_6MBZCgM{qtC#cp~^&IEN|PvY_|#YPs5#Z+6+!bEnw7oI26 zpjWZ8i1Q~xrAyefJSY>sv~+)Lcpx{jR=4*PTrO@&ciq0tMC#WrrFn6WvSF#NuCmwM z@ckc;g>|vD0@pv*KmzjDD4A9RSp_s1V-!Oi5 zrhl81_&M@qRJyGPCRbAoDcb8!@UZ3;%tN#D6?o~vW9RE&TUJOu%_jz1CKxzCnH;xK zZQEI?pLGI)T`>U9-gFy^v(VdrE2oJy3<)^aeL?y_}p*f6E3Py{UA=zIcOJ|8@2#Kg*>{xD)C7oj653U8LG2@7Xl3A|v?m z80~A-l<$)+Mawkq>K21O@P}(>R;qq}s1S6YYw?^Iha{AZd}yz*lx8zdErh5i#uKTl za(*;&hlif{M#E^u{-O}6dX?kC83(s)DDX3$>xO5{5!w)Yks((`Uqh|2XZr^{h|9Vi zCZ$m~x!<}V++4sXY;xms-zCaC&iJeQaK2hTz)>H0Oyiu7G%EN4j)2^WFVt z9M$ng5}wd!K*Je8NB3$3UbMZd&E|@w3jpaV+Yw*KZ~AFI#Qdi{9K++s^hM(KlnQSj zM&U=!W5-=l$z7tu&$7I}-ALL9f}hDH@zf_fvr*F>`$dEV&K0!gXz1*7h482q5JyC6 zw!+2o?;G-vLrXp7xPu72cuBllkC3U5Tej2opE*b`y)K#*L;J}t?K-~o*ux8Z4dWi2 z`NP4NQH*Jo(}NW``hGcZ@!;APM36}=CuxXE;5#wRHndDdVOMuf>)5e%9~ZoLo8)fZ ztR*+c4vV)q4#%n2(H3m+`Q|acs`|gaIvVEdyRKzx*t6EvD{iLhiEs6z6Ztffv2mup zh-pT*ma~kTlF9PkkBk#Q zY3(q7RdlKCoLYRJ;Jc1phL!g@Z^m!?TGv&WF(&~BWK_b76lwXEzug(>!_&mnAgN|R zjgUl60S7e0>W4XD>hb3`;;_`ZWBE}h29VqD=BW*HjZ3JLPsL$(YS!X>sbLztd^+tp z%cj##cV%t6JJ!?aqu(!$5%+Ux-8u~>ch~%#x%9q(wTnlyq$KvyTd4Tjjk=?yj?R!X zE{E7aUe=>2A{&zidI`!h3QKC7^0TX|sv6CU-%qcU*Tdktj;*Q+U-ZqC`e-?&LORtu zR!gC2zOWG$lAP8SIUYn`7z=(GM~DKv1OK5+{VIixZ|A7E(At-A5FYH_Q-cmnp)sso z{Z4f4JBB@%i(a{zgE)$j>5Zu9h@B?&FP8R`RPo^ z6Ff~km!{7x$PDr!pT2V)>cb5`w(PM9n*Z+E;dd zD{rJtrxEPPjogn$+oonBHS(B2cnho=Qww&itm9pGJJ!1IKh0wD{%O`;&ZfJ3Y5ZRA zHeG3Q9ofHQo6c%F^`Bv$(lxB-*Zpy7|2Upa?5?s-G@I;*`cAXyEihP0KkrQ z-?7&HzB?W3y7XAb9qY7X?7OO$per)Jl@U}8hkLoJ3GUQweCvzhCZPHjOjUV5$0 zg^gZ?QPZutP{*A*hmEENAb6->W&6+5(T(Pg_w+hUAis$tkQg|lm^KtskyoUpFSi9a z;a=vSwzjNU)Z5T=@0URx*}bL)5SSIl>VC>+m(eNr1NBE^L1^!0sWzu~8p_4pi33td zr>qX=jCPbG7{-MNMlHxe{q@?$euMBB_lgxflTI_clFWhb=C1S3p~0* zQ`0=~AxWHJ3lOb+sV%giIHVO*B(&L*PuDYapS=|pJ67t7`~*dg1X4P za_*FLlJfycg&P(E%FyZ6Icso=pf>V`2?D!%sivjxFYc|1O|_ji`bMj{YS=57fnrzn z4QTE>7@SA0s!zH=Kwr@aJcH3@(LFwgKvCZJAiiN5N_q39!YAsM6zlY_$YJpDjU>Nj zlLkils)N8IZBiOj6gH1eENy%58MPZw5jj|5-ZBFqEfALkIniFRfqD{!9WZE(wS$2* zt&iuaW1wd0(E92&@T`!ALG1BG=9u?Y{IxqsEZJ&cmt(V%s!@ z?nc{%V-c@k_T2{#|HpOey0Yfr(ni{s*vEIzwtADu$q+XJEdLK5m6+}HC9922`ul#? z#>L!Ds4BGYZ0nYH*6dDw2Ke3h|H|hdU^yk>_L9fqt!Lysj<}$o?$$asHr(4<7N_Gj z31W3s(Ow}R9I&;l_>6NkC~*m#OBpKH&n9Jz*P!pzD*xeKwj4#TjNrv(;ABef6ptJA z&Hb3SCo8-oC0ty&en=gI<6+k+{0c4*ySqNo`!`Xnm3{O|PzW&M&rv3;_Wd)_{^FEdyaXVOUyNIRG3N?5^YDZTr*CP9oMg@|L57 zi^ze9nO|=k5PasD7gz>rs(z~3rZf1g_0Twb+tFuCv`1;+3cGS^_S`|A170cMFRf@i zD}FaJ$0Bdd-M6xF;c$&xyNnt1-@qDbdkLB;8aUDk)2^Pq+77bre8n$y;k)|k7Ur!S zK_uuU;E2Gvpdf-tFsGtWen9GMdvf7rza&j=;5dWWEsdrLvy%7@)M2z@7_(_oA(5QwA9mbUIUk!bn23vu*dwU3~9$SL1@P`z`GYptV_@Odqi z{Xu`>|FHNQq$z#e7ul{r{C9s!n|REzd5PRXnBj0KUA!do`nL!C9&fA{oQp0nMkP2X z=c*n-5U_J1l|FNNJW&r!&Q9b*b4*gf=E`v+4(Hd!K7D+k%rr2Tu~oh0|91DofVcC3 zEj`roDZgBizm(>%NIQLJLdC8;Q*(E}5PIF5`DG_ZF3qvOI^T@kv*BzXD1XN!kA#?q zN%fif<*m)6g@-*le5BEv-22`?c4E&Q<&LV~JP-5(^BcFaesJ$uyv{10zVtD?+qe;& zwDX{KYj_KC?Jcze_;rfHHw~HfD98kPAh!4(R~hvxoLPB}#2`LfeF#fGI+g)G9r6#~ z?K?i9aa=tcTz_sl40WO{t%Zr4EyXzJH-uREtQTvpcilS_B{=K8tWuL1JmqONTS<#s zjZ-G5HoYZhk)!&p;;&_?#Vi#1&*@jy|JV%lDde#OKhu%jG9xDa+WvE z+UuS<+64FKnQ^G(PWe3%q?KQ6&6T7oeyMu;Vu26EA9C3D1!iaKsa> zj2Irb^G8~Iw03}T|MNs$fox-A0s|o>uApdHPT>;)kr2iZ1-mCpcKOp`JX_=&$IoiQ zd%Dg+oMsMCw#DY8loJ>fA!~DlZUH+GLEnQ)KvO(>JqruINVPs!G;X&I;@I|ns_E_F zUEDg$H4!vV_R2GXjDa4sm@o zLok9nayixc|DU!?;mY#NzVmVA+7^RQDrHF~AztQrvw!f3Pi}gvdzlKU`rR_CJ9tUQ zaktCLsr&I1c-A^*`{5)eE#|=XY{LYid$Mr%1;J{|igN-kOf7J^G7B+M2B4p4$-DXC zJm&JQjD_rc8sgUF6%vmMD4{Ip;Vpxh*R+o)d(Z3nELJhGiN5M@uDYKi)t%drfjFK} zG|;RR7*Q357_|waHOj!aA)(E1U95E_U5)Q26~ zak+L-dxmD^gv?Wkaq8%wKHaI_(W(mV$z_60hcIu@?YrJ#QQK6uQ*e=hj#y1Y_qAP@qCG`uOrF(Cn5bON%iF4N&C z0M>%)hbhlLa|d}9Iy9}2JFDSbZ_0!WCGdr&JrHExW1)o0W#BHf%0&7ei7zK~^KMi<30+BKvgb2d&*VBap;E=)bPM#vHc=Y8FUwCx+&+Ku;L|NFA%H_d zED*DCX`lom`CFGK+m`Bkg5K}Tz5Ra}4^_TDkTNI8hXU-q8X1@&hn7H$5nE&!K)B5a z<#sz7b_1x^orAa!@-?pp%$9Fjx8ZgzCAf|3@@29M|7Ei)9G`Up|3W?Oz3hhgsb=$w z{L*o6e}dO5I1-reab!DzsC1VQaeqycXZrxTP}WNc0Bqq^YeQqn2vd1n@nm7&^3onh z@AsQy+~X$tnDeQKtFFI@+(eY21S)!lEd6-HMN-HtgKU>06|ywMP}oa=F-!v6PIXFS zrb>)xkHHRWL;V3jc8^GWcnOnj6yCrL0N{l(16ZJa>IBG-qmUbwBt52~#uPvy1P7?W z4ME!UchFxvOhJ%f)uP*cP#S)Z0l0HY7}G#%|G`R0p+8&fvJ*0NKn41eZZy0bY0IUg zwzK78THOY1^fdt31R)M!76PWLqoPRPFhej#wvfUP`8+^AFOk7g2DnUwWei0WMI%WY zOgW)YaUgrSsZ^g{r(3MV7Q*<1r*vJwNeLAA?v2IP?S-Kr z1}U84kT|pi6j35)VT#&ITeS`ox48TRL%@|V2@!rHlG`~G;{QBS*a=3%g<6#Y+CvgL zjU1&3%Am_wC4Wi_SldFDP8HrX?yH8{zyZ@0KX8gco?IuSbfIm2;AXKW>33*8iRbOQ zhKOiG4-<+;cgqCzV88^%i!{QPdvc55KybiOwlG({dE_!iorYie3C-1e>>oJ_PrC1LW-V=oFQBV=7GG@)kW z$Wc?Rvv9qNTmt~Vu-{zjuomXM`%>P?>71EGVp&c15(XGPlxe80{QAhpHX?2o|U#b z9mRmc0Bt|3oFL99sZc{8^PeMQ<2E^0_Hn}R$DAA}6$?L? zO9mpcF%oJ3fyS=WcgNaHnuD0K_}$Gn773~WS7ghh<^`OM%L5L-n| zZYkz^3a+#rWuNj58=m7nUm73KWaxnk^d;b_NP^?cT7z*?V-ziEwp<%00z#WcJtI?c z4p&_0!Z*miz{jNq%5p}5MV>)5)PohKK{D2VJ*MM1{AYq1ecdTf{|?jUFMj=ZkRce+ zN1Id?6XrHeGtdUZwTR1rODOKs^DJpA&Fa%v4(Jr!Nf`g_bu#He;VcoDQ#dUwtONjQ z0GFr(Kn8qpMM13CsFgJXk@jUj+OOJzzCM$a;Y7IGmYl<~Z#wAcrtx7&z*V^UNI;2j z04N7of(*W;NLoNN#S9H-?jU||{y*1@*4+S<5D)_Z1OPHrWHkT)Ut~Si?E;sU9Vi*H z_nD5liQP#;Cjt}z+aQ-}y$}h^$xk~u0wepkQvCohBQ#bs00006Hm$GUDMs3;qh*)o zreVyQ7yKrmr{C8kka$o7=H!gBSeo?(gR@9t>q|>uVe9q{lduWx^33>#h53 zcejcok>e5v$Y72|X5DdJEOtpqGYA!Mz%d|5JSjmW2nmk>M~FVg5)n*zUjVm3%dHlY z^yK4@wG}PZo^=ucOhB{0YHMp%HS7LmHPsX`{QT8tQ)6Mzn&{HS=&4I4(UrZctytHV zw*TncbD)Gh_j)Fo&655J-KljBhb!nlq|c&NV{>-GDnib+Ya;z!ezrC>#POyBy=>t9vq=ZvudF|V8P!zM()&Sd1<;YjVbB0DV_R)CVH#xHzUiqejng+*UwB$aHUsr z_rFtc;VWy&VX=zFpMM_b#1^ZUesZyeRfZSHx7k=p*5h(LTp7yMS!n(3WV5Z?k@W?w zUFX>K>X3Ci;fb}c6+5{WNi2?W^;xzXU9N0}9j3bXvn#DyB+HV&UACgGN5+cvLbK5E zdyuoNt7#eCb!c-h_`9P*$rpew-+zVtYADM|p~oUUdU|hdG7m4iBiX=iXMR?(j~zWm z%-wBcg|y;o?|y zn=yP$@`b)`XW*_))1~1k6E}0IJxnYBGQS7VAF0g%Zc$GCxmpr&o^xdOY?14A$>ig$C%62|aqbk71VPxG^ zo#%Ei{?zqQc7hHq6owW2vgUmyZQN1qm-LoNd;Xm+8Pq8|YLyH~yuwSP=vcILKbOzYo7zUl?z=dLuOZb_SSR~pqMU8t0l z^m@8IN;Ng$7SoF})~9%X@RqWkno*B9VviYkm(0F1&g@51I40y)XJ(gzNT*;fFrv#x>w4^ec*4*rHvsT_SlTyERq%EV&UY3+oEAysg`k+`px) zab>`Ug}={my|cIl9287;bE0|LskLhsrYaJy;DhebbWa7Yfs9SdDyn`m?l$Ol%XwqX zt&c4`k}34%Nln6}47O_W!DBuID{zSI0?4ow<*s@4@+rDzq?ld)SB>}%AK1N`21}=b zN2BA@(bQ7aQEk(|^4_`r*Kuz(0@2mXN~JHmZVAq)Vfemo!?OFytMcF}>X|p6@5;mY zjgNz1|9*r~`84TDy0dG-WAsQ|c9!tyLGYzXxP@ zK5Igbjq~r6UF&>d@y7jEKXh5FihQl}Z_P^&BVf(lbk>=J@Nc)w@3#9gXq4rVmvZl6 z7lhf}q!g8Tn|tY+Xf~&G@5z!Ks!!hR=-n?CJNggZ{H|Lx_$I?A@JP?fFBmWUilbe{ zoiTc~m_E!s{RQwrjJqc&j_;LAZ(iMr?EjJiX^{PWls?m|^LgB7;l_D;)_C)*b7k}6 zEVb4}ykt7KuJur{Y1+ft=4WAf(O8cjr@0hWtzK`ku7AmH29^;Y#?f7UQUAuLdRNlF zZ)3h4o9Da{5?8FJ>MoGdn~#jVhNt* zUAeHN1M_7UeTfodd>@d3-dUfJ>jUIi*8OP?cYD*BSJKHpKYGj-jLBDqzL{Se(sjI0oNam{PtNptvuELE|6gkI3;ocSvlmt@50Y9k{_}scJ^1*h z$6?!b-wwHvgLmOSqr*C0ejjW8(Qawi$)Rvx*Sc;DjYom=DJu0UdsocHWY4Eg_AP4w98d9(IJXAR4{Zg^EGy447) zXX-I;{omE4es*PitB>n^|8Kk{=YEZnt1OQ@{(h4|uN3IfaEKZ~wEyd5s=r(0vL3$l zzjw`jXS%}M>*-P|X`T8sHNh^^LNsbT6>K4P)*VdLJNlNoT3uL*Mm1EMI~Rh5nDeX` zX`31(NzyB#pud;j>Xt{=03fggDpF z5bVY~`{~EKdZem!@p$J#b|Muna2p<$;Y;AHxhxNOz z8JjOjhMcZt(kFNB2!GFh57fqr_X}=7e&ZJC*sopb`}iV!H6LL=NHf-s(Ng}5BpXh9 zHdmQ1N(|Ch+urt{T0YLi_&woVb37IDYsBzs7~#ckHyKF9uHabvLP);3z~jCPKM#I> zc`pE{DD5R}w!L3*M*mzC7Lqfw>gZCpWq_YX z^A!JIa`E@^Ul97?Ckj5#ul@vdYyuvx**FW-eJQ>!55Ob7WpX6yT+8GRtjcTg-gkU$ z!_r!^x4$4O$C8gt{xgnT^UWZuD88g$*OZ@qq?zW)v|!ctFwsAE&~{gPlhQER9r4lL zHEz%VOM!dYrAmkUn3L)Br!6&=rO@2h`sOaZY~2-s-J8{&=d7n~-#NE#VU!P(zO2Sj zyAq@8wn{wVawu37hLXP4+wK{A>a|$a+Spb#DG#yiq3(5=@+aJ{K3BhevAu%j1rMEU z%YRV-CgCsCapJg?W9%|#&@Kv~vGSG&m;?x~ba(1=Pu#T)no`CF|6TXL-!w77@4`#C zCHjbTF1+xV6rD?o`~~u-^!Q6XU3uQl0Z<#HaRLv|c;YZblB8M5jGb8r&kH2)=BGQ- zl2?o$&t{sf9lX3bc05!pGyV6j8q?)&UBhl96aNR-quw2$xKS*~U;iVAxm{^~U0tJ7 zw1XV=_J{55!tKs8lJc6NdWT?mF9sHxw9fsH;Bxrvtcv5rtKaQiuz#es$3Xjk+H}Q= z_OAY2On0E1sMG(RFtGQ=TV_@`po@P!vFEKAbY~ASjf?Kx7C)SbjyU=<=z2^;KHI{p zf4BI@`gmRsx3cmGzR*u>3png(yqA8)I@I3LzAn7``pKP>`_Fcr8PeYqo#yl36lv5u z`tJyTa=A5))F46-AC|I~D1QW!;Ccq-Ac|x7b&o zKap3rlw0|Ha`y$v-i2>c&xCp&Zp(U}sw7RYp)meNB&hFC+TR`FJ-d-SNjr`u9L!{} zi~~MlL-6_X&s!LNu8)R4Pdd$%h*B#_^se3!|>>lYIQhuHGd9_gJ1uztm$1`qB5-eNUi_{$vk&Uoz@t^Et$= zD?IEsz4Ct6y05HR5I%kCKRQr0h)@-DTID?Qu`uL(-YWjl4sA73DN^vqOUdLQOX!H8 zH3WTGD2DD%6{a2b8*r>SldmMzt5(>EFZ8T68cE3=|LDxnbEIsWTkmMRtHC&eUnRmz z#}olvVZS2rwlDdZxOtfR3SLLLaKCz*^jB$L#)5i{z53W;Fj_E5uUXSKyh$9T;W{ zRL%)5K{teHgThJ4x>sd)ffBb_FM89PmHt5of66u}(^9F52}(xDtz4W?*mR9HC!724 zBNn;7s7=S9q?(%|NTHjWxXfN5H4-G{oIkH?fE6k7Tk6lB?PlX|ELQkncyVkj^a6P| zS695>Z;1Rg#$t0bXHZGcEv!mN*fNL2Rwa%zTE_v+kN7NEd|Dd0s?Tc%O@qT9wr6HM z(j79sd`R)8mfzcQGH|rzAWtRNOM29w3SBeKn*u?_OR#9Qh?G>Zoo>^Y2nIoG$Ba7- zW}O0DNfFab`M@9r$KdEm;)!5j-`wEyc?*`6o(0$DnCqi*UsY_)oGf@2I7RZK!k%}^ zbL-aXDrTxJ_ImJ64iDdIgf^cz!;J{oo~wwMujeU(Wd__gIaO(ip?9&=`L9y30FdLp zi}_B3rU(=&z%9oChfR(u>M^tqItYcr2bfq>Y@Y9uo`+19;K$%&s{xzMomJmrXw-W8 zkf3kaD{#-8BfzKa7ftqj4<&)Ek>4dy;spyu_xXQDdkfs;JYdR zsiv+%Zxeykn)B;Wu@3OX%#vf=k^JcdKnR5^pg3;_&)&GLZ(%laJ{)$SefrQEmcrd@ zjvUV-ZOftqdVIK(rcFtMQzjHX)#_OWMJ2@eyo!gcm_uRtf^zkvZ&~O9j{_AOxN0Qn zXqNG9q;)uMGpSc$kAiB9H`7_z;mY{>7Knl%Obaf6&AN$BjhdS9skrnulX-JWyTHp6 zNoP|Coc2AEbF_~7+6l|_PKeTPwC5_08;x2FL{Y04Za|Y4$HRn!6!AujRtI#bfzzo$ z)B8JSQr!1TH0JB>g{T8`&eJ$~91rixWp3wfW~6oNVR>$7I9xN%ll>*fa#eV2)!h)F znL0blr=?E0k2ROK-Gp{p+L(^KFzJ!1{#A8n^|RKo)i2AZD8dE^Y%~n-%y0j=U31TA zLa019vgQ{sfq-G@({w7GwBaqfbgGIbNb;HGtENs(kNKc+ldp8(;o;Z6BZe;ixoxR| z{(_CC+KIq1G7RveKca7Wsyj}qALE6hll=-N-Sd@R6}heClHD;zz3@ted>E?)bOZ3- zD2h{sc6lhgd=iAmL7Ubm1a!0>dQMqc%-igv4vn1YPptvxfjZ7O(5-%hJ4B$xxg&t4DYiOCf{Rvw|Kq=0- zA}J^W-!#yaT(em)j)Aig6vU%)ol|pe#FQF9MeFtcqxCP|w^z4$P5t+nD zeT^8SbX1;H`(alKBO3a63DF7K-n2El4-q89qK284cpbAV#7%e~RO-Z>30L^nk{!@C zC~aBD;E2mb#!DpsC!hrcRETu5pmks-35ZPB&eXAlm>}{tjTs|svrk1LvJ%HQ$vFKa zK)~o-tSu9gEMgRjqZER)v|V*YF7yi#+iFJhz4&#^M-e|j4RAzDlUp_|k4(!&3PX`R z1O|&Rc4DJD5eeGJSFpKBCU^*D=#0gP7Dpp1iQp*2f-ori_&=&LLC_&aH@SJD|^y$eWCVCTt#esUZ*kQC!hdLj<=)|sN| zVepDTMc=!yN5o)L`GY=|W7zmqY$m(06HD|U`Vpst1rIZ}F^{IyTaWX{$Ui^Rn`S(K zAP17!o6MzL35x}XnGz!7=XX_}uE+v#G<_X6AgQ^B0505v5_B>C7ROxPnZ{`&HHwZnQN9b*Ao zErDOmhE;+^6Br_&8hah>1dkW2Q<`sQR19V=H-yFyStHjGT*xP=qE80(G3D8}^iVYr zR1MRBlW2bU;6kbVu|C%XlE$MHp{W3yF+Hbhb21~2-fS`Y98sdt@gu{_A58TGI`yKX zRBQ!4MSde}IgXbtG9TA^9Ta^~hIxDq(Vm3udnC(43aY47(@fI}l?#@<5%7sdr3nX9 zL1?SZ&x#OqeZF%qw?&sdHXlVcQ#*|&_#HJx@^KL4VTqkt9>;Ns4_!8LlfDStYXZx1 z)1;RiG@zzv-ti!u{8=R9%FSix!jV=S97iWJIke$J3z3b+5NvG8V44RoFoR`Y;Ibfw z>-d1zlMYY~(!>U?H~)_x#Y8^Ln4Kj=<|p%8vFB=qjL}a|3TrlDrZ|1* za+eUs@JvwPn_4YC-b1tUOb6#*mU?-GXAi1XtRmEFfCK`{CU2hlX)Vb4NW9z_2OypT z5Y*1}YdObPU&nB^iw2juCi3v3V6E)E0Q6uV&Rz$TE`~S>FTDsOm>R_{<0S;i%6~aF zzmDXTUW>gv7Sq>uu6?8fVvmZ>&fvh#JoaRg4}?B{hk#@!T90D|vJTC`{TvCl1gZrW#04MiNl9#1 z#sSfK52DZUWi979RIs!3Ht+~uE$$?;j#LYl<*_lD$XoHu`PZurv~1RhV+-AGCk4X9 zsoJ5Ocy;5Y(2C1LP;k z#43HfA|--iEr39VmAwvIg5hnFavtLu)o587x2x&5(={&(!E#jEq9Acaui_BtB$#-2 zi92PMMy09!dsge9ydpT1XeBT!WzA58i>i@uEy~AzQiOt=r^L_DVw$iP+6FWlaXMrm zJ{#TE15LsbUla-+jAirCVkCepuQ;IvL};i8IT+!1gHojt*Hbx8(jO?!jS8Eh*eW?z zNf^d)M<9?!2u>sYDA{N#Cq8jCeFYh8M{l*}7YK!M?I8$B0UH=O6qXL-$6!fpN~NKE zf0_EFmO`xpX21y#gA-!nAkBDhbfJ#;M@z}GviDN#ln@{qQJ8is>LwbApaNc2$cbWM zM>`$~qf3ECay<7miqcYRM59!~lz-zv6acgaYrIuCAb4W6BUVmqY6<*luuq4^604oH zT`QfAF4G#>YEaM^;2S3Rv(=o7ven~+9NNL0|kmfD&JX>D4lpMJL(>Uu@SS>lC zwH0epuW^KT8d10zEgr(Ry*Ua8TL`d~#51H@B+bd`If-6aX_15)De}%3$%;}Lf_Nbl z1XB|0u5zgOCTtu6c#*ADjN~MmH;a>hz~L4IewMp@n#!Tdky9O zPBm=e^(7`@kBY1uTaZVr;u*{!2vHaiWO}Bv;I3qqPywVx2SzlCg~?--GlVhMCCj)3 zA-PqD?{S!&%o$HYiU%n-NmKr4|NKV+!bqY7^0ZMW$1J~cEfIoCl(j(i;EMslKC$Uf z0v`LGN@jokk!pwkb*}vtd-GKD`fF9a;(l=8wM?bTD~5A9b`2;=xC~?9Rz-Y~B}KJo zeI|i97c$NE!g`0H=xcmbnDb-Do-P9c^XLYVc@3r3|3POi#D>?KUtaN22_duy;ae}& z03xkiF$fZ3>1vA$dAga|0sR2!Y5&vImRdjGa2Fh#vd=WU0ZGbZ;9E&@w?xs9DJ4&t^LdQ-m#VtxPj(!4l9{^*DJd7*ggDGcBo9+Q`%n4JZ^oIIY5hc#HqKq<|qh3 zif*~cJ3tDGSCKO_W%kiA!{kf*T94h}`B0hClsJjp!!g8-y||)^fp4u25qM3F7zTUN zSj13W@(63KLR7#9$a#9QJz2wXGM2zSB0Z$ukG}Np9iEdYdbJK31mB1Dj!HKsqWYiq46^`Y{^Q?@GYR+sRk(P$^9y&1$eMi3- z$krw>_8_D*OrbdrBOxFy<`YA}S_~XR92#}#d0wXdZcUxz(>nSE$<#TALb4-m^d7z8 zrb6J891EGKc!~m@V*)8jUaVpk7|XNXHYTQ1-@g;Y)by(5dVgU6SSlrqI)znIU}y}2 zvYr>h5QHnp_I=cKul#M^isVOc!IlJX=WnKYbo_KgfMMb>%utBWg=;iIcqxlJh{cF~ zU__YPD`g{-5OZ+ub~ylCT9aQb=l$>8dl$CpbcK{9KydArTQ${jXD~vn1Q9<`-lCjB zT6=}Zy!LY-n4aJK+iGL@Q+C7(IvMK@l~`|>hglld*mHld=&ZfJ`JE>R?5UO`_x#oR zfyL+U{(g>y(%x)r0!jl0*Ucc3GyUBX!9W<{oo75okjkZq**Fx7;VQ+Q(#N>@%-8?U8|R zZNWwXPKFv$v7CY^$0l5itZiy?ua1f9>1!*%a;a{!tJazOI$EpUR97CPB|ZDi!vlHB z8MWXBI4dtG4TUljX{8L!9U3wbF%qCq4&@!B0CSk1iL4Px$?;}gA1GxDBvWHT)z$v_ z48wE}Y5AY&ng})k$u&bBAc64WDakYfaij5YZP5+^bF$0cpL~8G2k1g|b!@g$UeAl$ znGAcQukUXQ7r`q~xNI~1&&kBiCf7%7gkC5VTdokX*k*xKGUu^G!l-?y%)|rS`zhwX z{+-tuewX@DO~aF5;n@(sT4yR0@G&4Ep+iI(Y#rrE1Mv_^W4SmMGyL(C@-Xl6Kn^)$ z&auo=y&`2WaH@Tbxhu*x_{Us_a^KlAKRZtRd`4A_iDFDKeE&CIcI$SV-na{*2BNM{ zr&~ICb%`G>RYLKeI08zACPBt2ZtMn73&o5;0QiGHB+p+FT>m`DBAA)Y_|6e4enftJ z{(Msc{K7A40@B8j0%0BgpWc(ejz zq}a^io@1jHx%G`8Ib#-=th~ZxHi7pNrbjD(e*^U2YZ(nGJYN>+o|QsO8L$;2>Eh1X z`yiJ&i*Ui;igvTImGAhJ$nL(;8!NL-P`vC??WfdHly03EGmMZJ&yQ%-(yldGAI9dI zCd4C4h*Q&r!xP*i`VSA@^jq@!oQG56FM7GY*nDBr*T1Ad8J_x;igIF-=>%8>?2omNTl2nlNzoF2XZ+k^AT zow;9Gd`B<3DVeh|UYNdc&a92xVi0svz-OA{0oaOL5^_|Qm%BG;lXUdmffF|!j}I=; zdtTvtF4fxZ+q@*N|Gq~pcW;40M~MhpVgw;N1)NG5Cj!O;5LyfWXgCDYIEvcnzpPVz z9pW68E7haha!x5%e?NKmNyMe@CP>Ef(t!GNM0d5ylzs_g`e>px(|7bIe&rL)Z4rP{(h> zdMnbTnSTr%QFW`_oaa2t>_62Fu~w&_HLCoKpPGUp|Dux%?EmLGW@XrF4ESQE2CG(? z>qh0uKmhPtMWj+CtX@N6FgUHm#>|kv_nN48=Gf5?5CZ@J05e2HBme+!Wlxo50hPwx zsGG36+uPf>%}6P51oTe?l-j0frTbelxER=&StUuYQr~~k@dJR787P_n00l5gVvTzG zM$@*&np4`EB%^B={2NuIZ+uD!xZgqpiO5n*U3wW!fl#Pu-Fp`Y7Fv7VL%TxT%H<0( zXhN)78LI>as1RFinaV&(($JQclZTKgEag5*@|!w6Nuv1x03!fJGXQXZVEul3@4LI( z-PUgJ?ddigEEB8Sa?zl;FWOsr?a`1R6=XeBtyru8t0h!dA^wD*QV1apDlni=0+NJ? zst_QAHEkiF()}6$B!pjnQT79(TfoZ8uDWEOFEfPI!u>Eu|ErVVF*cV#bmhq}z6Chw zl8|+CZAizW_E@Jio!E0j5mmx3K9p0=e}KH>`5zCQ)=;nJ^cacO)nr3!Pc|Z2I>i{c zV*lK0T2)^|RUT@-RSAuc_bWQ7IK;C3Msr2_>U!E*dg5&6iAsgyB|TJFFJY*(C~tNG zT_QG`8N&K{z_I%L{Hk%e>W0dy1|-T!kYHmLjN?9nIy3~T>zJvH2)L7owO2xQWu87h zMOV)QN4ZZv_DwZeM^_hVZlQV0>()?g#$bMWM+2Upkk9V1NfAv8^s7A(+iSv6cb`K2?-x#jL$CGIRUdZ~;E2iaOH zAVmsjY^_+la6vT|hhMYswU`js zjGZzj-5=7#UAGaPqE<7c>00&K z)xNB_Z(Kein@7;ADpLSIb>nq2R#r@?8Uy?oT1n$l_0s(7rKh~t-n&&@>s83hkZSNK~21 zxVNOt`{ZDbLIV66`f4f)Dtc;9I^N%|-=4gt7kjBkrHh64Qi`^^=xTa=Iv(AMb_ty0 zJos;*+S@!G3+5V*zhXO0{*--nKn|hJEWrGR-AlvxgvAH2U_iu8cc+`@ir7%*7ZMo4 zt9J+ks7xGk=2L>W{Cu*&xO9+(W3{4EcUJPE$3z(~hh2q$uVIr>m%nD?Qed+X6Avl~ z!#rL}*zTXN(m5;_lKg!f(4ViBD7YAu%Y-$+aUDXEtExiSD8PoVOYa&n35`#c(9_V* zd7N$nu5RwHRI;NKWM`F`CNwo-tyig3VVv%3CuT`7h$7H*rQUj+a|=1a{;H4GpS-cj zF>3YlQ`QS5F;&!sCH8a?^713P|4Sw!_^ii_6VsVn*&wnz-aDP6?WcG*!QCwhH!ui8 zh@D;&F$ROfkxmRrG^uO9gq~to$6i*)3ES}PTkZo)3nmD6Sn{ea$e|5|QGm~ii=~*t z@rYHi%GU1Z(PLwsFQTBQrRL5yDSYBhdC3VSm_dC8jN>$?OsLYWk{Ov1mnE=5qA}(q zsiAkHkM@9cR}C(}@HKE+_z%?_Kg5{I(;iU2W*L$*1kQd!NET{LDk@o|tEWH(#K+Hu zriAGhSTi4u&hh8y+W-!VHC*<<1|$ydHP5=cGaLvw>m52HG=tK zXaFDTw$0_-4c)8-9d;IrmXmku>b_k0vg;(mw(WAew{2{Hj_pz9jvB;0YOGdhed}|0 zLqwa+_9?b~o?GOKx74;5I_jqM^3=1wbWRxsq|6mnRKM&1z>c%=&3KZd^V<2RF%AZ* zbDDXgeGbL;x^C(6Pd=Qtw@dVSo@`BsDxG)OHmP5fJbX1P0%Pq}hSg+MjA40EeC-5s zBNo5e0B8GW(8k-Fb<)maYhI3-8KB(u*9CK1)LEpoG95AYtCRDn&900k2=%Lnc1ONF z6b-tbSkL*Nbzb8ym6B}#>t6h;W0dxPt!>czL=Lk>;=%5#T(`ux4O7{! zS+2MCPJCh0(Fn>ZUNw9jD7Dox99_EKutC6$Dd)y`-gdD{1g0vbyl|EtYjV{|L^h1 z)s3dfr49IJ{L7gQWUKa=dF`*o&7->t{!q&aUH#wR_jwFCiCFX|E}UV|(h*;tYZn$7 zr5@Oble2N0U+%Hr?_`$`FYqp{+Qo3pc3`*o{s#hBi!=f~rma`X?;hd(9?xGq+b=%H zh?d_LWNbk@>TD%yE0rBIf4~~j_S5Fp)~^9&Te1gkewEw6t9O0V0$;W~1y?7dZ{MMD zbaKPzU`e(v^uC=$_}6xy-TR-#EnbJdLWX(3@t@-LPy~|1T`yiK{_T)f9!HZ&A>44W z?fM+=A+Cr(D3f~o?y+lrD@=)Bk6)8R)}C}86`F&;vL6P7J@^BahdVMV3V7xz8 z8~J;5aDzrEfMT3@N#M-;6Nh2X+%s*r0?MFt<%wE8^XbvtIQXfk$i2!(y?^v;ZzP4N zrE#|{$t@f06SmS^O4Sjt1GqFLR|CqQ;QAEc(?9w$+u|K$S!P}1BRgsDOQ{tlzIqOu zg3qWt(NpXG%rS$Vdda*;&!&TdQic|Vnos9yn%*4g%3XWOZyUL-I-Nxnj+=v1qD68h zHAh!C+_xPz{RVn*#GtLi8@-Q?o>UV%`Xoiv13-86)?d}tQuW?D@19OEm)l8HXWbjz zGoE>UPw?MA_WEnf5+u%xj})|-+1ur5OZoxrd0qyBdgti8!&N2Kp+!fJ(b`}Gr-zC~pA6QzE4aaXiybvwYKYlGoYD5%t71wui1W8Jc`4;=VmYB@To|&;XY0)k z;);sIr>SD}ly;qIk?Tn{r-)Bnuhse&Ae5A=JwIS4tdIA`j~tx@&Q?VhThlI;hlWuY z7uUeqz?pdAA(?mDvJt%Ke?O^jyR@xLbGPdQ2Zl}~5INc!0Oi1v+5Dh#wfi*t>6J&b z{gPy<5W2=Cte=e-EW=7JF;PS_#^71-a?*D(x;0y4#;XWn+k(UK5v?Wz?*91&QP zSLD!L@8fpZa_lhwK%e`^|lgFr7+*EIZpZ$`?zwc+T$TcXFwcS^{9U2^2xFgQ?tl<$j3YO;0fK|9Li zOVF_Y0Pgx9u=Lg6wu{T-jpZT_IYVD&k$PT_sYO+s2M zSB1l@uH1Z^YJvRhcad#t_^8_vzHg--4;xcGTahm7_2f1BsprMNacFd>Z}a$dy~Rh& zkHjf^CNrN&GVVuA!j$WyIbCMyXDwZM__q4}Q=kF4&7pv4La{%%p{=lNft$eE9)u{7w4!py94Nfhw04gK5e=Hqxd?JnDHz$Afj5SP7x9I)6ZjOxC&BA)D$ewKq zgcou&6s~l0S*zRkoghFVl!BWiF1}%661On;4cU0QKm%oPsP4sOuB>Fz;_ZhD1WoG) z%q!3XrG#UIG{3L{OVC-+ag7M^Ieo93RR2Mlg2iA|@UtRfe8EC@O@8jrNOL zRdod4We3Se7$Fx>FQO#f!Z8^9#apB_3&c3J@>(%go=Kj{3=j?*rtsRP>6QenUEkQQ z^ER#}kb!Xv#B8Z#$W$se`{t)OOPJj@h4sM`({&xjvEP(1P8>vPAlCIw#>D8F^MOr_ zYmar-DAsr~P;`pEGS!{DgH-P4u9!_Lr=8R*!_4{Q)4LQS__xl-D@JBpoMg^xnaL#9 zGLlI-XJnGjnVDpBCf`|^WJx9`o_T2EV&hWeqvtrs1~6conqnSoQTjlqP{4z|rkDPh zbE)<BlLX>4NhK0CYdTB+jOR!G9&~%o8DagX~O2@wKuuI_ft{LFr zO`Rd;LDOQ4mv?3fONV?w+f-Lpj2^ChBstxTgu+h5PS^mu$gyUxsQssdrw{$jJ1*46 zbpKWl!8_sFqnO&ZS=NTGMHlDU1COy@z?(Gx<{|wmODBTIVz0P(8V0h$V0+Hazwx1<{(Jad12+1vsvE0)s*06heTzbNG+7^ZD(=H*??nyfD<6Wbft9O&Ii2 z=^oFLrI}>F+r?2#f+UkN$&*aaB*(=;!@cw)Y{N`r$tOogX4jP~eh0L}-W4qnU$>t> z{PF(25B=BMz#1Q*d+AqaNmIV2%rJ8(0ll|(IvDC-r@dgF<+JH{(8}6#`LVB+T>17{ zL%&@+l5%h#v@eMfe>V27EM$h(>~2bynllMg=kroIMaKDJI5NMGB$A8*s5zw}RT7tx zOC(T)g$koR2)|yR^LMaJnPW@kBtHSFDL!vRExMfZzM=PYUKkH%=kVdJ^?X)|P+0VsHGh=NnN6 z2v?+nL$fh2-8(Dw$isCUy1TdiaKU80B0}g)r5VLgloV+&wu=a31Zzxlq+SH)TIwpL z;cYF$yA-%ct*Y~xx|UaHrlw#+7+J|=*P>T%XWF0*&Xr>6P)XDr1n5XgOmT?@M6kLP zi>$w+G2I{2MtVH`b7+y~*LcJ4&*x2av+q@pQC(h}l<5ou+w+73L9HC+P1zn)gv)w1 z!|^)oh9+MvFk$r&%P)WCA)mmf{Aa@L2cv+3PP`Odl{35V{2m77RNtL4h$P9@plehx zmBOZ6fmA{$24I#5LHXFdQ#_G6&zE#{SiC7%+`Sn+rCP8(!g}`#qoWjyR3HuG630|9 zs1n!i`}cmKVW%tF$7O(rDp6JJfRHTp;+g^hc3DNAeACg+U7SD61WNSpM|LqhqO8DDNpX0f zVG8)Db0HE~a!{3~%c_8cV!omkds!R-$k&^-^6h*p6|pqX+hJXOs3sNg#@2 zfx9S%0wffJP!%H70SZ;LZ|Y36bS80O`Q`=)aAr3~YlTF(@TvqD#;J;`fJ{OStITu+ zyE29A&?NAC=4VyKyu#mXQ(VZNcYzNqWKy^?Q3Q$S5=&eHL{P8_2ABf8;om!}`tus- zEp^x);<_I0dS2JKok=;Z``6muPwD<6;suy``K!*5kgYRuH)e4c%oKK_E}=;cLWXn% zvj{SkpoL8|L;=ns1oULe`K$W%KPNWSd_XI(Lu)4;fEM`sYP-*@qtq4P=p$wq?aab3W>b-8POMt;;!R{X};5N5JS8b%S;1dod(6=Jz0&VkN_-1B@E}AX~4+>QnhLBiMs7zJT zpi2_z>FuB3>~x+pZw$IN-=anLO%aapuncR28gdP)C?ty#z!VBIO@S2HIpZ3uWB-86 zBSt)s*BEPr%ZCXKOi(}ys!C;;zN%1VnY^^$mYE{Sa7bjXXm|-$cgzv$Zz2GxIt84F zg*1%`)L9jwAVwwZlEEd#gj`WR@vTHS;74mT&}n$FMyprK*<{zlglhBu1<>HrKf|Bh^tONa1wZy$kO^iiO9g?B-D6Doz9Mq6P1?J)k?l=khJ z_LXC8{iX)(d64Mz<5S5t(LRF~p9awVBCQ(tD^k=FY8E2^4Cy+?Ydx;cvE^)+T zumdVZ4WVHH)GUF_xunPGc=@vX|F;oSn<=x>X!qhsX3RxZpa)EsIL21kG{6{8B{6cK z7Xgl)E{Dj@rmO0xq)ZZ7sFXq(Lv_eyhM)#qRAGUK49rloN@Kbetg1v9h$<90rNBsy z!T~D_Sv8~)ohrv&kky?m8VR$xW?Q?>D*{zETGLrX>FN|{2w zjHN_sw0YAw7jJuq!_Yf>q`dDKhJ$>!V7EIwCCl7-0X<95CSpFd0;&3JbGB z9nE@0zFdNp)I@t<*Z&7;Ox%le zG)7iOVN6sw?&-EejdCtZ43RKc7DKB=;)r1@uxbQ_-6M;mBrK=$5PJ z6&lD1TAHLxhX=?TS?7}XHTWaQ>j6g2Fs6f71ppI}7^*`toDfw76Rtu|XL?ytS>fjl z`v3j52MXeZs!-Rg>a37iW*jgfVyZ}oYTlD8Fj57hVE#*y4;aK^S(+?K0DVA$zvEbA zk%|RQ5g0mERQe>wh#8?ObkEn>E+Rdn4aKe&tU$uLib6E3P1T7DK7K=i#*9|5i*8Lb zz=dEyA)x~ia!uo$3Ja(!rC`7ri9(hk73KGV*yP2NrV!oBE7hKbsp3hPRs^IYuAv!G zg>Wc=rM}5R^1_r8V9ZzMCL)5i&2}a--}FBhNB^7`3{mZ88kNfn6RR`3zmt&27&&;i z=Yj5ja_SB;4C4Kr`8&bL#maI1IW5WCymMG9X@a)Ic_v5h+__UtZi)KL5thZlmpJ1T zyHP*H{X6qqjgb&{?@V_2Mo!#0TtO7lIs->e+mREjKEB9XYgZ$PBvdC%(GTijh$JGc zAxR~XoPyWyGMKg_(^sRL5D)_Z1OPHbbT$A0Pj#Q_zkrEhZCV4Y&Aai|p_Bq72`rKe z%mY-a?xH2>BLbuc5vm4+tMz0HoOR3xIT`P)}A*VoviH(2PfFt@^pv9?0oElC$(C36~;npT6wDs z16g}5t%3@q0JO-8q7JeE817A~f+hd}BLFot000e8d+%*~-rL^Zx9!$@Y{{()I%+3N zXjwp8dpo*y&)W+~Mj6@i)fOxo0t!JCh$29^B48gdfS3gQ&=%|m2|(-aC(o=M{0Q{P z+$Sg6=vc3ybGFU;!WPon*510hx3V!vG^z-KJ`e-0X>hv9GYSZoLww{@GOnNAI00?&WA%C$P2mvKQc^ z2n&oKJ0&NGmj!BhAw-GoA~giOCrAg-yb9`S`&-po^e#ih>;v_xyxf3FKzPu>aVeHQ%O%tsVvpg#P1CM9y|T%ZH;$D70kq~rc5fm zp&W$M=?(Ej9Ap&I5FX$QcnX!ZRnAJ`ySBr7?GSsE9tyl*3ljMn?6$v;meR^TAMc;M zCw`-7Jon0>^Qm3db(=66fRu13fG;8bhv;52HY_>5{(c|oiIRLrVQ2BzKVjz7uWN-3 zX^dE~{x_0e`S04W(QZ=BYzi!Iw((rN6&Kt4wxJ&z{ESI_?yED}@7dQb0q2o-VF#~A z-IRS*XuBUR2L;)>7f*Oz*523pwCL^FXZu|(`MhUH1&sa$*kfJb2fl4B^R_%U<$~k% zmrd`tZECu#U*(Qd|H1m<8`EXGF=a7W?@?VJdVDbWzbx+zU@ZN;;f*8s@YwJp!A-J| zm*HH}C(a85f#CXWM!F|>!8?$&ZA%e+KUQTK-&+ok5EjQ~H^`}JLpyENw`I<547ajw znwConTU!MjsXS{P!?5c1XYH|H4&UYxXW4zZC-CO(cK8V2Q!})s*|iS&bP($75FjoD zi}_Fa>1I#6DK{a)nK;;^uir6sGP0*pIzj0+^gBqrr*V(gQsHduT@1vwp9qIH3NM!> z;ttKPnK&=QwF_&fJTf1?T^%h&O+7zlpM>k(+Wh@(X}AP%pR|TEKguI^)$q+)fpgXd z^P<{Wgm2J&n@xqo9KGoJTqeEhVxM$IqpQ4&uLQdfXn(fRCRA)D30Y4A}5^=sm)Zd@&b2A&(b_CWLG^ zywj{vW0keSzNy0$jER-ss84mnRfn+FTm&UN7nL2Vve&T}%zYMcbacYrm<$a9ZggD} z8fJW}bx-@xH2pCjoP2xCt6rr`uIr6-*|hd->la_rVI#1mYvF&{+$Jmqwk$0ehBh<|Nlo9dLNw}cC^v=Q}fq`9_^z|wuhqfzuk;=9-%_2`<^LOzV$T_O06s7mXn?-Sg%n;i$ValtHf#;#Xcuv<{UYMN+n{sbbDxjTU)~moEbe@Y zn&M^G?$r-oa`ul$zkELTT#m*4NQ19gvu^!xIO^}o#?oGT{utTyxFXu9u4ra^|0W_#KAZvA2Tl z@i61gKi+0}HVp(jaeO@tDSy*VQcm(_noVrg7%@M4|KscR-`my{kyFIC-z6Unx3y5+ z%k6s*)4s@jmFavlYf^+hZ@0c}ABN@{=WQ{F?zRWOVA$@q!=kJQL*9DdraaL34U2{G zoh<9Oba*=GQm_>n#S9d@?U{S^lgQZB+E`XC2Quxc1~)WC&UpXYUIF&ef@|mn4-IU- zHj{6Su|G)9&3>3{3r_1!1tk|T`UyG1`0 z&kalp92I^{4Bd+~PT~)nHnuk^v3ETna^yu&4`uy}THW@n6t5g3>Vfu$pw)c$@Wp9RMXQQav zgP6AUjc)D4?$KM4@}i(R2gP_VCKlSXz4~3~h`irD=~SQpTeJVSB$UB!S-OFEw8S;Pky)4kF?R%>&`iT z1m70*Si3h<@5>}UyR;&SA+0)B|wZ{hA{t4EM+# zlm6lh@p}0XpNXHw*2eqWQ#krE$CQ~Bt&cHHomo}O^Eywd9T96W#N|)Pqi{E0#R!tZ~i1{MjT`==_@{~jX(rB*J$!p%3u4%4JGXgaZH6?Z}U8B{jj^C4(Pge|<`yDzWY;dT7*SQdN z&-ntSi=K2bd5-%sIfXLAR*Ux@bJWcZSZvE}LsqB?y znUEEh>mC2w{zE!gCYTNFr~1@5q$f&)8hH$AAXG69Au(VSiJz|_rly{xTO*#W6IvcV z15X1E$TOxX3wn?|ciUxS8$uNjAOs#@Mr=RLor>nu4HDnAg{XJaUq5v*wi~D;^n+t8 zaPLhhB{Rm#%SYt_f+SoX`NJqRDH7VD{(F@Wlzuym3CigiECicp>qO2TClXagjG zG=PZtgT{=r^H!%pU&0HGNmoxxJmYHX=c@J4U(mBoT~kriG0#!?7R_Ibr>T_D=jpaYHX%IAG@ z0o&SxcV9O4WFNo%8Li{%UUL)d@D)EQ_273<_^ttduU*d5m+AuOV;^-f{2n@WirOux zdE=kC`?&HeM6CY!V_t#}FK5zd@rzMO(r&9CmGVNVZ)So|5`x@tn)J72~|c!P}g=CHoor)Cq* z9qkz`5w2{H3X91Q$GeI9!CXhaO`M@bNLk0Vhfx=sl6mOD8e)eg_Nj*l~ zgc+MyrVNC25MRl3i=#%67Zg3CabIUZn@~@p4Yf${lR)B-JsE5FUR#?etPy&2OS^Ix zx!-m0<>RywWB@}m(rTfl!0tJ-HvE+Brl_#OJ|8(555jn!;2rlnYnhY0Ub3Z=9j2Vl%B{akmQD$Ny z5e;CAcH+Z}n@Q1_X?O?lo6o`v2;+L{xw71nfgk_}QQjsB`)Op?t+Tu95<9D^p)=PK zqB{z?m%YxQ|NX@Lt4g46TDJ!JtiAHq&%yUQ3&p)V2P|n0oEDGPTM+c?lvXkqK&QW0HBXj7~WD*n^ob{71KVjw zqC9uHnYBzX#qiWcpI8XMK-J#88~Q2UBdp+1!Snn_&H3U21dbAP_dH^P};5;6BkeB)5S=^f=u6KLUt0l0)T$ z(;NEE$z%*i_*_D~_+|Q~*5qA3Uwp$#ePxcA?jOJAZ#`8jux+ZnJByDk7i{%aKLkFm zV0&WSTeiZsR4F|x53Kv&<^;29m!3WEdQ|EEc{sF!GgFO1^qAV2+nF+r*_-ytTg^Mw zuyVZO#vt6dmc+epF-6lxnXFTOY-d*XFUljn;A0m*T@(=nOp{XR(P?#-K-h>SvUsS9 z;z(g7lsc1Grx(!lZP$ylirDyxiD>2pxSIiqy8GWL1ia#+pnY^ct&mEk2&v`ilB$!*?``jnD0wPm#&yd;Y7c$eQd z=VZ+%V2V(P(mN2JC~nYLsFL?Uv=j2rrHuJ9DW6MBd|FQ2p@_~D#EVT8t(#tPg$?8+ zM&$KlLQDT#aX$jwC9?tufruhMJR?tJ)ds~`6UK<=UQ`t55h$4^`_m0!4SapWX9V80 z2N39IG3kM#YMy{6_@2PHNbXwi zd93C`Dxp&rcnnAVIHeP<8UlX}{OA*cukPjc?4vIRA8!xw!R9>s5zG5}$vG9zw6(ju zcC9G>7^WzNKXfHX0Dklu>uxT3zbodu4tnLa!>@512%vxFkVcJJJsIT!_$W(fd6mHx zKWuKm--xk|JvelfY#_jk3f7T%rDwCU4AV)AQ2l<(JQ)!FbdAd=6oNanK96qx8(mAg zPUq;%X zqAd2Zpa*<*tp34#Qa&!#2`2`9XxFHACz}p}53=ag@?6yqaiKN6$F`;o{f6j!wq{_= z=xY3GDWjMH%uAV~obpk|NR%Wfu2pw zmZ2?&r3xa$AE|uBEsp@8RFR~LB2^Wssz{ncsU2}vTaMntD}ZT#Oz*QUp1&RJ*-w23 z*8NH7y)f(!>$h#>w`%22+2tiNIU7rt2v}LpXdgFHAfz-LO)k5KurEHKx^>(huEf^% zns&1p-4uduH)koq(bikG>MB_EDc2^v-h0@;^4`Jlvq`nE<-@bRCj1gs#%#>lvTkSJ zNe9xT{nDOFmNqRrd2OGHSoW9is-V|MX)bWy|;JqHkXy7@80Fc=>?mD_<~kYY73OYK__q?JI(u2KZdWa@Ce zV5J+RnnN;XYhXpf!Hohj2jhGRPpQx#HMb%_a8byS|_`Z&QcH`(r+r zI|`@tt2YdaBo|8yafah1Mp8XQ%NH67HL-lk{E%9~$6rtt_wl;!Iss6w=9VXybl7lv z;8f+weGHS7MHvPQWEV+{kRu)U!yMHZ!J)%N#o~1A{lj4-=0r#>N-+t7c#1WILzT=i z5kMbuA0JoM^7J4C4+I_oq_kA-N~kVrM_7k>m*)kq4hb=VN}x?Tq(j8Z{|4B34vz&GFV2lD+NrRp&wajzO@n? z$ti9vh($;a6D24qZPuMA397+JsB3kc zNEXuPMG>}DkrVuyJ%4u?1dqMp`^z6-2Y++>UEcSXtrTdF_vZ!i;vbHI9HUz(PwAKA z3=~;_!AH|7mPfh0nuOxP5YFzEtL ztteUml;$`H!+Bq!b=pPk|2M-8 zmFoz)9sNr~B12pZNNtia0mNfPlgqt#TR@L_3aO|R#r)D`$Y@4QQ?E+-zT&TLe%L5w z6FfiN)Jg9_s^irDs*Y*t`F%I*PNA2d|0%!TX21H+RmrDq#-hvrzLgtC%9K$5ek3}( zogQWXtBb3;W=!OKb%rMxX7Zxy|O zEX1k^DF6WB#C7AkA5WSnurULKav%M*P4w|5hMR)`p>Ohg5Bx$YDjBxV9fgHnT~ zSSg50-!hssUcH0uM6O~htfWG2bU;89^DE_qIjt#9K#5mFUvX7gPfbh=Nw*=Ab!)KI zxUCRe(d27DcUF!|G*(awq|k~bOA%gi>v&x8+gM_!;%&4QSON^UCl{rZ#H;{q_^#Yh ztOaC=X(dltU0d7z_z3YVbnt|PY%qp!u=E+~;3W}GNePpR&Y6XTUO!j6Q&D${*u5VU zumW2K;@r+GPGh1X%=ivUyr#s=I8Qs_qd&zoAc=5?<^osq3_A$40fk{!FO?F05(4z# zu2MSx;BOtEZAI^OJq!jvnBW1sM_oZz#C42dcCJHm?}5Z}g*i}w%{FM{l1|!Mjk;Y- zi9NtGK}jRt?KzGCg$8MCuo|yCp?G^a9gX8eax9I45pJqDk@bVZU@b&(AVez#VVFou zmiy$1N=s{)!obRAf#x9C5wXG2x|< zNNpTekmXN)PpMZ)GD9!rH>Mx@oVE8`!5nl3AfOUDy(J-G6kMAru2L-I1(WDs&GPQI z8%48{YlU;nj|Bj6Iq{{5c5Loxlm?GED}Ekqd8@PlZoY zNmox>*Mv45{%?jKt+U6d(W-o zXU<2N8M!o}ckZ&RDLAiSZfy=ZB;}PNY!Mwnr;X1+?-S@eI?F6%NQ0wJQi_4b-8qH= z=oHu;Fd)bd(@q(k&1!Bh5_TfiJ3E^0DRU~Tk_$=*D$(3}1@puZlL4g( zhRgjX*#jwOUtVGTvQA(SRU&wGtsHK%!9q0O*SuP$Q8Cwi4xjHLRWM0=+*>V#dI!mN zibz%% zI_=2%JLVgnAv)Hgj>`gclr9E5_`as4FuN zW|~VA)Z>sR5JMV_M_44ED5#M@j3XQ%2C+sdURcMQiuHg1q6Jz>v{P00@&zQYK64~a zfI^wj9%o50EhJk3rjQY{<(b(DOLh=Nw1ARXF`O#e4}cOBLa!Exo9D+6($_S_JVz z%(NIIq3F$N+6;Y~FkJV#T+LQ!;^ojzq2BoJvy%h~mFIGWw*WIKFa)Ey=N(w&=}9<1 zvcJkPNOGMsQIF7?+skHomIcZZ?D2V`W8f_S@bjWG5i!Fy64kT~u@`jd8ekwogrQ0b z90j^-tPr+ak;2sa1G)^5@)z8l78USwb?M>oA)1ezQg9Syat+5G?I;{Tt=Aw!MPyl5 z;URuVeKlmiaU~|KpOHR-g`6|2&Ue1j!ONk!4<8|aH24-8Z$%C6MG5hf`47PO>A5a% z(nVk2?kGb@E1fWldmVe=Yb6Pk`~n8A1;44fEPCTm>hYw%GAwSlNtb|L*?ba)g?}mN zK7TEcEY#4ieC+bmqAGhKMSlKPlYKjnev~nF4u@`>zm^{i6sef|YB>ccdhwP@NK0Zl z)e!9}G%#g5|Dy@ObyfGYtK`h8)sR}1zv_>t*1-TlbUij59uI3F#!DEa9M~eT$2>W_ zrIDN|!OJ{?K5FHf^n=h;vZR!!S`1{yW(}TlFamfilwLc++B8k-kY5Kma^ zrlm~08(N-!lk2}Yw{Blc$!)khQ7K4CqgXU{Z?9Ttc3xtgPMI(kG66$y*{|(jqei_K zgRha5atOE#BgpR^lbLZXfLLS#kVCI<%mr1odK$WV-kimT@b0HzWj;}syLK6ObBc(x z1`dS%J(t^s1uOc@*cv?Yd9W)oZ9+@B@(}1POj_w&GK0fz$~zkTRM}P4G3yfdz1rrd zxBE$mrl4XM*XQ(OXsX!k``ApYz7)!)oK#SWB^FD|JG6!_b6BL5djPw9EBoasnm*cE zYT>sVI)UM-ynA0dg-TMmO<82H}yKN%k!Jynap;lPn^vLQJD7gbni_P_u*5D)_Z1OPHb1T_EvUR8do<^n1Wc1(ZZZoiDT5=vqNg3mX| z)s8}}bpNuF$w}vY1t70d-+$5Z0f3RAxS9X}JupjxPQ5R2NnX~zk|rd1ThqXwD7=1~ zO(FqL>(J+96$)bT(n$mA7F&IR1F3&|_6C_&b>eg%rdbGuZb2rO>oPOv}R)wF+2FKmASrV<0@=snYro>W@FE} z@{5hE$cS;ZmFv-4h2@%-MXFS-)k-^7`dZfdOHvl=(dZZUFSngJZ0o3sv9-JPwJhpW z9@U;b(e{y^&t&qs(K1&Rr&WXQSsK<;M~yPj*CJk8wyNwz(zMM#gwE)|c)P&bCVgqp zWO40TT4tW!ozk*bmGM>c2)fc+zJxq;wyt&HWH`G z8R3bJ9bbUfu3oz(la$PziA3x`1RJftA7(JzQ;zEQv2LT8`#i%+ryLC#NHHSJfWmjm zLsbsgDVyCPff40}Gc--;Cy9pEB+y78e4SJN_TaU(h2k{=kq(Qb=vES8BIsybrAOD* zi8_W1ZE#dtJ+$`LgCcAtMVaU%16J|6=L`t$;oL5DxsA7XJte!gI_VANdb+P!I(XeC zBT;v4@e%B0jjwt>vfqIck2&qQ2=? zR^oYWNqy+@*{2vg`pvs0$jYsb&PR9IMao^7kE$(yi&n}V0B=!d@(!#wWh%s2>Ho!L-7iDx9hB0Tj-P z)R=}1_$loMJ%J$DE>KdqqFslrt4vxs-lhCuDJ9qM-c^fz>!`Oa%joIe%AVnDr=CL` zE5m!IfmzT5R1D=FB5UkE#bprkg2$GPg^RR7y5RE`Nn#mhziYB3weS zoRWL=KH3Bwx=yVl{d`1qNQLOZ>doby0)0PTk;uRH!LKB_u|V@T-1|KOFs2Z2Gn{#P zP5%g(sNo?KnNaGTu)ZFvEuP?AJ6$EMs#VOigER^IuG4<;QI+r zz^)KXVewFv#F4^ED0Q;1HZRSo4&nOHP!WdFFol#~!rc#;p{M(qO2n5PE7~dty>wfG z1<+xn{eH*!s39y52IsND2$TC(yi3AOX}e1PcXx(Die-CPFeZ3 zcQ24#w)azp7>HB)mQ?X!UvZ9J6t!Y)jeyT!yezUV{hB`X+L3R4O8`Oa8ws?-rqi>l zeAYgm_qY>Qk}?lt6MlCV*tmSvug1kAJGQ)F2fZ?zs~%fKYS5pDwG-tU12hdKLNNU8GuA42{+y}_>;AGj>Nlu z8UNCW{}-`+?N+8k%!>Ox8()VC{hlHDb2W5|lrqIYn$ltMC)+(a2U1~aDq65%<(G4pw*1k>}WxqcQC8=s*QMNpwT3f#u0xYk2; zVPH);D@IH8R6>0&aL3FFAOs=`{scw@$bb!DR?)V@?Gsc8U_BNnR3hi|gzDTi8}1=U zT?Gf&ggNvjG*Ckg69^999@q;3Tn_~j;))s11>~!*9E=X@`7urvxmNSCWRXr9Vd&2U zzefYh;A0IE_{zxsz>u)BF3z)7lNQJh&}Z`mC168Cb5rs1u~iG`LWN%ZN!%K_zl>nu zO}8JeJgj97sgL~W*8-qExE$OYv=oR7GK zY*^zlJjNXoXvGkiN73f|4WoYBy?{?g-rlMF{b-8;(B%>tEVkeA#j6&vt8bm2S^>M* zvkPw5hGK|Oh8R6m!&y2or@p`FcXz#KHL!729q)hM@A<%eT=`E4yVt3h!tScZ+^)%$ zJ>MIus8yrgPMt-nVy7L@UE6DR!lm&nt4zP@`%{ua^C+LpN#*t9%s%9Qo^pe_*Cpv( zsa>XxJVSdNwquH{db_o>DLZZM8eJ;Pg}3%@1i)v9S~-3r1oK-MlGP$$r(k{)vnn2IT2;%2;vk1@=df& z7pQ}wvK5|hSSAewT`l&qA9MPV=Cezm9&=V2)J^o*NF6raE9-51X6!x75suHFXHzva%^7~uTf;17=!&?m>x8m7X+1_1UDe+YFU)s^$BIn9=k0#Bgh3{peC#ms4 zO~xgvtb#UUBS8m_>pNunRHj3;BHU-v;QMWTxhhP z_=fEt@@z%syTHvF?3ZSs*ZI%VOBGd zXuguh{PStsVzyq`d*WEqFRS_FJcHx_mVMyICIY{j%QUiA^H`ny_KoHS5iiJ|)$Ik^ zSpU)ah@E&;x&522#xgSXmGvdYioD?~rp`^2BB{9Gs_v1V28i(C`v z3nwPbt1oQL8Hl}ZZ&$vdWnVT?wpY#1Lg=sW1K-d)P?l4YYF940;?2W<1AvQmlmAT8 z*`G65oCVMJCp!`FRKA{n1^U+M)N(UxllmwBIHCjk*3;|!KK|nlzvfqI;o($&n{&RU zw~$)gf7(N~#O|5y7F^CbCu*rnTMpmPe)}OjCcCSzWBQD2S7A^3S?M*S@qYXYe+8Hq z>|*uQ?>wTk&RVW;`>os^G922*&+BA!F$xwr^DS;3HG3xffp6LYQw|9JRh2@lPnh`Idc0tCDOeRIr5sGR*xVa%F52Rl6hA2N(B#i#?AokZ|R@Nw9?A0$+^Fczn&!-JpH~ZN)qtmyA!5iC65Yzmkso7zvx# zbCDZyDCOVq#Xsn`gF2=g;rK7<^bd=i>+df0ppG|1)KTh0G%DzMVVCj#U*_F`lKRe8 zLO5KQuU)C|3z+*8JfLBrW`>Kq@l92p=9=EQd;g!pU%^KfgGIuZrtan7`)~C;t~dGc zx1Ak-yV2v}woBsn+01$*xJZ^!AL$tMznvL>DyZ_sQ?$d45{wFAFv0SU1Ew@3{SF(>3i2_)Vek6~HF5O)Kp6u>A*WutVj(*1G6P~i zs>bI6>iV_?6gmG(>`03&z(I0XUEjpJo8FxL9eMUoyI6nw6f5_Uem{m88?G>57A(g+ zVXKnC0IbR4mGN~5UjRVI$D1xS0)aB?f)IcbFz46_`qZN-k(hSq-GCg(NZ%F%!)>%> zUHZN!zmy@OExgMDOyvu{0uJXk0Th-7a<<3@e*U7ii_6Ti&48c~qFVJ%oVnI!c}ZQCP~a6D*$|l&J}yH{r#)*Ev3%X0UL0lUp>-DBboaUX05s&Ywy(&`oUim^ zz%GCe`Oy?V-$~z#pbP=f=PKU|WdcuBQR|+K`*YqAvS-q^CLp_;KQ~;~8MzgXRU*!CWzIYlsHEvNjYB0b zcE^ozT&EewPhat;y3FPyA{j*NmDWDdM4y9)O?(}`*wF&>Wx(@H!MR*&ldq){&!xl8 zuG&h^4)d)5f7l*BjRbAO^|J_K;_^uGW6hQluH<^GDQ{RbG+5wiSE~Q&je2cTifY+%}ImL5(J^1#_T-9PWu`^1%IP z!Nz!tGF}PLI*`fg(Y2Dr`ywYC_%zbs@#H=61leZNv2G92Ih8UOa|8ESzI*(OWt3IQUWE-z< z>LF3uzFQDq*wS}eAtgly4Iki7!~)KrvPc7pjj8;+b(wt?siv-~zrn)2o=~Vpqek=7 zzyfh){sz#(A+Y2T&E~#ilhURkEfa}BYhzgu1;4fkkwZX!jjA61)1hDb^-DcGm+lM9 zf)kL_&6hCTKd<^Z1AKq%DD1Jc!@NslgRC?RuK>O_F)VNZB(Lx{_v4DZQoK`~XHM%G zT=KHUY*XPHe@gtdPJn~xVlzgzRlvj^G6a__|LmG(irtu=5D|CP%CKk7f3*dKHTMw|5 zr?Fep6Z@c(XwaD91**rftC%qC;e;;ujAtD5f`RZ#kl6};U}(NLarDeU4oG_L5})6> zl*;@~Ex=;GVrptz;vn^ATzErwB+9EN9F(>(+b&(6DCa)g-FrEr=_!=L0=se7sM>GT z4}og9CC6BEO}9fSwDj*8V+TW7Cs!}#6C6n+@P zniit{oMZ#0Lz;3G712?rkeZAjifbTqkFw=G9cso8S3d^1{8M#mnGOpKD^cX~R5+}v z4jC{McuL|<_PmWCbF4SrsG)&1XKik1)H^j~QXyBM1+nlJuGNE5Nb_ z+`TkotQ1j-`A)&K=$nj=>wZB92^b_-g#8pyoR&hvQPASB%4?J)BPdC1Y?^loQ(l&! ztHk)1PD@BQm^ML(G~8mIEhYkm<(dR3WhjRY1pDD`XvPdDIKe=g#2iUkP%z_K=q!*W zEo~Nr(7?k|INqrVRTpF;l!o zxgcPP2NFTN+(EQtF=Y`JLx@Qu_#~MB!MAuBh;gbYl3E$0Nnl5c?V$y8jW<}O$AjHHwb`#6)LbKSxm(~q^feX&8YcBiYN z^Iev~1o8&|`{+~!Q<*9#3&RIS2AMG9je%!CG0eqWZa$I{LQ>yxa7Shn9QY4@ts9;A z!HY1~a@*FZz+mG>A&|y#;e?`*?**90G9l2t;v5T9V{He7iG)Q1YB8YJ1tC}&rzL1( zPLH)6>Mq$dC+++0eh&&a^Z7)(#DBv=zW|sH`jHPzb=atJoDFP551ny3$Z!HX;?wL* zH>|JBfNx`3k2uH+1lKHpRoDcaY+=$M|H)dQNql9B`G!+O7V-|!&}xYhImh#iMi3lO zA``<!0cBY_-1aG?r>*+WwK>+|Ax(Yghd2G1pHzH4ks_GQRb+{-3rm zUCX}MU_UyM_djj)DJSnd6H|+&^{MvJRX0cYl=;!$I_~~OWB&3nDL346UhbDBS#Uqh z9mdTcUoZS5O@-d@^7Z@gqS;aU+TvF2X82&YQZIUo9;D%N)+^1q$M?wCF-Q;EdOc5! zOaX$w?@9yS%D3DvyAYf}!uPQ?kVok15B*1q`#rgz?U$TLr*feSSBLj@oFHSi{FFHy zzwAQ7e5m0khcLI(S>(NL4q93zcD4A${Zhim3N{3JLoMeRzhPRsgzEuwQ3}6SkLk(( zz!ktzxCZj!?>?E@9B;LM-^w>tsWV;UQhO$rj=Add1?3pgKE5V)OL`Gl%idhAW}9d4 z(o6g1Xz`wuChue5e#>uv<`k%M>L$!@8(l43WvM9>2O)3X?~QT*Rz3$%hHiS!ojal0 zH$VLYZ>`+R-57@->hJz75)2{&0D>|xp{RC#Qoi*n26xXp)pscOMeh&(%HM2T1-Z`nRy~6q3&w?ald+I*lzi#z2d35BchHnnnMjUL$_bF11_P< zfP`-@S{?L;dz1E|-|HR1Sjz4<&d)3sJx%tHyIRd`_II{d=;y;Wi?y|URrxNbym40B zbKN4iFAAcFK98O!$m>ga;+}ZPc~@6+O0ntkS3*gdQ_Jix{Kh_Z4WK<1ZnNM~<^ujz zAkL`essD#Rn`f29dH)|l`+6t3o#GMU?cBJb&N>l-<-9$u37|i|HwWW-P?SZK*9Hm~ zaf@C`r0HeKr0sWK@4|&n-c;NitNLYNL=SWCFODM972&&do;JRVrt!L}%ch?^FDRAB zSsxB(Lcam>%TaHO!RJxq8=qIV7Hy2FH6(55DovY6O;PODyZUiQgPz0h4TOjHl>vfvQJ-`?S6h_`;T`O5*M5D|c$2U#DT| zZ2z!szpvKtPNaKm=4kGv+MHUEyXLZMCta!T>5`HzF6rr#lP<#G_jt7ZG@Ip^?!1?% z<)y3Ut!%;J$Ik5`^;5O$-HUBo)SjH1N9#$f3hm!qeYZ08pL(iA5vwKans|w7a`sMs z`&qoOb7jRMYs}|wn3T>u;Tu&F_&AOzUt^PlclhRxT>IRNek*gVXFv`%b0qn5WuIG( zn-`jEJsXeaZZusOxd3mPxzOgLHERH5K%2icMx=gnI!_nE^R2WxudXU0j#Zogs(`2S zMS65o({?9Y{HCApAK}cB$9*B6h8`2k*k)xqiG=HW%+pWYb(;@z&DRCk31I9$TK<42 zU-9>O`GRMAgB;P`^+Epjk5Z`Rt=48MtK~OipZd>&fpbu5`Wg?coU!Y*z^C2i!Ifvg z&=nMRnFpPZmDM*4N>>%`Y{eh@YASV(kQrh*Y+wqkOjE2hLPHJC88o-JT&ppxKG`L@ znyqM)f>>YL!=M}<{jN2XF*T-0NjC(o5QHXfIVi%`h^ER_5eo-oZeUs z6>0-DLJcSiB8DN+WUf6e!Tys(O=)O(bLafWjLV)u!AqXI$+kG>kH3s`Q`rI-WDJ-S zY88N5zP%DDj53_65m;Cl^pwkNTE_pol6YaX%+!>9+h_}eRM5y1O92{C%bXV*rWM?7 zI0R~(!A!{0qpIi3AoXhx*09+W7GnuoF%YGCj?HD52!n}c7WM$?2U;e1C_irWRKGF- zk}Ic2m|_Nuvz7r~GX&%!AX^Tj(EX=~+V&g-ND+-D7{n3;w@7G1QfmMZP&5IA%^)7h za}g$&)TbD|u}i4u-b_3ea}WklmJq50cXM(LNgDvR<~U>3qY^ZUbBUuRF@0^ zNllg0QZlbH*-U7xCL1Eak^-zIL=<*Om#qVNWTM!i4ckS6qmo=NsR%Hf;{Y};IS!Hl zU@#M5iiSjE^_R#jvD_Ful$0Qn1R&|L)dS7rj;aiZc?3Y43l-L6yisWjDAFZ?K-&eZ zV0!Ea4k-*Uv6-iciOUOTexy-Ix(6uQaul;2O-PWyGAJ=QA>ro2j03QA$w812l>W6{ zoiHS=SDDvnlQh!UB_<}eGi*u%<;q#+jEk48%7wOGS*$@pV24^Qp^SZdgtQb)^-2h) z&}T`X`%=z9)VS!+`tS#D>V>fg2o+udl-_EZw1rv*OFhF=ywm*-9Wo@%yX=un!!c+= z9YIJdIE)goe#Tj>M^J#3fS&Pz?a2O~NeY(qXksulJcp|?Tk^z?6#Qt(*3x^Nuu5W} zVWxA=rI5q0dE4nh-_f#(L4-LqLO*A{p%Y_(G;FssQQQg)cY?U@gD-4O0=+3CZ}*6- z1%yINRdI~0&BimC!U>Sx+vhc@y@|2$?u3wWDPTCNPpyCeV-w)K*UyVX2_mln5=OPz z3R$d?PLqJdWAjVzAg*jqhP)sVh3yBximMb{C>$VojZz$t0LuY2-ZjN|i${nLjD}&f z%Lojh&dRJ7007AE?Y901hbblYibez;V4RRhqJz+{sRepDh*ds3cnoJfH9){b(g`(e zX&|6WrjcDiECF9$j;-;5h>Zwvt#jJim=)9-ME)J5Ul9hdH)`bYlHeSUNSN~hEMih+ z6y{=C04P-^1LVLc;!uR`w3t(zC1fDu#m-Z5gzOfuEy(~C^DCsW7^kq1D;;4`h@~ak zOiP9V$KH-D^5d=0aWFH;3n_t0 z^7Qm7EN_+i_ds-J0ElJ)iV6U+0bK|Tse)b2026;gKrcGjfrX%n)$Auol@#|j1rXXJ z+wFFvwdFO=X|2rM-dnP^eLcs>mYb%hY-k%Br$$|C9Zhow$zZ3$oItU%!^1!u*>+r( z*pizI6AKd;@Ib@>5CQ<25r8TH0{d?N|F`{Ycbg@=FWJo(R}35sGopa7u-XQ%Lc#z{ zG6uLXN0-4c0}%uOL7hN6LdHXAA%cKjfHxsqU_vCdSsqXfBd9MM@XvT)UscMi^p71? z0_W}DzKW^HTe&AeZZO((iU1dCLqJ&ICBr_wXWY8)-21lHjokX~dwb&FxMyy^+p>qx zRv!B%_`(NZ{{SBG?WXMh>`qR!&wu!7A{nx*cpn_FiFLiq?LDlYt6?iwA$ynT`YTr(r<+K21m|P!s6!N{ftL8Z(YASUV!y zJgx6|dm5^AW@u9)(n%1Za9Asv`6$A`VV2 z5uO3JNu(^20BU?H;gJv^0~1q(FtkP6h?b7$y)nEz{OhE~qsMD`++dnoszXLX1I52i{p2rxPOBltQ)* zmxqvy6H`pg84=3yLZoIc6cLZ79oa(k+I-}SCz(TFi#B1fQz%bI;h_qiC-WzbQy^?p ziYTOaRu6?vH6dVFD(FcOn*okk2FMicgf2E|Dc)kufy5Bk$)9IvJRP0@O~)rrh@sO4 zan*WCI0;>~QDXoMagmY3Kw$_FZ9OIzIW7a#QkCddsr*TplIXG>D@*P=9Fm?PvQ0aS ziy9C<@Xiv*)2nJbHHB#jgJMxz7;z-p2`+R{1W}aoG@HR#y-o;35NbguFlzPxAZ;42 z)s8oH@6D91y=&9wardVJ|4J&Gd#_y?fyi<0s|#>?#{&$Lkx3=g&PoN+(G&*Z^FU~! zLNdwR@saQg1Fvl@bz)iB^Q~^Ytp|-l#Kc8U(a0(S+Vj-!49Y@VnD}I(MF6CL*lk4a zEuwBU>eld0EWw0;X~|%zaHg=)tfEagxzjXOb8sJsyMLQnC*GIz<8hCeGd_8R(0Xcl z;VPk__na&Qf>jqxFp%iq_TAzp0+znf1uST)rx57_YmiHY;5hD~Y4VmO5ub=#27+ar z4y{&LLAKCPg>bRI>hf7_8a@dT`z`mPZpmx9UunDEUt0BNwUUdT13-!1(hVVe!au+O!k)df*aylue7KSs6MobaX z36gerAZ$XG+%Q5W*Y}sF~Naot8h;?8~TUtsf*N7%29%WlbfEkBw`UC(} zWQwTuXp_?b9;q$*$A*KNbju?p7853n+u=$_fVF4qWIs!-(0J2$obQFANwGxCE1W^B0t*78Ze5Cg#(TrF?xr;WXcI%;C5dT*+sOU3;Fs%jpm0SiiG{2ubf` zqD!(&Aq{0XhGO&1S9}kvFEWWikZ#IZkbOHN#3!y7mm62NzT`xJ_&Bp$o3*J|l`OF+ z;ZPIML=;ybG%FZ>)*YfZ7p>i`#b4BqgLvFsxw#;)B&t_=$>W~1x~#+g&7%38^PMNS+Q;yKGw9g_US)9&kMIw%e>WFxW?ZXEyaVk{6IdfPs%Lh(34ika? z_?o{Uc!-2pkB{n!jlhsl!%8zcs)g8!o}@9fU9GtsQF z=d-|+P*AE!gx%9j+@^WNh3RL*(6LqXjA4rH4OC&psx{jKYM-iF4u`aL%Qa3D`x1L( z7Y3~z4b~IW3}AqDG_X*iN&#Kb$I1y^Y*$0l9Px;AiK7`ym?!@@9hCJ2K(UhA2`zL; z!a@07VY=dKfkup@2d}B83fMLOVs)X>|I@>^%G5yBQGpbfRy9c1N*=Ct$RvI8CPFlv za(jz%nR>#aqO3X=#$tB5Ein!Bkl!k9JJLFy9(blZPU^-gmU7?+Y&^zVEj}7-hMYEG zU7GMhl1wrBaZU(F0-jgwG1J{!mycy791u4LlWHQv ziy9p4qH;nOn`G$UY6A&@IdLaW6N+OC*JGF(;7;V_ylw);0zusZJs-K0A z86dao(>w!AoeZP&kxi=(X0Po0w64g%#Hb_55?9o16i$d@Q*+%)R;|mdK4Vu9%bP}@siF}$)1dssr0IaIa_F1z{OR6~Fz*`^KDuaxtSvHGX&Vtr^ zY#r;GbGLj**+PIJ;!Qbai&)Se)m=>|)z=v8S*`=|7N)nzJcJlJ?c)}rern?@cBQ{W znQeTkd`hA*s$!Ty*mjB=YqChyNgtWU4nI)L(4;LI3m4pBH5Evc>7>#A(y!U}29&@|&5Q)L~Z z>x^^JUtS!wktju-&+RiY9a|xs5XGi0w=};P|FI+N=s7B^)8I3WD;m+ru8TVrYeNd0d_{#4qb>pHq7UoD8RF233g%d=)}Yh+bv7)qd97=Lm$J#0@h8O4X^OVTvwyH7*FYCn=v@;tuj^W`PV3Pf(nn#= z{u^2+6+>YNt_{`5I34+_Vx1&cb^e&BFUeHc6bZM^Si#6)eHep_E|Q_KB3|u$IW#CS za@q+kbib}vK2y1?D{@`U5CUZ#%D7oE!cqOKS3OP3*=j>Y`1<;-)_UI0^qpmiYn-Y& zm#?V3nh6nX%3xbm4H!DBYaVgQG?q1}Z{xREjOhuz5f(c2^;(|8^AtyP4Ho@0wHpe6 zQT^)nVDo#TShDvU%1x|jR_kEg_^;7xLZzBK)@B35j-+KlNSLwKUpQS|Ajm#e1*FSm z9V6`MY3W*Styn-?Ae^xQVBln`2aj$as@(OHbm&^0SxZiaA6SQftD3V&hZpQL7g@FO z+-{8JyQ+nZ<4tL-u40W_n1&f&4^R|Il2jkpH7aP)b2$kPV)o=(I${lLmc|*`5vwCp zor0#Cr!=iumRqQyB&-5cH6+ieAiv0AV$p{CH4_J?AN5dTNs>Ddf>B9}YNo>WOAIqj zI(b zBmE+ViKr@|jZlu9WO~(AF+G6rmql{Z9hu}KqBGW53?75K+DIgTMOJpWmc*N~*O!%! z_Jf|6OlR!D82vP)i?x7;yBDoNqq@Rm+wgrf+o+GpP{}1>V$hDWNyz=26+>L3&XYK^ zV9aVo=wltB6PU5yV^G)y$BZ4FG1V(4kvcAAirQm@a)@A9PcqK36)gTcZmyuLI%5Q` z3msmCaHB$hrbrdbkVQ@t`<4vxzJ$maRsT_l(zOnpP8PZ1O`4}*b#Av|#xs-6R-1eq ztBv_0q;yB3a3K8^ibrwINPVnR1{B?umJU|JiGZ(byyj55ariNDtyz(TTVH|Acc$a{ z6t!jB+g)5YKy91Gr7G%!Y>T`*3Wzp6OJ`lf9FiM*!bgZ?)jU{Qa{?m)tHZS2@wekv z{c+oIZ!;DC{=AO9I|CjetTJV_Oy&k^F!sTRc+NG=jE*j~Ix@p1ip}j&_P%73p(}j{ zncKi}Z+UNr-66P&dvh*jBgoo|4AyHN{A)8hmCzAHx?3a`$Cc{+L!z$-X6)LqvrXpV zn)k#>Ny;8p)@AjMGA9fv_NU*rdY2>4xaRgt+&@Bz!ii!se{fbe1fS{Yua`zf>23ae zEy1MNy;bcgJ1eI(ceRb(+xK>?8{hAoQ&cRLAKqBix{V}UXNDW=8lA6)rcRXH9cGo7 zMVwq(>W^q7l3RMY?zh2?_u-L^w5ZaZ1&PURBk6wI?$6SD=?S;e&?~aj1mi-yEp>cw z#PjXgz2&WMy=6iA%o>4l7hBPjBgQ4MO(D|qES}De4NM~>9iigbJ%MJfJ2)+ug2>RZ zu#{-5{@3m$`_y?W8)O$WhuH7l#q6@8X^DmDqBOE>T>ah!5(9B)ilF;~5lG9Ss)XC( z3DKv{Lb==Axzfe7X>H!)Vw7sgHlhfrJG)0Tf6O}jemk(gtQz1@|4q_qSKPICTlG|K zWt+D=%z%WW01z4ol7jChEt3iYHs62Q*$72# zE!+29Tg2V}DtuQKpt&y-U?d_Pyu)i^;#Jx}l$2SZ zk$RybQ1BF)WE+NMM2JlAvM+UMc5sUVUYTa(1X}H;%;KdG8zA>{Ld9Luh->h6UWwEQ6QwT1@Q{TNFkBEVj~ajGO@shk7a3$XJ~Zv)#MG zTv8|W>A2QX#?_c0CEO6SLJ`jA4l0?)8!|=GL$gy)s-pUHYKWiGI4!1QLlf2ttOQE= zxo>CNY@HVk1*c2R>`d+WM?s!PuyI3n4uP$ZT0`t61(0)0uu_8o>U%R1Q+5QH2w0%z zPHmb>V#LrK9T+g{wB-)1ZC-ey@!k_K((BCOb7dGTqRK8D1#{|}m!jNM zCB1bGP_b(coKH>?K)x zo?&nl@sSU@x%ZZobKX`=I&)tPkHX>z_{un!z)>|}7>R_!DH1mA z1JDCW3f*q%(`(L)UyCUlUX+Ry%~^l}*MbA6(P3y|(6NoeJW`)Ba3cPmV4U_c%!4ri zVj)ChD(hgKo~Gr^nZMjJ#98OI(&aSR0j%YEV^bC?C|n{S;3d)R^xWTe!eUWz)4003 z_=?N<2vZ_j@STz&AadLa^0fvws~u7>#1+C>ini^a+wN2MM|$Zx z`)5%pCWlt3z434pjlKj7AUqO)p$Z9~;%4-^lvLl2bf}|;dek&P&x8>%PgT+&2mo_V z_F&kFvhm?}tvy#W6?yR7RNf5yQmEOz_Q+$CZ|7r?Wrv*Do!~} z69`gx$f6jaILZ(wlhVJZ@rx4A*ZGk`J>-@iW$A_{Th6CaXate)>u-#TEB^McWs8o4 z`&ZtR6pj?0YEl7BIEh8V?_|F1v-kL9Q@c!*zHc#7rPJSUu;zy`o3+4D1+k3g9RPcS zV2lh<31NcZy?EBHWZwS2pYy_z2s1P|7*V& z`xd=gZx-wvdT}oc_NK6Gz4fG!(q9xh~DhP9&DG zwGzXO7rJm#Ai)yP0VSS9O*#z)cpX;|l$?M!>)?@P=w0l9M@3AaK>#WqJ20!oYp z+K#b#C?V;`b!LvskK?G<&Q$}rZs_aLFIA2G+gqe{u2xEUO4UJ3W9@BZ{$5#pzv_nD zvBKn&*7>I4w!;r(r6tnmI~C;Xq>xLbVR%b2Uh0*UAcUZJ;*F1An23$h(q%Pz|ESXR zcb2~A;VO_GQ1-&vmP_0+g|KjWg=5IByhu{G zI^f&>&->`n9QW6&SS-=`0Vs7k$aaVXj!##^!i^A-a~?*xeemZ?vCC%v#zOOG@XJcw zx3am)7kx%8dr}d z?_h~eCM_j#qp`$Z_#8?obK5kLc;iaxtDh?LUb$lOY>6sL$F2SrT@^?=q z=F|yt$U+bpDTEb5Dfh-l7&V-8i&Li!LqIC+T)(fNrKJH#+)Ejf8wsINY-b7vwE_Z@ zWiu5s#e9nY#vup$fh!&IQKYbX-`bBeZusDgUsBkU-C53)sf?wBQ>ZX$0QSTNfvJHK zAR#9mA}_^J|F%Ux^p)*^f%N8Q=Hfovf(X?}cb_^ERQJ*%$@xSpy{ug?N|323m<86$ z2p%~o<{<1RXI2?8!6Dxc6Yt)a1|#|vm{s1F-`Y!pPu$2}U*vH32LdhPWSm5A%E+}M zH4D3Jr6sDFu}(NF5H?GUAgu&&Oi@9 zkWL$39kx5Rk(SHU6Nbu37d+&BzRA0)5`RL?WuUIy-7BrwMY@*iWJoiF0znQ3PC&H| zSh)2<_+L${|Mry(i_Ey?rLrGb!lL_mg4v82XD~$A?NR1SL8w{n=j;DGXgVJLI z|M?_=8b+$H0$i|L+A%?fD9fiyg4BYh5nNj+WyI5%v{rDal=~qsFWB?j$=JD@8}t6n zjZ)tb;4pWR9$tAmi(1|=vWq!+Pw8tITcpJN++>2LoSFj_Ly>c*6`D~XkZX){inAaw z4{+s6T|dUmd13|?f2BH*`lZA@6Q=RX%o(f{4oWaic)a4k_^gfHb3+IFP^1Jlmd6fG z$@|$4`-h$XB3Q5-)B274uW< zr3p9}tt)qTA;%1o7pFNQYUb?Fr+F}t_9}7A#50HiTtp!dPcVc4-B4Nt7AVJtiYv@l z6~_Ab6}yU9%0SJrgK)}(9Lp$+Gxs!4l?EUnlOZ$y=URwkUYwaK5iHF?iV|}qz<3XX zg2}kbXe?q7BSwZ|)c;%3dgZW(b@`~) z8xnUXSf#R}Wp5>0>wLuf8`8G2^Vq=w;UeMDKw3|zwLu70MrjFLL z&ksf+-acv2FD0f>e|}L_7ZD~1wE2_Y$H+=b?5$6|Y`i#ECf)Q*0}*F=;ouqtkQIUf zXI>clD}T9^XsMs3Y}v|p{?c^0dt(sm;^BaWir7PCJ`=OYMAg&l)1&Arg#^8 zCDdvgC-VPopt`qy(0!N8 zelb5CDFd&Ag?E7wsgzyf-^Xk2U*A`MD?foJJkeX?3bEM!OCn>WfabIo8jXSzhf!Xk zBpX3YjEV<^?#9Gw#mK}fdxs`c1txp{OazVTyKan(Em`E@rLd_B_W$}~`Pu)jqrE58-S%gzv!|VBQ9#bpmS4DGg6g6;pZ9v+ zS?75QDv@L>tjMM*=SYIm!ibF<0`fk}yZINVGf$=4#L1(knFUk<#RN|7nbc~u;d2BQ zf{p{PoXPU+Rd2oHdZyJ&Y%5nFvl-;xpXYLBwTwam;}YYbQVI|td9!oDoeN=h<=U%u zeec{U4VT9o7uKLj%hTA7UGHvaFm_@0-^>5@BR1&s{bY0SP6}BMJXveZ?T~W5+nW!k ze5G(;et4gOS5p0xH{~99X}+Nb=+j>irynV|p4Y#Z$>05q^iv4N%8+WS{{42PA}&p0 z^dI2Q2i%S_w1WRU>F+tNu6>3nwNx2-m2SjOSAb_ zl7QqZa7?xz4wbLpBjB?TNGSyM8FIOPlgH~+GWzC&ed|NaTllquGx66+hfT~MyO*fv z+J1vw`K#i-y5;tl;I&AWIhh;W>#v|Cq(B+}jSaWijt9cHzJGaBKPH*ncCtvUl{n z@F>oAX}^1JqQOYXl7{~mnE%_AX!a|doO{(=Pdmiy6R}Nu4^#bKCz)j@qrb}!Z@$2% zQm;_lw{}~>Cgmd=spg$L(?%}R!X1R|*zKlv_c!v+y*p$UU;f~vzKs1@8P~^p8+ie5 zz(06KsCDn*vd(zX5BL9)HblH;W}DK-)zNjT^x~r{y1&Ss(B3j%`Ro=70QBRF_h* zgAHa!Lh}+L*3{wVrRi=zP_JVt<{jWX1iwK0wXMWF()}+2dL93^AMG3NqWs$rP3T_xI9?$C{q9rvC-rAk3~!v5q>tNW$a(=2GOsK_wqXM(-&+ga`bho0$bMD} zS0>-^{CgM35fow^*o7}V;Pa2m^q~Lqzob3=`GfshVt5aWImAU%blV?!(OG+jomF*4 z-_n0Z_Aq~bdo|vV{`j{~`8_iLKyJTJJ8wbJJ%>iWRUz3S_Xa&tR0kb2IPWE}1DpGo zUaF5nHeO-$e0C1bJaazQ`LhAI=jT05py&sC^-Vw7yKXVvb3G_|-@eKwOECGrn!@lU z&ywWfKQg%>2gkF$ydpWeK7WEY33^|`ugQ}hir;O>oS(SRP3}HjibBv?qmQ~89JeGu z^ZBjm}d%VS}ZMOK+rH@+N8jX)HwO5TU9=_NlHCUWH$#7i8IG#xo49IsPzW@*c z0Gb(qD+2?+`|iE%?$+A3-FJRld)P*9OJ3J@>)OrT=9jH&SXwF;q!3X-S}tT{te@6v z%iT4<)fJPD!KOlgDfCP<^i9!MeeDNbn2&aG%;Uj#|*MNkF8?f36iR9U< z6<^IIOg%k=R@GlncM*^2>O7%tg+LJL*_Nt+@JxIIL~n2S1$YqF_J#P{rivy0DE-xa z3BG6RM)>$a0(FJ=fWek)c?xYpq<@R*tVewK6Y4j+j*t5iPyR}%#XBn1-+6-H=m)H( z-yswQJ#WC3WnQ2CK$dA6MpsV>*RrJ(umn?6IKb=V_Wu@scIftg{M)MU4u`^jcf1cO zP>H|u^YpxjWo-YtL&;^<3GM|!4lxKm>q_X_x2wyTRaApe89-h3+Y3^69C0=6<;F&C zF)#>TR-jBH`n6xb%{PR3NRKD@1z|PSRZ9R8XuW)e>pDb*%3RmeTk$QuwUVmaqB``8 zaj6#uu&)>1HVztrXW8W`Vi#7CZ^L zkaxN-l3q&<%rd%Xtptz*`nSl40-H(Uxc+%)SATkft!4z@QSkj>%-q}pT-ODs5C6?; zPi->!%YBfWH!!9+Ro|>%ju}nw5u&!Szflv|S!!0GJX7u)<34!V{1?Z;zvq*Oo~?rz zE#6yKC2-ex4}A;7uFR+M2Rt0XZ#onvGUtOcv-fO`oC)s+-2C9c0gpxK^jsC3YPSJ& z-x0p#@E^905?VCS%XQ}j%`dV}zn43o9e8pj#U*TxT5K=Dm<2MEuNjz4Le;3o_lIUR z_?-0$x6q1qEHmgr-)q2ki52jfWBym6CK0yP!h7WGL!a&n$pWtuCNg>H0*HO=%#Srd-$uLGAvpp*yzQM79_&O!CFAxVuaU3d1RX!VF)DK3(C%!(L0)K&Jo0duX6CRzlk5t+5 zBNZ4Z7}2#T&x+N{b6JaU2{1^B5D5A0{RXcuoRa`u75E0m=XZwiUU$f4rET%XckZpU zm1?^Ex}P;+XD3*fc&W|m(sV0R!pBpwgG?i?uB^_>PLr*p4!Fr#qLRQKq|0KPgIV1i zT}COjH_;=`B1gyEtZz8~yVK6w!X%e5?e69>KgD{lSBk4f(q%h?UkNHDIx_AJnHQ=~?jnaN`l) zK9wn1Tb4BM3U}>@&m!PZgJH<0x~KIp)iKAq`S9w_%dh@Yp)g2hY{&` zer;lW&08+cd&d(8{nrOC0t2kF_-7xE``BnCh%v=4PI(!H7{x#1$g|2@@5FNNWO6Ve z-N`uHu#NbGl+!no6f@Bk^G0+;HI8bd!9Bz=*5V(|2ffX*LbVfk%_ozn8$Dl;%S2 z;&J%j0MOV~Z)@Xhp#}OSHz8BuO7DSn3s{%6H4~|U)S&Jcu52A0WG`x=AVZdQfrU^^ zO~*VX{MM&= z;TjyE`*8km1D93Nxcmr2q<~bOTp~(d9smZC-JU{Yc{r=7^~9OkM)vtznVfeIMIx`8 zXdd7efL^$RBobFxibPKgq?8~WkPe^$auPL;3cy%{I7xyN<~9&7{NlI@jZW@tRHHb^ zhSIET>g(*D>qFvA+Nidepeu?DpHZF3m<4h&V;|?hf#gC+kJNQtO=wp++~$A3gpQ;cMpnx%8R=~{alDVFpSy|n6q-y*^$L4%?0RGM0%HytQDXNn zeaY`EthO|`m9)i1J(}qFAi0ujIQ* z`sYodp|LtzKP*OCo+en~5-YN@Bf+cyO&P?b9}hORX+&Fv~PeL8u}dm33&(O`_CPu! zNN$pH6$c4BCLrV&erK0O#XJ{aMzN_yMm zw2&puFI^E7skMna@QUh*}$x_Cy zl#JQd-=Upv9n0=>HlDkfzRNJRDY?9(lKFQt2kZp{QhqiOgW3hS&-KoGR zt%l+$aL%1|N!3U4aBCNwZ?5Z8L+gDQPn6hN03PRwZ0mRMkQ3RgjZVb-T~~aOCOAKr zP5~!eksG1tGDxuMdT7_`lHe8}HM^OORZqf`qVFHb-tV5^N65*}J5vTF3Q?cK3DZc; zBMp1oJc!Zh=$h+ANtclu@-beb2Y7rVR=1+{6fuEu0wEo9Jw+xwDvltrSDuIGG_ZIPS)4KT*3jhZb&map2x)U?#En9I&V1_oS;81v z6C6dB2K7)S>3tRzx}hMoUQ0x%BxbAi&8@9kxF?PQIHO(~{~6tCN1w3NKipbFjP$dH z)=z}^PGtsUE?V{m>}Vj&{Ih47u3;=AN2HEmu05ZI4?v5o&SQ9(M}AxriZUXWMRjGPw-lnx&DqCJsl$^>ZEe;>FlE7Gffy7EP9r#fjU%vsjf*+bXssvQ>jp7B2BAE7Z_7^Rk%*xxU5+&BJ3WJ%GL z55Qc!~)Wd}oeAx&%Bi#q&># zOVX&n+KMBxd~s$J#v{Dnx1K{|lGJ+y`a##11xEuDqnZ?lWNS9VKtP6ia+(NbL1-Y5 z$C)4ZzAOp755t^0TlQhZ7<>FC;z50vi7|FCe&0}}3SHY%yiML`RdVg!^3T@Fk#X-{ zX=1EsVR)r{mFv|tlU}QJzxH3|t(77X8Gw9BDcMgxfsO`DZWh;rUQ=e#qv^?Yw+=?m zeZo8_`Y99=L|t*)0~%T>I$A1JpjFbo(gXyuYi2$*``youS2WvX&bm7yp4jA_T#-Nz zz>DR;(o2O)fSg`EPMkXz}#vB1a zW$`#P%ZjvdKsQlB7{k~E%34U~27XL7!)19OA>4*xD9N{19(J@_`k1IVwh$0ZNYfxh z4~e5-G!8=|DMHbT8YD;#7YsDVcu7)^gak`liUc_okB=k3959Ru2n0w^p#ecCNt`CG zL1Hd(Ecy`gEY|2w4oJd+#smLAB6Q8=KW<+wqNyP-ND$xBh7FyojO4H3sHF0p>@ z7W53ne7PdUU}Q@G7Gap4LJks;6c7?|Ae1F$L3yMav5O@7dCg_D5HL(}?s|X9!P|SF zqG$DRktS(5nwUq3fl!(f$e~EkNGX~ksVZ^?#ht^0p(r6m_!o-E^LeTLUY@`HO45?~ zi4f{B!h~k&wha?>jWml$b0ak|ijpA6fjJHk$LUBZ5*R6UX#LZDHGGUHc2641I&)#$ z28r(!gaylg?XW2{;1a@MKuH{dhRze=NF2oy#AYKQ8TLh43dQI680<>#d88$$CxrPj z{1DbGXU`nLq)X>E))LGXLqd^3VI%@bm^cj&qUgm6!qYHy0)QsR0Ly@ZpWsrGBBP(r zax&WfQ=Gt%UV*?&CKvw+(BGT12^pR}VOY9&WvHF1L5dNh$x)ID$xwO6(Pi!=g-J`z z0wPKRFf1xJ5xM`zv@d~%7Mo08z7|Vg5*RFsyD zOiq^jv|ulV<^eQT*M4^8{J!%cQXGWlJLZ-8Njs#5`W15eP8?>bzySJGpFxp>4XEeJ zn8R-HrH2FaK#O8i_=M8sWs(VoyD1SY13PpoZ*L1U@EaGjthZnVZUg>)eO;y9Mx&yF zkqTX)IxX!_=-}27PVZ1CK~P6&A0ZAE@Jerq7k)m#E66&dHs61aCcDan4XnS zls=)JpqT5x`W@(*7?CAil(%~g5N@HP=Ouit8>UtmvmZbAJj+GLq7K(e#{?8Hh5O}wWE zg*xbgFl-C;)tv_t6A96_V>;HNZdG?L-YRb5eSs5J*x6XuR!-M;!3j8{YAo&_!82k} ztp#cVs;5Mrcw+9-I`WvEre{K(Ai2up1{-jP@6=8>zwpzP`v>_7cCds9?;Uf_i9AzK zigq_>?{xpnFOP{<&i<78(;Pbcpf>*?!oCN-Al!T9k`fAUefw_Awf&J7&rai^zdo^| zm7(JA59z>!oKMdF?88IuoLQFilE6~PGP{oDy6c>u6T{q_so%vm{+iY&&ZJ-|i@VsN z-!kPpn>W0_*Iv`UpfwcFTYWd}v+!DA?>U6G;)^b>^qyT9rOt9!yU;#qXSR&?WTsj_ ziuA}VYin$6?5iuQ>zp0;p~`s_bHCe<&2op_l!hs2IyHX{%W>Sg8i80i*~^tP{~6J1 zPY(T(T?NI{jy+_U0^M44002zDI4i zTV}3iIM7bIMqpQgD>5@|mHh6TL-KGCX>-@Uww1L%*jv%+OVY|5@`Jh)s38 zBWBAn(rHEdXVaykT-1|vYfuQV)czaR8Im#}*DMRD4JKFQv!$uVH9Z2fYrO$LX!j&I z$FYlA`lsS4D51&HEa5t7$xUL^W&0sOm8OiysUq$fbRrrKdPG0M4U1l&8F9{6aZ^I*G)V-XM0Au54=I^PVNcXetUFMG&(Q zP{JJANlx(r0dOdJjW;c^*>(!qK*1ULhG%4m*K#`+J5hS>9k=X$6b%gTE?*jG{V zv+JnxvJ$mBh~hqzXuCy5SKy*HHxfh6V3ggs0pai(*Fhb5_@$JUqKw363;~4JKixq5 zki$t&`rAn*h|{;*iFXvt#i{mEoal|~{FHkqZ9U5LC_k4GBs`Sy)*5n(D6{H3Ay+}? zYUYbhnxrFMchBP5p!w-RvTmn8Z%Y;=cBsi9KPYc@p(!JO&1>Rove3}!i8|?T7T#;; z6;GlAY0WBA4Ut`)i5yEpo*khfH+SXVrP175Ch50B{>5nGuDA z0WT;YE{o$$z8mWQbb<%aiy0^sy$1@0FAh7_m%p|~SM$FwTYkXb2h$ZhU)?zRfu=#L zT~z6p4$5OV;~~Q#2O2aR_m5s-{R5?X20PmeOWGP3`)7ADM_Vc_-Wl@3r1I{jS3Z%o zv2xVK+Tf&Tk%Us)M0`e${E;apnzf?gh+2^;@r<5v*r8#y!Dr8z<&y>G|1umbf2742 z;eXxq|6Y!SFO17KsNursTs;nsCqH#p%FwrzaG#{D1=-xR&s=%O_p*@HE^E1&@PXzy zDcWaD5-BUV(AbBpj9WY3kUCQ4+軅^(5CZ@J05e52B>(_#Wlxn>0h%-ulWqyy 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

    4D3GQ?HfC_xEu%YNoR zVdztRsN&YW}`#<1y%TLp3lYX^YOl-FE<49_Or_L z6x<=5^_Am){4r6l-g<%w+$(IjF0c8leZ?yYM?zxo|J~Uy>N@DYzvZ6|XQ)2N{N!(_ z`sR;Zd>Qn0Mr9n~ymn5@vO|)E(K6#a$6RyG+H99+Wp6X%lQD{tS?un9;@mlRee?95 zs3vD8&}G!PYtGb8QZdd0>_u;ThbaBV>;}y-a+2s_%u^r8OpOn*0#V|<%CwluaCeCb z<9RU#+5ArPEF%FS=JGLF-#h;6F3lwE{7h&2O=TI;C500F5e3JN>hOFKni|&4MKz&a zYg`jxI>qejJ3bpjQFv3hN1IofnOY}a#uLClPquNIhtFtvUHeuRqZmAiA@y}Rmg8U)>{kbbc{DpWy|C#s&aTU+|TZAQJeIh${j^=)G>h|{O9k*oN zRQmqQVX)M;%c`gDoJSbSzwqj;Z&`Edk@)SeLD%6hpJ4un!<6g^!%12n;$fKw_E4Bi zIU+b$ZpNoS{@&b`EOALtd=zyYm)ydx-K%bc!fgj>oNf)nc%}30FGBd9iQZ?f4gd7V zi#giAzk|n-DY4P9-$H7Kjc(9o>NF!;5MGkWqH8f(A}q(40f&+aNvfVE2aAdD47CWS zCHHa2YHoNGt&c2ta@_0%&dMo@psQx6y2_bMiupVQ)~3KAvu*n?r?acm9)SeU7-}o%x{oE!)iN zU!r02KXrrEF-y%tgoJ-HrL0|_y=(V zoIjr^dy*P&TQR|)J6E7dTH(RM)3vxhv*cJ>$sfyos^6T z>s2{zOlUtm*`tfLX%FvD$xzEy`s9wm(1)khVD`5efG~22P-1Sq=gaUg{nskmW$nH_ zXau?4|D=TKK=evLLiHeTB_IMqasvPAl4(n*>?BLna2icdi2;NK>R~wGC<2KnD2jks zDOyT_>ANL2bTH{<8pdauIU&>8ks9;!!_GH!U8U-<4^$-kog7p4WmIbP=;?#Q&n0ni zWahL~&gDZ*fC8$GdxP^=rYPNQsl>4tOijBBQC65b*Y|GTUW%{MBMBTdH>@1L01&

    &&{ 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%0A`9j;on9^imvWP2%(fj&$x z{a*X#rF>_7w;B)6HL%u zR?E^A3c>QBHsd{DPaX3H?TyLPE`ak>d`p0nESyQPB%P+R5cXD}U^$OorG;Ba9(!Cs zwba{18PV)dG;~%b{zE2<=^nUcS-nu8#&2P9e&Nf`De` z&r%u@2B(pej4?PpkKodJvxr#!Cc0LYt+L*z&A^|t|0kqgw5GHy^0T2Gi*;Qxs`h=D(7Em_%q5K#=6 zr25n>BO5Bp>C*iu-`qB|n9$8ly!$Y+zAmGrdZC|B09ed!Sf3D6 zov%=L|3nYwUHS74a2*PBe-l94wl{ew3iD_P9)F=S4DO8jyU%o;(PjTozn#&)N(fID zL2_?{2Mw?`)%v?=#O1dE+L>!(n!JgV*_YVQdgK3SE38?_IzPsc&V10{u*d2%N5~4t z%m0N~?j?hS!}8jG(2t90BwzLSBIy|{Lp7h#gffwdJ5lLDx?_5>#sIeVZ)OI6%d>}Q zSfr$Wj7+*;0+RFxb?la9K~R`L12up)2l_>`8M9P1pCQ;#3xb@N2dSIBfi38V{ShMY zI|fs)PEGx4Ra9$bzMjgS-(aa9xL266AoxvGiuu%tq8|wc-=oeHn>9Jz;TP$UZHDnI zvln)Ut}cjaH~-x{X3Lpc2m0G_Y3#_Ir_Usxp?x97d}nyF@{{cW7k@)V zB4Y8=OyXRRXwpB(w5<^x=5HhSuK2f-V*le%CiTzK`cob00Uh$c)hW*9`6z#sZt=IU zlP=IMF1IX|xA2KB^)PcC8c6hiJ~5a1>~C8SzT1#-j6o^!C|(0E z6*RtD8vSDAjkd7d``w2o0O>p;()CJ;_YD0m?X|QYd@;zZzWP|cLqrqwLi+80-amJj zQ(RC{tc`d^4GqmA@AiM7{IpO4zmPwqkD;_h)fx1IbuVi)l=8mr9Wt)ZP84R--B1=kNkjVi1{8l=7it;O5%n&VQ}=cp>&=0GR+&jY zTKBa^J(zAvmH6hXfkIE}1HHBCwj&y&PWAU%#dv0^d zztsAHwgpC6-h9oJ$Xp$$^`-ox8M?jsu9(y93Bc2@x&`T(N9eP^|Ads-jORq;7F6u7 zf2DJ^KGp@5Z2@aAuayzT^AhusnQ2&BB`7$XT%Ua^kAjv-YUxtC^fbr60BT*Hub&Ul ze1}WelUaj73cBzYh=DHyas5h9phfPROz^PRmrj__NKySqi-;c~EScoTVEer{Q+tgV z|N4ZF%aFo+@=f}|!dG<8jFjH40D1)NZe~q}?PTdI?;%=UGnT39{jUTgDIHIl8$h_> zc{eifV*A3pvI|$q+Yb?1W&739x;o;yLO|Z3C`=`t9UXdQ;;H8s%K`-HgLyHSI9PuM z3)UyYrNfu^2m`Gs$9)w4#3<%c;y3|(r;Zgj$l%)(-PeP|t&E%wr|d?Oc*2>N-WRb}mOG@mN~1F6uCToBUaP_L z6Cg>kMb{S>xUz(B-P=IkafD*pt5Y%@oLyWD=0|DKlxPSXa#`7i+zHsa2)ErC3A7E; z6zO?T{W)Y;%*jmY<|`atxFPp&l%mncY6@GQTPy*q8D;f6{;jG3;E)H;Mc^3$974oW zC+tchJh88LmhBI2NFjn!W$P`g;%HO_T>wDpg}>ZD%*09M-wP8mdxDCt}KpM^RY=pm8p6@3a za|TfK9NAjPQ4hasug_3WEQ=MiefE7=FPN7)%J*cG=qOmnM7C}-sxsK*;But#Hi41= z!N$>(E_o7)S)g;GqP^tYiurs|(8qwTwa5eBMUib2AhWLX#eY!M0PQ$)IBVI~7;A>G zD++^Ct}34}0HCa8XMu{trgyngqLrlr;)HMscHX1{A#LWvNomqfvDn)ZaBU?#b$tpg zpei`sy!>(~`AFq{-?zGn{v~gGomD{5HwZn6d-L5(baR_)xIDRY^R=8ugchS{zl9c& zE%17iav|O_jxEUPDhU!{?W=FoEqBI?X`XIQV#d2hqKNQR?}Qr(P&)2>L)T=i*J@=Vbv zs=L%VE@an7Wgwmx{wsnj&W?RKDl!hI;|87#8?_F$0)NIL`Ikdk=8Mm|$Qow{$jD{3 z&jvCppFK=D1|{>l5^zRu^@{;FG{UwSPJJ^zsv-ffmelT%k5Ec7eHMM#6RQOCKm^B zO^qD+WZaH+vJROmN8eG+%5}REsJ{Fxy-CG372}Fh1xF8h*wE2)?e2{3kW+XrWDyho zIOY7dtu6^|K`pIxE7$&}h%9EDZM8eqy5KT>LDk>&LXS99e)65^_>Wmg5=N5LPrb{~2R^4h;qCnrXN4p=?%G&ypgol_ z&E@!eSyx_Q9ENt6yx2H)tB1Z`O*hbp!Lz!HO&%})q@G+8Z?Hu}c+`6XAQnEOF#9bQ zTHtnh6Gz5~pbIPh8;%m3C!dLgxmYxkA@l>~fb93`wg)_+C~wOhQh} zg^h3!Fig7uA7*H;8RZ;mYWwAob@p_utCr^M9{P3!M$4k?16M=e8Q~49JcKj>l*R*N17nPj%zv*cPxvjRZt^<+o1ZxZKj#`p~}+As2Arf zXNiioVsK$LloIz=*R>yO1v*QFKUoOE04pyf%UIr$zKU0$YZE1t1q9^cpTEu;H}OqL zcmD3Fsp3&tlsS3eYu4{jMuKMOc9(D|C0w9Odu82xAEYJr4HLgy}s z=LzBv$6b@{ZO$!*tsIbGN4T}4??P-JkemSUs}&*xr&i?w&}_b^HD`1Oo_{g%UR`Kt z#6>=t2QMckK^R5p^J++Qww$>0_1)~Q093UlK~=?2C>(R)vJ?g79~h3fdm6>5AZzRj zj`S~*U?f1O)fc7;qX7BHa9CleoAlvlHi@C1!%L6N))9hA`=V>njpKT&Z>tvMSlWgJ~GltGHZMnF)1zv1y?xk!rTdu7d zg?>dC1&%GT>4&`5&=J77OPs!Pw=$PW%CM^7KYBF+KB;Ne2#GZ=uSE+xRE z-0{1S`)O+%TJ2jGK0yL3=e1n^&>?V-DazuzM7&H1B(G~e5BY(mZ^J*%D~%mpR?G&x zoAVDL9mLPp`n-~ujM&rFD0X7ra^*MIr13doifw=$=YIp$tro2bay?pAur+%5p!Fdi zN~`x|c;$$=!44Y3g6LO)>(@s{(^UVw@-E%roPl~UEgMdR&CK`tkY%&)jK3u-1uFQ_RJsl+Cx2(6Lf;Ei)JL>#PuNz4hFW`V|RGx==G&{y0Rwd6XY|(=jX1dpkxg$`FnwR{X zB(Hc%Tm`|QQ0)3VC8&?;IVGe}sfx^pqm0+_p!r;!U!4N%eDpAim9(gE6k^2hbzj)! z0_>P?eO$;0mx^2KC`PD28iIl1F3CiIzB7`$*(F(*L%&b}UZ{nN+PRSZ$z?}d+yxC(1Q$U4dv`(o%Z z+QMQReJFZ3=Y_vK=7DUmbjVsj4hzIVc8$QeOT*BFu? z&(5I1ue(Agy@h8qFbAC(UVY&Zf&;T7U(ep6ilnE7J|I2Z^ZJiKd?yjg%nEL344E z;I1e)w#|r44=yb2&rcvcI9olgI0>*YEyO3pxb1ES>jI6gz!BbJ?KMV_pd8QUb_XVn zZL{VQu|-!g06n+dy{idx>fIO=EhmVr9ff%H=9T`E`m*<98P5K_|VVAPrH*Z~CNz2%3-6{xhXwzotgucr>Ne(L(rXIDNRg z3)|AGwWTcfoYJZ`oUUyuMw>fo>?dU$h1xfk7ih<&aepTWz-$%lmAJ3kt~F4v+kv=A zIPp)L*9R=7EuD|WOF8k%7$Z$aSAr|Ms<8-9apQBUQqaveb-0DuMP!EO?ATZ;pxKQ< zYanWgzSFF|&hmBdb$y39y*F7@q03NHg<&4ZB9U8ds^Z3LJZ&NVmgf3!<-jiG65Fs1 zQ+VLW%kFR)O3kzL$*XI!TzNCrl$DMguZF`+DI@K^(-cG96S)4ii4k{9VUq^ZQreXM zBcjYJ3tF5=tM#*G(g#u_oT%Mvv1ah*2^4l#7jr z#d);U*Vs06)?2-PKA>`JJb@3s`eYenF#BDkj8|f>V2lf-2x%ZEl za84<2u;2p2Zs)-JTEyqC2tU~+9F11yp(Y_4@tc+I9AHr)$bajmCTX{rl%pP~a|p*v zQ{8ZZ8wbxLc~H$s;R5bM48U#z6Jt%*`Fu9u1)D}NGU`p<2aGB!zA>SDl}-dFpGDg- zmJ!2nG;f!0G-BHcg!_VqHryhB4S2XEjYIAiZxdJKUqc9+)ZHgBRY`!#5z5KE9kPWS zT~W5l66PKaZHF3xn&6_l=C!wg#r;VGV-Li*sEX{s33e72{D`)nfH@`q_675$c;uJw%7j_fYSELY z=FhLQCzV`W7!IYLe&wLY+=X5mX8C}gpaFzt2=~;w7X0CHQ(cv`SCXx2^vtRYeY5Mz zbF1eDz7j>E57NXUHtQ>F(jw7vUBa-DdL!9*;KD{!9o}`)rp}bDyonKJOY`7F0~MpX ztI^lXd}UAs!5LQ`H%j^*(sSSzd@s*TN#1ZGc3O1t7d83LT>Xx^0e$|H>kjX$U8W z+AcAb%^Dp8U%z7f%pg=*UvvWFf<4ZE=LYR2v-fL9WQm-Zb}9SP32$E7ogv_A@H*~K zm!klPL|m-K9?cFEj(7^IO?Z}yBTKw}?fq{N3%P@}Jj2H~nSUr2g=ry%Z>y+dU|SCu z7xEovVBPsX?$?>39B#MdreE>saAcg!Q9 zC^zSfPavE8Q96KUH{NmI#04Xsh^5zH0vm!trtW;$=?0I#!D-hlSjK5`wFiYng(z%N z!W_I;ysa6H)FJrk1^*yL3(zK&iOeEKV8K=1*{`E6h4%ysmOo6XWI~X!PuhcBS^AXM zzi`=-5D|rkSd;(3i)Og#cTZsg3a~OcA9{jI=}jlB{C~x(!NVg6p2Vc4;VFFj(9AZO z!>bD(fCEHHXmJFMjz$6yaWK9CUS=%6pT|58b4lPN4PAW0dWGBfdV|Ht`BI_73=bT^ zKiw=RnC<*h#8GTpX!n3Ad*7c^j845Zw8`3xgAGB1G=l1t`;wias#S%ub>$m`Klb@M z{DGuSEa12aF}~yvK56J@B|#VYx~BZ3UNG3tC;lUH{|ivkzTBk=|HtEc{!$%Y;p@Ml z3n1;RZVBn^EtkW6U=ka!xg-Bpbgs?tgV#hx?l%8Ug5h0H2kO*Ojv9cbuGvh$0)(fk z&!aIRD5CAsgrDTSep6}+w`q~M8u#KNVcT*7SfkD&ie&$p>>r+g4J_0VkcUixUh*<3 zN{ppIG0+eE!L769@Zs{6^0xTIaNroL%K-B{yw+@)LG2UXNc;ZU$@^ula-TI;>&573 z`K!*_?byhutE(z3c7=eaq+>9lbqPW>^J5w{N~9mqC08M}N<3J2}1-;{SjjoAFvPIiHpNp(D=LcuZG4y*Wl zjckeUrcnn8L9inZ!Y9#x5G8tdXiN2yiCgG7Vl7b>%1GEuWN&LRC;Vo1|>8D_Xxcf|Gqj7SQ9CO$8V6Q zn+=vb&jqA^Yp-NBjB`8L;v2j&B5p}W3okeO_Sm6-LI&dDnz$ai3b9eJIkofEQV(|^ zRf#(tHZgTNlf*yo^=yx$6&cn72p+Ox!G#83RJFS#oRBniaOyddMg?$?crht74GT^A zcBekW68Ei##{=xN>+163FcWQikNAyvz+&(&n2H|Rr3@vz*?PUH?Br{JTg$j9Hn8r| z@2+h?*73MG*b;iundibxJk`O*ik3-%;tu8hPZEbNjha%3-qiJ65LZC%M_fo; zM6Xr1WXdD>o9gC}g{#y_>w&7=t{2vSG%vKTt}3%s`2uTgH%U+0VE>PB+==b&_|P=S z3O4#{>BE&)@{C9Ez$K4{m3<*NFw&rbGj8ca+M}dgq_wkFnwGYfZllrA3BW<5VfoAH z3+e*o2&A|b?FPc-pS1gG#ga~|NpOVWBe-Leow^#e>)Nry5vs~&!Z|}lXy7*b2mf;g zV8-Bq57o9>W*duC$xWOiBo;P$INZ{*$sA5PLqBs1!bnjkSh&mWJF%6HK8CHjOipmX zuCrsR&9`8&s&WI~>#zK6)Iaoccee^b(yKd(`SbtbzmeG|uSACgXBSVe!^-!cDd{w1 z1z-?kLZpMz4>dgpjvR~+lko?@q6t(Fmi)V(-o3CO z5i+(IQ$9wtBOkPcQ z!h+skB+#dK2!k9arPRQM9c~mKENxo364>``-16>5E^J&Qtg%4*ft(Lk8Hr7!a73>@jmV0hcn<$9;GLb=?^e+~?yA=|Lu<{(T`kh?+P)W&JHe(gA6AObU zU5fu*Nb?deT(?%GT*HkSX2AOv0&ND+SW^I&;aB-2`!HAPD`6QigFQjF3(?PqZOzBI zE*;1f^E;)E)-ubsd59IQd&QGAl3z2vACicMxRr@!CGG@m!PxpXLL1qayZl5vCoj=eMvA&T7!j~dl$z3cZE5M|rO{N2HA$1eg16%6ss7ORn`p>n zBVq7lz7;-gqm!Cx9OT^DeKMA(R?tc$|J%dkBalMDSJqhag9Cjv81)jJ(}w}=Y_%XBDMMhh;_q`y zh4rJY$Xa!jCLKYtiTO4>(IfcNUX#lB@u><>jy!CQN~Yd`W7E5zz>yYK>PNI6+SpHK zw`3x3L4CpJSK4Rpny{{s{q>@iy4twDQyfKy_zwHpR3muN;xUh8^&x6+wi_*{_>E`t zMOe|wx;6dh_vZZ#<@FHrn)657rhOYoxsoNtY2-DQEzJMf^E|s@kcrpL`L<#D?k^{z zdjTP+CM?lvSCcFrd8JA?{4Mx+-i7@Jwu8@4OJ%QCsq9yF7 z5$9F*EX2EVAo;IHD|9w{zN|^)Qas%HT!r(3t-;54cdFlWpbcyP z!beVqa8{)w!Bkc9O>m1_k#p4$&n$~o@R5E%t-X}HU#>|kPF!pV+&2ucOV~`D7zaFhM_$dG)reVAiE(^z z{2o^}u_)X(A@VB5@m_CWnxc`dJdUjRX3?%;0BCDP2b780Av#nIQ{i6ax`DDT$e;l` z+~Wo==oDJ*Qh}vHiwh@hdjLcrTja-}lG5utRZ0;SEr%iq_D9ORe!x>nbGMu(P%i+l z3!UW1Q*=-BwbB*~h6C#H*RcKd3Oe-AM)?@-kicU@KgVeDWlw~3pO<6)Y`pveU~$eM z3r!yynIOiqrpe>nU>}Ua6?L`Tcl`V&=XAuq#2mS=v#vZsl|(vR0)!Dx5+Sq#J_HIR zY~c)CFNcjuI^g;U(bf%YUhjuLG~gjUFgvyE9Ir{u(n32VM($$Jk<2w0Q14w;F0>ul z1wB!30fZfHQgx2yvzp#Q;7+DX1zbexe5O{EnX>wm3hOLiv>yPzrSSzt*r*&uLi%y&7p)`4Z0o!jQ8>DhF62z*lOMG=IQq1LR9 zIyUub^KQPs*JcH)L^N{>Zg3b76FTl1m5RB(mt|aBl2qF55-Xs~R}xeeq_N*g&M~XD ziG3yws*xVXAL8lL2G-f_%troYf5pS!w;gWhj)>!L@qjDh3POdumlj57ssN0mo0dg# z2#nFocH&%h1M$&aovNGxsiCV5uxrRDlE9k=?gpQJB5K7-qlGvr6UZa6>rllDczC4) zx)iNsVtgru0!xFk8cXq@0h33>dK)~Nr{P_Z!-vI(-J)Scr-+45x4PQtem)Xg?LkaAaJN}oax zh)xMwwNKDE-l`hVeic=7^?ZWwcdspS=1*OlP|0&|G1XcfUph1(EW7F$|~ zvd20LTrH$ZZHZhwDdkoNC)n#X?2WiSu0FIrRXsbIsw&PEh!y5#6|Hy#jObF%|0?JN z|JJZlPtQq0Pp!b2)B`kg^}%WeT^$WNC3xmwEO1Hw^qQY7Hw|N`tmrz&1o|yFD|x_* z_p0mg-Eh(xPNN5#Sg6AdD_wM3R7tB)rRt&)j;@fFftF(*WgoU4Pt8%oF5U!S6YYs| zuDOWZgxn6f6S+;fUIMvV;Ph&4BU1;}g5LtvU=#IY)C1es^Vd1Y6^22?A^g$%uJ)+5 zZ42`4$25;u)%dRZsM>aqvQ&3zOfL`4ZRO`C&1Q)m!zVnfR^R>dT!F&d#tmrnePN8f zUa>)lKw#E+1tMd#lefYiQuem5&j%bPzK*%tc(_~Kwpg!gOEzl&qQeC)=>=?)hGOd4{txGoeqikhvju`cEM%r%{3hCR7-=X|ULj^4B)92rT16s$vWThFNhUL&A8>U?E zA)uXo{*k)&jN~NcRuri3=Ne{a{iuIRhwfKg`h|Puf%!D8Lm2)=`fXIs(8~Q_))zj? zVrph(GVCcNgN2i%q@%AJcGI-fr*9P)*J@<(tx>#*UEiFMPqZsEP`^q> zj5Srubn$h-&-jL8n7T$sFPu54f5z*nD!M~5k87UP+QriKt#AzUzpT>K20x|Udxk^= zCc})Z^ozsk1n&=xy{wgV{{1hTHkmn;e*RqI8-E7!&v2llDkNNgyndw1BcL(&a$LaTVmu~k=SWO?1+dXC(+%E5Ub?xcS(DP57#cK&btkTqL;-Nq!${vzJ}ar_90 zUYEYpd2qXg{g@R0ndR^^OeGyfUaDS>)wM;FTIrAdt4Z|O->{5)@RL00UB?ktJx|Sb zWNwY_{WBw>I&UoH>HL?$qvuB@PMJrC^Jh)wzh;T>p^c2CBUcL{Hts|B^}xYv(dB*+bn*gW?Zpa$_!p{^m2!#DWQ4pQ zE8Sy2s_OzObPN9SB+{O5Ia}@Tb0DDLu@4f4D3BI@&TpUN{Rj}GnZR>2U(|!N|J@Ik zn9x1g%g$;{*^o&wlkHy1+gLOG20}09Jw0Xt=IRp7L^Annc!#9%@ z57fqh$UL5<_>5{AO8fv~s?Q&lcE)W|5T-s*BS@DwF)sfD%LY#nzT3ypjLqHP{PX5) zHBAp41>gwwpV8})LAqbZ;R2JGjwZq{W-!icganUIdX4G!7kU}6{<}PboI&Z^6V!&r*%mXwf^E|LnHIRuy%-)JBm6t*Cqs00GIr^DyLq(y^b~uKk%w>^)e>sM zR((N!nakx9njJ@#)pcjH2WTvZ`!Qzm3yw9z&vVUQfo6p9=?P(XI#KMg4gK(DB>E97 zGla3ft_7HWsAr&^G@P?|zSM8oslG9ADEcqWPPX2*GNxkIJnN^gN8qp8E)jokF&KPe zlSbaN<=h-x`LS%xj#JgK=99{9ZBxON-1J}W?r2@XtBm9cX4`t|6a(0~oM)4`1p}X8 z=>NCA>V5}@8vhS)2Dnf~0rlpnu4#mcs`wGk;+~5YTdM~sq;-AJUokH@9jOfNpbW_n zQT2X{KxEn+TznSuEa~=#){D?dyuk>XzRs(IBcc7COn7Ty5&s~0>^d3!p9zE4xPR~N zcinAfC2M^9jDN=`W{@IE)B*X>5w=|>a3X)3PADe%4iN5Bwx$P~+cUt4ZkJc(wqMhU z%Bgz%WQ3cZqsd*l@f)*qx|KWKv&V0W5vk|~P)7HasD+rJVzd14`utI^y95Ny)E zPkc-xar*P=MH|oK6h`;K!E8Ryzj{C2`2*qR8cfy~<_KKx{3dz%g34-sbsui{gx@yP z@u?svx>+E#{QSw|_Uf8N@Lap`_u2?!hX;07syX7@pe6quQvqQevkcS2d9P0D#uVsK z_3UekuvE0)&wT#xG-%A1kEH#W>UXHe8dO=CcuxCh0IwOgo5nTc&$hft#K?XfCwpOl zlI8xrNk>>+?)#23nS@>9gnsLI)d4Ydg`8 zoj?5KkhH}!>&X2xpb&o~vp?sOzR2y&$^3d4!!v+8#PT=bt@|;FB&_Vk9wuVWQg;pK zFgQPcnBbp5Ox@#Hvk1)>zL>>?VjVXoVjw9d5ep+R6LB*MFcEvlcfFWSgu1H3P0U|x zD-{glo+I@IqwwPUI!x=jf*Fd9#h0ct1r&{BVBV?)+rr45s`UJJT?2*E43j*$+b9ulhT`uQvth`VVtH z2=;7kVr*sKA;#c)<$w>-{Eh!_Ti3X??|GQOYM?HAg>`!{V*A#y%O@lr$;;`9{~o0q zvcH9&npVU3X9uciNqt=Qe%)XAU>tb%@+}$p%85=)U1IwHy!uS%93}EK>yIG}2GGvD z8;jjfaDdw?jSrWwM?CgaKfGLp;4h3z_(m-ugPFn45BmMYSFfMAT^?}%HsVW7`xB>2 zCec|Pw7Naq9QuVsug*AU?4K)%T+tZH+b|4NznBMT8Ok%1FVqSR$N-zDx*r$ElGPqY z@lM~)k1}SMUK@jh?N5k=;~cRv@BiC{e({^MMaD87Y=>OveRGcuQ>zGfD@fFc^!HpJ zvqA(+P&g0y6I9snSa3>eWPATp_^JH2>$p6K`{sfgPS%kvk#b~O02wPzXMYaifNbM- zQ7-?%ar8U1`4lHqFRM zc~xZF%2#rSaw&2faUqfsLc&1hnD+d;`kiDbaMoaGbc;VKpgLdOi4mO9C7YDk_1&!$ zE$Bcwf`~>xranQw^?l=+2s*(_5wnk|vfS<;0{a7?EG+h9SMjuI4C?BcAH(|3u3VD#{&~f6 z4zR9EyQEXXOHsQT?_}4rEb=Vc9eMJVI|8;nk1QSlwlp?Eu&d_Is_(%-n(^6@8?jI7 zzJWx9x@#nrWFdX08fBqr$sZI&|3MhR>aERmM&L5-sIZt=%%<Ey*-Zb@zwoq zH008LhTo80P&xG1%9uk+lHHU`aru=f&B6{dzC$JGQZXs2_3A#mxf;8mEh~TO3DBeU zpIWr1HXkbZCw0jN6fFve{U5X-DSt6664pjjaO0=V<6<022Qi1g9iOwM5;PDXZbMBf zI*{I~Fq&)zn2ciXKjuI(VJxZ$=~abiz?!P27yvHj|bhGquks6A3DDl<-pqz%W$XwWaH<5(r}(z{cDf?CLOANCwFnt2?`^w zjeXOTk{}|eqe9v(?_7c;;kUalU%;bDVsi1LyRXZ=M~_LDbjX}tnUokTltG@Hk>AG{ z0kc^9uMSs|!w*H`^i$lCYCZT2Qcnzzn7ajT!+vRF?;s(F)UPL~y1l_^C1!?3bc$-v ztsMmX9_>^2=xtS3Z5J9XOs(C53O_0Xz*ZiZt1Dl{I-kc0%1!VNn`x|l1g@$$JK`6F zPB}7sRZ))nNaQHTwtIhn&%-q53cqPu)=W&^tckhyYuDI}Sn7mrTHhJ!B+ytE*g#<0tye9Ct%G5JZ^z#lBlTi!#S_Ha z#*2yJe3JvWix)VY(mEA}_H~qgF2#Jdrutgciut#7;i#IeA^f_u-^WNBcdf3B*Eti( zM#9FrM!GiPn<>mx648rp{G=X$-Iu&-TOoBynI+!E`c8qKq0J`dNw&cAXuBM%F$!Nr z$W;fz(87A>eH`xXM)s>sRaaufJ~OLEs=E2%?S!!8yX(JQv;Mlu4^T`td-zm)J9BQ$ z)4`vuWA_I}dWd#bPuM|n8FDW>X#Oyp_Pq(WeII~3<<4$pjH(a%0|P8s5U(`@vRq

    mMF8nnn(_+a2dPFRbvd5ioCMzy65XGWEk&v@*ragL zKpVT`hH9vsW# zSK_N(w%|oaACl;6*IFMoy2W!|y8Fs;Rk8@JiF}wPwLJ-#l=CV@(H-|@bHW}@}lR0kqhb&fy0{tOEts|q^kj4%cP@5l5HIGAYgR4Mcq z)tFXA6Kp2+pXi3RIykAfZr!0{Ks0PO46y9&1yl>q0$_u#w9MafWkkf*6ba9fD~>#} zkl|k9kd<{2#qn#C03I%yC}~bb<6>QcSL?*IrL}~}kCiRqs<)A@VdZVq)u|bPkz=VM zL=W*~VybR(ci6GdBcB0ISN^v$Mydx(Hr3n5)Q4Le?IsvVeW%#YHTg#3!Y&ge`;oFb9)&bn%S) z5Q6BKx!61Zg9?u^Q@oXfC3ls#s(dcLQ2Sp&enKdC!LRa=&qV&f98L5xz+cOy_9zlh zxEOiY>B$!ptsS`+S&y(IhW5nJj%jmw%u6MIuMtj@s1RwT^R+IKklTmQ@N; z?C5@VTrIVuNiw9^_au3hEVadUoUA$Fa3t_x+`N&s)(QVeG$Yx6yf`_^INrl3ICe(< z4p0`+xo_*^7LtXMsB&%T`OJgH`=ovdw{;}h5@{{8*s`PEV|?Dc5FC;Z+BN0M-jR|5 zaIMkhn>=ccDn^GhcV4yrU>tdvP5)zwesDY9kWM8Z|~NjD)y1{(n-J0K`eb z`K^Z!M#=MZxO${E35a{k%?^{!QcXGGYP`>K1B1AOz_bpkQ0 z1Ap29y0>ii9owpH?ub$~ZK;i=9a$@d={KN9`Acce1wZFEIkfMkZ;j6ig}LEspIHBR zKRF+rjrtn^|Hpb_gTBDv;6r;z;%IO2L$>hWVg&-Qr#YU`*VOYnHT0#WjrT%x9}4HZ zZ;)^V7~(%bR}<z`|en>z6z*zh1O`WUX?$%I72QDD*E?4S-m-KQhS7G5>=24}bsg zg16!umG1@zO1j=z@Ij0MDaBY1xVlgg+gpxQQX3UR2bIwqa-zNdd;Nn`jxVE=^U6}N z&SORRtp^fxi?*VQtOT9}d=MM=qnx>kv4c2X^}4P21!Y&_?! zj-%0BVFP^(yu13EtPJzAh3p$(0*LOrwqujg!tgj%S7oIh<#gFDGz)#M#j*^<7OTiY z^;ny289Dmu(Rx7F?Ju4|j~ZVS6K263ma_$_K+ngN_W-)ad=MzEKdS9ETAa=AB)F^R zF7`-0uzF!wRoxzp4mM2^QcAV$-f;}ZW*_pr^wGyx30!Vu zLlK9q*X`gQE1?5y-fn!e@ys-4UoEkhbTU&x|hkpbK;Pjf*+%MCc zL1y5x#mnL#uETMSzN~D=$=$FrwcvJ6YSfO#mj~#D5VXu?$?sxbH-;jzNh*QWU1|oT z%j0Z)pui5kal6{&n6C8}4A&o?us>MEYyd+*yuUzne)~A#G#eR7z){?}$QyEZTbOIZ zty}G>ZW)mt^~6QOMqj9M(?qFU}`Tp;1=rmEVLxg@kb~A=<`$gW;>_%TJ{UO z>?-emXzWl{;BHf1F5?r*1fM`ABh5bVV;?cg{8~*HZ2R0B@xXu?OaBR5kz@MH{|8Hl zBC4V~rNPiA900=naPn=G@gTaUrQfq)`)iZU5*#+H7hW|PxB>K7*J|oF3lr)+9cgX^ zo0Q;+LFc}M3Flb~w_5v;Fw`|<3NY3?NBD%r)oVoM^9$3e zTFs^Pl(p3dl6e*Ksrgpd|DPSH%n40V^&tg+LDRU-{pkDfXUXlv;mi4W`S-8%wz@7>tFC^n#bvT9v*B={m|bvxY7@$MQlMTaIPxUH=h{JcK)#`sm=*Dolrg! z|40O8Tk8a>%;0y5ZVl<`KkuvY!TG!2Xq5BmkDFro%rxPN8yVBL^SsurZ?UkbXFU`1 zFSwM?qLVpUc?(nFOR!i!^es!}iIy4_wPI@mbxRke40P%D3>sF+G0-4QdRYfxNVy_j zN@)7}d*+=8qFr&{oExfJ581RN9`emR8RrRy!Fu4spCR|@@U898G0WV4B*fMKq)WuS z5o@T!S-7)&Q{${iQbApBAVT}=0S=$({xAG9NCy2@C?o-1PdKFOZX!xolyZh&FDbTQ z#)sX!E|}5)#!=@(JK6jv5@;`;k_8PXfJ^TkOR!5xjI^Zq2QoWHshNJ{6ih#by>Rx3 zN0i8=Q)7r=$;WlQr|H!aoR1OFPp;xT&B2aRye|HUq?)Ti(PAHMC|f_%fvYXi-cU

    Ai?r0*#_5{m-$MPFL`yJ`u!38S=QvU1TnKgrZB}_3hG(3SKh%5K5MItO3>C z?s58-5cAQtP_N`BjNtOwd`pBIDDB)FRa4dIBPr`bE;x-H^{o&xdLfTcU8o7F3*36aC}RMruf`c9&fXUn|pEK8L_9;LsIwKRDnwzaPLEjhM8E{cPyOEn}?>DLdu#4A#l z5KX9(TJpI>3njxNf(b4ZKWPw&XZo9CQIg{!T(>35C2$XQsa-=|G9BScg`cP-&&caX ztxI)51WPqE8cTvpD$?U6gpyz*iMi3*6S#zS5|`vc7E)yhVeUC2>8@Zhz;R&7QXcoDW(pSN=F0xoa^_uRAR z3y-;svora)GXeBg)diq>B1SPUeKb({Wo~UwFCRgHsm;e9(00sbHXg?wQ zSibLHp9PAh?e?S75c>ad$d@3a#W}>`{wFTvVmK|)B(cDxR;&=#!lJPPv7*P9NFxim z2^MA%PY99vS_&kx@Ye4FFXGJHNu5O>1Qv!7fYxV-jn{=}(Ie5tmS4JHRPq*32rO9m zT4)o-qGgn^(*b1c6xV_#K_W1Z*CD81i&n%IVi9BDYLqQF5?k;hLRb+Hw0DMWagXSc zH$ZOokZysAn8L|o(|cJqC{mzK+_iQh=WuzcK2WL2>l_KWOEZ1d>Jk(la6b!9o77S0nacvm|sS3}k@ zO1yR8S`i|$aEMS}*aL9lA+UvTq6BMiX+@IU5 znOPb22jNmKq1}Sq43^H{%{Ex7ugFj2B9j4hO*jPX=ov)A#~e1>>j7GYQS{2XEaD^1&jlg3{bu!FgceVU)JNyt7Gr$`?#_VX43XWwA`buv zgYaAJu~8aYpd#+$g@E8A+h(y6ksd2xW*W#pixmw9>t^&XmIHECAe#ty8t3Uh-Bf$@#LF$zZjC8X^{myV97Z`3Hh&tdATWS*!p7op0uvcZMs@A0! zjTVZCz{={@ESe@`sNKjgi@>&&M`)oqp@KCdIu#>$3pRxJN3$8I8mNJ0%GY8T0R@Xh zlP*v|s+}~(Q>fn-4~Wi;*VGm%36uOJT2s~FjdsX$Pj&-^6=J!680`QSi7bG$Q# zs2R2Yw??pQ5d!$eurb(3Y-5^ift{dWi`cV&o&=e9BZ$GEeFL8eBU?bGg^olPMu_oP zk*_dBY74^A9lfPUU`-ox?zQ`vAh;}dF$}rGSd!|7Wx#6)e9s$U@MQ3zYC#*WjNGCf z5sWGZbNPk+S(K1MJ%ImZ6j7y+YgLgiK^H^nUkr-;ZLonaW*KvpvHh1CY}5#DTM;6( z*qbo9pFtcwo#tq#h^&D$V3=Bbw~9ob!=!;?ZX3p6YAv{!C)NTq z%Ej72VX%`h{|{vtag|{VtHxtVU3C`U5eE51r~#ufXf7bzLOYQn3{l*D9_L`h2rY*C z-MQ!e0ye-5{G&hK8Lq`S!X#B1RIo1CqW8;Y5g$<^F=EZXYνh!$xPc|0uuS_w{J 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 z%0AH-Sg82Py%L|vUL;`Y!){Fp0^Z-FW%|HzhGN)PZyY9R))xH>IRFY*8NWy4>!q)L z?K#!ix|#PqzpKg4bhH7`{@xbG#@YdYRZ;iZ53qkR1O-n@?sv(sUX9-jCnqVlyYB_3 z=?)I)4(yCm@w6hL%*iKb|AMaND`3o>weWax z$OnI0iTBOv&VPjbg%8=wzBR|Vdu%~++eDU(9ms|WQ2C%0qflk$g9`s1GSB>;m+DNc z)vCokgik{`UaJZ7e{}Zwb7*6-7@G1|GNhjGLIDdf^@4_3@O(3bfY=kbJ4k#E&#hpG zEF35->eJ8?WT8gF$#Kb)FF(2N>x-exu}hnB_^}>ko(~bK9}cZ`IX+8SJT6>QzC{G8S^oga7ob89a4l zBmEG6@%NszT-M+W>W&A@Qd)Q3oSVL|k&Z31Hz~XC9&OJN2%MQp3M68M!0ByJ_ODAR zW-k+cRR&Z>s2t|A9>AenSX^*-X`~FzLhcEHMa)is%`dH0?*LSw~BiBOCpqmRBQ;eJtUx419NFM}2ZaMT}-D zFz%sZ8_gU)aGzWG83sA^uK8niM*10JK=>MaJN(WaH^NuX1~%-I7nFD=dm(QoF7x^P z>lB!fkB;cWN@#E#_=U+5jMGbKBV$wjW_<<$&<# z(CW+|(b}1dVr#T6e|ggCDqnH{a1F6++(qyIWBfdkvyPEoI@arnO{l|>$#)!G{TH&4 zkR+9E>7{mF91)bs24*PiK{=ib@j? z;l0POkQHz_MspU0j(3qI4UX;6uyohE$S7Sez6K+~{}A}lnD+)2k{J94g%tyRuP0G_ z#i@vEh~08s^!ikz(iSYi#I(~aGyBOkfMZ8!UgYF)XE+o1*9^?K+T|LqR{KMl#WqO3ZKn+8vytf z4BP5A;Byo%M6ge@BN~8#*Ei zIpfkt_}tu{yM^h+twlt+tqU2taP?v^)YW!3E*FoG;nbH02L43gHpP~fNYi#&t4EKu zI5>uQ|}A zsV}%9EO5ySIv`7^A3nsic#OeQJm(76kKGev>23LYYLcc7^M+rs)Ksh0YpbjEM{qlr z$=>5M^t9D~5#ANCIlUmm;2QnwMhLD(6I?=M+J|KB5_ zgb#n<(N4Rq_+{@capP%Fn|~!WGP#Bu)?e`bwq#4jD&}YpeZtwTfBH8pVAJ5dJ1?W+ zo?@n#?3AIkyPa3XR&+f3{=QxyA#$P-0JF{G6NAKnG3c5+6jj6>I`by5Oiowz{!HTY zh2BWwgwB_AZq1UPAqx24XQt_v!5!(hVWEZ-JaKBCo+C=!(N``h+)3qN@A^E6xzKj_ z86pAt%lSRXLbbYADuBa^rjZw<1yWd3)BFXRfaX=R&5y7-Y+g4D{8*gR=LNF>kCi#i zUeF74SUc1F1)hNC)w9iy3_S*__n`5NHCLgH2!)*pxOQoCGHZDFH&j2yh^7C`lt>jJ%OLGAH67 zH$sMyB+^9INE&iR$}pHjgUAR8M!rZF*^*fh6(NGop!3>Uk;6Qv&kJV(AFFekyx@KzrEWToI24!8z{0 zETJg>P`nCIdQk`B?#!WSaShPeH0}Q#?dC@)61Ic%buuk_lov?)ZOG;nBN_q=5o0QJ7>{ + diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/Update.svg b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/Update.svg new file mode 100644 index 0000000..75b3194 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/Update.svg @@ -0,0 +1,2 @@ + + diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/favicon.png b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..06713eec4974e141c6e9b4156d34e61e89f282ca GIT binary patch literal 4126 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 literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/mini-st_2020.css b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/mini-st_2020.css new file mode 100644 index 0000000..1b12ad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/mini-st_2020.css @@ -0,0 +1,1711 @@ +@charset "UTF-8"; +/* + Flavor name: Custom (mini-custom) + Generated online - https://minicss.org/flavors + mini.css version: v3.0.1 +*/ +/* + Browsers resets and base typography. +*/ +/* Core module CSS variable definitions */ +:root { + --fore-color: #03234b; + --secondary-fore-color: #03234b; + --back-color: #ffffff; + --secondary-back-color: #ffffff; + --blockquote-color: #e6007e; + --pre-color: #e6007e; + --border-color: #3cb4e6; + --secondary-border-color: #3cb4e6; + --heading-ratio: 1.2; + --universal-margin: 0.5rem; + --universal-padding: 0.25rem; + --universal-border-radius: 0.075rem; + --background-margin: 1.5%; + --a-link-color: #3cb4e6; + --a-visited-color: #8c0078; } + +html { + font-size: 13.5px; } + +a, b, del, em, i, ins, q, span, strong, u { + font-size: 1em; } + +html, * { + font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; + line-height: 1.25; + -webkit-text-size-adjust: 100%; } + +* { + font-size: 1rem; } + +body { + margin: 0; + color: var(--fore-color); + @background: var(--back-color); + background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; + background-size: var(--background-margin); + } + +details { + display: block; } + +summary { + display: list-item; } + +abbr[title] { + border-bottom: none; + text-decoration: underline dotted; } + +input { + overflow: visible; } + +img { + max-width: 100%; + height: auto; } + +h1, h2, h3, h4, h5, h6 { + line-height: 1.25; + margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); + font-weight: 400; } + h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + color: var(--secondary-fore-color); + display: block; + margin-top: -0.25rem; } + +h1 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } + +h2 { + font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); + border-style: none none solid none ; + border-width: thin; + border-color: var(--border-color); } +h3 { + font-size: calc(1rem * var(--heading-ratio) ); } + +h4 { + font-size: calc(1rem * var(--heading-ratio)); } + +h5 { + font-size: 1rem; } + +h6 { + font-size: calc(1rem / var(--heading-ratio)); } + +p { + margin: var(--universal-margin); } + +ol, ul { + margin: var(--universal-margin); + padding-left: calc(3 * var(--universal-margin)); } + +b, strong { + font-weight: 700; } + +hr { + box-sizing: content-box; + border: 0; + line-height: 1.25em; + margin: var(--universal-margin); + height: 0.0714285714rem; + background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } + +blockquote { + display: block; + position: relative; + font-style: italic; + color: var(--secondary-fore-color); + margin: var(--universal-margin); + padding: calc(3 * var(--universal-padding)); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.3rem solid var(--blockquote-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + blockquote:before { + position: absolute; + top: calc(0rem - var(--universal-padding)); + left: 0; + font-family: sans-serif; + font-size: 2rem; + font-weight: 800; + content: "\201c"; + color: var(--blockquote-color); } + blockquote[cite]:after { + font-style: normal; + font-size: 0.75em; + font-weight: 700; + content: "\a— " attr(cite); + white-space: pre; } + +code, kbd, pre, samp { + font-family: Menlo, Consolas, monospace; + font-size: 0.85em; } + +code { + background: var(--secondary-back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +kbd { + background: var(--fore-color); + color: var(--back-color); + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } + +pre { + overflow: auto; + background: var(--secondary-back-color); + padding: calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + border: 0.0714285714rem solid var(--secondary-border-color); + border-left: 0.2857142857rem solid var(--pre-color); + border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } + +sup, sub, code, kbd { + line-height: 0; + position: relative; + vertical-align: baseline; } + +small, sup, sub, figcaption { + font-size: 0.75em; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +figure { + margin: var(--universal-margin); } + +figcaption { + color: var(--secondary-fore-color); } + +a { + text-decoration: none; } + a:link { + color: var(--a-link-color); } + a:visited { + color: var(--a-visited-color); } + a:hover, a:focus { + text-decoration: underline; } + +/* + Definitions for the grid system, cards and containers. +*/ +.container { + margin: 0 auto; + padding: 0 calc(1.5 * var(--universal-padding)); } + +.row { + box-sizing: border-box; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + margin: 0 0 0 var(--background-margin); } + +.col-sm, +[class^='col-sm-'], +[class^='col-sm-offset-'], +.row[class*='cols-sm-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + +.col-sm, +.row.cols-sm > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + +.col-sm-1, +.row.cols-sm-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + +.col-sm-offset-0 { + margin-left: 0; } + +.col-sm-2, +.row.cols-sm-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + +.col-sm-offset-1 { + margin-left: 8.3333333333%; } + +.col-sm-3, +.row.cols-sm-3 > * { + max-width: 25%; + flex-basis: 25%; } + +.col-sm-offset-2 { + margin-left: 16.6666666667%; } + +.col-sm-4, +.row.cols-sm-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + +.col-sm-offset-3 { + margin-left: 25%; } + +.col-sm-5, +.row.cols-sm-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + +.col-sm-offset-4 { + margin-left: 33.3333333333%; } + +.col-sm-6, +.row.cols-sm-6 > * { + max-width: 50%; + flex-basis: 50%; } + +.col-sm-offset-5 { + margin-left: 41.6666666667%; } + +.col-sm-7, +.row.cols-sm-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + +.col-sm-offset-6 { + margin-left: 50%; } + +.col-sm-8, +.row.cols-sm-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + +.col-sm-offset-7 { + margin-left: 58.3333333333%; } + +.col-sm-9, +.row.cols-sm-9 > * { + max-width: 75%; + flex-basis: 75%; } + +.col-sm-offset-8 { + margin-left: 66.6666666667%; } + +.col-sm-10, +.row.cols-sm-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + +.col-sm-offset-9 { + margin-left: 75%; } + +.col-sm-11, +.row.cols-sm-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + +.col-sm-offset-10 { + margin-left: 83.3333333333%; } + +.col-sm-12, +.row.cols-sm-12 > * { + max-width: 100%; + flex-basis: 100%; } + +.col-sm-offset-11 { + margin-left: 91.6666666667%; } + +.col-sm-normal { + order: initial; } + +.col-sm-first { + order: -999; } + +.col-sm-last { + order: 999; } + +@media screen and (min-width: 500px) { + .col-md, + [class^='col-md-'], + [class^='col-md-offset-'], + .row[class*='cols-md-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-md, + .row.cols-md > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-md-1, + .row.cols-md-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-md-offset-0 { + margin-left: 0; } + + .col-md-2, + .row.cols-md-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-md-offset-1 { + margin-left: 8.3333333333%; } + + .col-md-3, + .row.cols-md-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-md-offset-2 { + margin-left: 16.6666666667%; } + + .col-md-4, + .row.cols-md-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-md-offset-3 { + margin-left: 25%; } + + .col-md-5, + .row.cols-md-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-md-offset-4 { + margin-left: 33.3333333333%; } + + .col-md-6, + .row.cols-md-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-md-offset-5 { + margin-left: 41.6666666667%; } + + .col-md-7, + .row.cols-md-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-md-offset-6 { + margin-left: 50%; } + + .col-md-8, + .row.cols-md-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-md-offset-7 { + margin-left: 58.3333333333%; } + + .col-md-9, + .row.cols-md-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-md-offset-8 { + margin-left: 66.6666666667%; } + + .col-md-10, + .row.cols-md-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-md-offset-9 { + margin-left: 75%; } + + .col-md-11, + .row.cols-md-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-md-offset-10 { + margin-left: 83.3333333333%; } + + .col-md-12, + .row.cols-md-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-md-offset-11 { + margin-left: 91.6666666667%; } + + .col-md-normal { + order: initial; } + + .col-md-first { + order: -999; } + + .col-md-last { + order: 999; } } +@media screen and (min-width: 1280px) { + .col-lg, + [class^='col-lg-'], + [class^='col-lg-offset-'], + .row[class*='cols-lg-'] > * { + box-sizing: border-box; + flex: 0 0 auto; + padding: 0 calc(var(--universal-padding) / 2); } + + .col-lg, + .row.cols-lg > * { + max-width: 100%; + flex-grow: 1; + flex-basis: 0; } + + .col-lg-1, + .row.cols-lg-1 > * { + max-width: 8.3333333333%; + flex-basis: 8.3333333333%; } + + .col-lg-offset-0 { + margin-left: 0; } + + .col-lg-2, + .row.cols-lg-2 > * { + max-width: 16.6666666667%; + flex-basis: 16.6666666667%; } + + .col-lg-offset-1 { + margin-left: 8.3333333333%; } + + .col-lg-3, + .row.cols-lg-3 > * { + max-width: 25%; + flex-basis: 25%; } + + .col-lg-offset-2 { + margin-left: 16.6666666667%; } + + .col-lg-4, + .row.cols-lg-4 > * { + max-width: 33.3333333333%; + flex-basis: 33.3333333333%; } + + .col-lg-offset-3 { + margin-left: 25%; } + + .col-lg-5, + .row.cols-lg-5 > * { + max-width: 41.6666666667%; + flex-basis: 41.6666666667%; } + + .col-lg-offset-4 { + margin-left: 33.3333333333%; } + + .col-lg-6, + .row.cols-lg-6 > * { + max-width: 50%; + flex-basis: 50%; } + + .col-lg-offset-5 { + margin-left: 41.6666666667%; } + + .col-lg-7, + .row.cols-lg-7 > * { + max-width: 58.3333333333%; + flex-basis: 58.3333333333%; } + + .col-lg-offset-6 { + margin-left: 50%; } + + .col-lg-8, + .row.cols-lg-8 > * { + max-width: 66.6666666667%; + flex-basis: 66.6666666667%; } + + .col-lg-offset-7 { + margin-left: 58.3333333333%; } + + .col-lg-9, + .row.cols-lg-9 > * { + max-width: 75%; + flex-basis: 75%; } + + .col-lg-offset-8 { + margin-left: 66.6666666667%; } + + .col-lg-10, + .row.cols-lg-10 > * { + max-width: 83.3333333333%; + flex-basis: 83.3333333333%; } + + .col-lg-offset-9 { + margin-left: 75%; } + + .col-lg-11, + .row.cols-lg-11 > * { + max-width: 91.6666666667%; + flex-basis: 91.6666666667%; } + + .col-lg-offset-10 { + margin-left: 83.3333333333%; } + + .col-lg-12, + .row.cols-lg-12 > * { + max-width: 100%; + flex-basis: 100%; } + + .col-lg-offset-11 { + margin-left: 91.6666666667%; } + + .col-lg-normal { + order: initial; } + + .col-lg-first { + order: -999; } + + .col-lg-last { + order: 999; } } +/* Card component CSS variable definitions */ +:root { + --card-back-color: #3cb4e6; + --card-fore-color: #03234b; + --card-border-color: #03234b; } + +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + align-self: center; + position: relative; + width: 100%; + background: var(--card-back-color); + color: var(--card-fore-color); + border: 0.0714285714rem solid var(--card-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + overflow: hidden; } + @media screen and (min-width: 320px) { + .card { + max-width: 320px; } } + .card > .sectione { + background: var(--card-back-color); + color: var(--card-fore-color); + box-sizing: border-box; + margin: 0; + border: 0; + border-radius: 0; + border-bottom: 0.0714285714rem solid var(--card-border-color); + padding: var(--universal-padding); + width: 100%; } + .card > .sectione.media { + height: 200px; + padding: 0; + -o-object-fit: cover; + object-fit: cover; } + .card > .sectione:last-child { + border-bottom: 0; } + +/* + Custom elements for card elements. +*/ +@media screen and (min-width: 240px) { + .card.small { + max-width: 240px; } } +@media screen and (min-width: 480px) { + .card.large { + max-width: 480px; } } +.card.fluid { + max-width: 100%; + width: auto; } + +.card.warning { + --card-back-color: #e5b8b7; + --card-fore-color: #3b234b; + --card-border-color: #8c0078; } + +.card.error { + --card-back-color: #464650; + --card-fore-color: #ffffff; + --card-border-color: #8c0078; } + +.card > .sectione.dark { + --card-back-color: #3b234b; + --card-fore-color: #ffffff; } + +.card > .sectione.double-padded { + padding: calc(1.5 * var(--universal-padding)); } + +/* + Definitions for forms and input elements. +*/ +/* Input_control module CSS variable definitions */ +:root { + --form-back-color: #ffe97f; + --form-fore-color: #03234b; + --form-border-color: #3cb4e6; + --input-back-color: #ffffff; + --input-fore-color: #03234b; + --input-border-color: #3cb4e6; + --input-focus-color: #0288d1; + --input-invalid-color: #d32f2f; + --button-back-color: #e2e2e2; + --button-hover-back-color: #dcdcdc; + --button-fore-color: #212121; + --button-border-color: transparent; + --button-hover-border-color: transparent; + --button-group-border-color: rgba(124, 124, 124, 0.54); } + +form { + background: var(--form-back-color); + color: var(--form-fore-color); + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); } + +fieldset { + border: 0.0714285714rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 4); + padding: var(--universal-padding); } + +legend { + box-sizing: border-box; + display: table; + max-width: 100%; + white-space: normal; + font-weight: 500; + padding: calc(var(--universal-padding) / 2); } + +label { + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +.input-group { + display: inline-block; } + .input-group.fluid { + display: flex; + align-items: center; + justify-content: center; } + .input-group.fluid > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + @media screen and (max-width: 499px) { + .input-group.fluid { + align-items: stretch; + flex-direction: column; } } + .input-group.vertical { + display: flex; + align-items: stretch; + flex-direction: column; } + .input-group.vertical > input { + max-width: 100%; + flex-grow: 1; + flex-basis: 0px; } + +[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { + height: auto; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], +[type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { + box-sizing: border-box; + background: var(--input-back-color); + color: var(--input-fore-color); + border: 0.0714285714rem solid var(--input-border-color); + border-radius: var(--universal-border-radius); + margin: calc(var(--universal-margin) / 2); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + +input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { + border-color: var(--input-focus-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { + border-color: var(--input-invalid-color); + box-shadow: none; } +input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { + background: var(--secondary-back-color); } + +select { + max-width: 100%; } + +option { + overflow: hidden; + text-overflow: ellipsis; } + +[type="checkbox"], [type="radio"] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + position: relative; + height: calc(1rem + var(--universal-padding) / 2); + width: calc(1rem + var(--universal-padding) / 2); + vertical-align: text-bottom; + padding: 0; + flex-basis: calc(1rem + var(--universal-padding) / 2) !important; + flex-grow: 0 !important; } + [type="checkbox"]:checked:before, [type="radio"]:checked:before { + position: absolute; } + +[type="checkbox"]:checked:before { + content: '\2713'; + font-family: sans-serif; + font-size: calc(1rem + var(--universal-padding) / 2); + top: calc(0rem - var(--universal-padding)); + left: calc(var(--universal-padding) / 4); } + +[type="radio"] { + border-radius: 100%; } + [type="radio"]:checked:before { + border-radius: 100%; + content: ''; + top: calc(0.0714285714rem + var(--universal-padding) / 2); + left: calc(0.0714285714rem + var(--universal-padding) / 2); + background: var(--input-fore-color); + width: 0.5rem; + height: 0.5rem; } + +:placeholder-shown { + color: var(--input-fore-color); } + +::-ms-placeholder { + color: var(--input-fore-color); + opacity: 0.54; } + +button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +button, html [type="button"], [type="reset"], [type="submit"] { + -webkit-appearance: button; } + +button { + overflow: visible; + text-transform: none; } + +button, [type="button"], [type="submit"], [type="reset"], +a.button, label.button, .button, +a[role="button"], label[role="button"], [role="button"] { + display: inline-block; + background: var(--button-back-color); + color: var(--button-fore-color); + border: 0.0714285714rem solid var(--button-border-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); + margin: var(--universal-margin); + text-decoration: none; + cursor: pointer; + transition: background 0.3s; } + button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, + a.button:hover, + a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, + a[role="button"]:hover, + a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { + background: var(--button-hover-back-color); + border-color: var(--button-hover-border-color); } + +input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { + cursor: not-allowed; + opacity: 0.75; } + +.button-group { + display: flex; + border: 0.0714285714rem solid var(--button-group-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { + margin: 0; + max-width: 100%; + flex: 1 1 auto; + text-align: center; + border: 0; + border-radius: 0; + box-shadow: none; } + .button-group > :not(:first-child) { + border-left: 0.0714285714rem solid var(--button-group-border-color); } + @media screen and (max-width: 499px) { + .button-group { + flex-direction: column; } + .button-group > :not(:first-child) { + border: 0; + border-top: 0.0714285714rem solid var(--button-group-border-color); } } + +/* + Custom elements for forms and input elements. +*/ +button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { + --button-back-color: #1976d2; + --button-fore-color: #f8f8f8; } + button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { + --button-hover-back-color: #1565c0; } + +button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { + --button-back-color: #d32f2f; + --button-fore-color: #f8f8f8; } + button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { + --button-hover-back-color: #c62828; } + +button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { + --button-back-color: #308732; + --button-fore-color: #f8f8f8; } + button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { + --button-hover-back-color: #277529; } + +button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { + --button-back-color: #212121; + --button-fore-color: #f8f8f8; } + button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { + --button-hover-back-color: #111; } + +button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { + padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); + margin: var(--universal-margin); } + +button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { + padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); + margin: var(--universal-margin); } + +/* + Definitions for navigation elements. +*/ +/* Navigation module CSS variable definitions */ +:root { + --header-back-color: #03234b; + --header-hover-back-color: #ffd200; + --header-fore-color: #ffffff; + --header-border-color: #3cb4e6; + --nav-back-color: #ffffff; + --nav-hover-back-color: #ffe97f; + --nav-fore-color: #e6007e; + --nav-border-color: #3cb4e6; + --nav-link-color: #3cb4e6; + --footer-fore-color: #ffffff; + --footer-back-color: #03234b; + --footer-border-color: #3cb4e6; + --footer-link-color: #3cb4e6; + --drawer-back-color: #ffffff; + --drawer-hover-back-color: #ffe97f; + --drawer-border-color: #3cb4e6; + --drawer-close-color: #e6007e; } + +header { + height: 2.75rem; + background: var(--header-back-color); + color: var(--header-fore-color); + border-bottom: 0.0714285714rem solid var(--header-border-color); + padding: calc(var(--universal-padding) / 4) 0; + white-space: nowrap; + overflow-x: auto; + overflow-y: hidden; } + header.row { + box-sizing: content-box; } + header .logo { + color: var(--header-fore-color); + font-size: 1.75rem; + padding: var(--universal-padding) calc(2 * var(--universal-padding)); + text-decoration: none; } + header button, header [type="button"], header .button, header [role="button"] { + box-sizing: border-box; + position: relative; + top: calc(0rem - var(--universal-padding) / 4); + height: calc(3.1875rem + var(--universal-padding) / 2); + background: var(--header-back-color); + line-height: calc(3.1875rem - var(--universal-padding) * 1.5); + text-align: center; + color: var(--header-fore-color); + border: 0; + border-radius: 0; + margin: 0; + text-transform: uppercase; } + header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { + background: var(--header-hover-back-color); } + +nav { + background: var(--nav-back-color); + color: var(--nav-fore-color); + border: 0.0714285714rem solid var(--nav-border-color); + border-radius: var(--universal-border-radius); + margin: var(--universal-margin); } + nav * { + padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } + nav a, nav a:visited { + display: block; + color: var(--nav-link-color); + border-radius: var(--universal-border-radius); + transition: background 0.3s; } + nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { + text-decoration: none; + background: var(--nav-hover-back-color); } + nav .sublink-1 { + position: relative; + margin-left: calc(2 * var(--universal-padding)); } + nav .sublink-1:before { + position: absolute; + left: calc(var(--universal-padding) - 1 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + nav .sublink-2 { + position: relative; + margin-left: calc(4 * var(--universal-padding)); } + nav .sublink-2:before { + position: absolute; + left: calc(var(--universal-padding) - 3 * var(--universal-padding)); + top: -0.0714285714rem; + content: ''; + height: 100%; + border: 0.0714285714rem solid var(--nav-border-color); + border-left: 0; } + +footer { + background: var(--footer-back-color); + color: var(--footer-fore-color); + border-top: 0.0714285714rem solid var(--footer-border-color); + padding: calc(2 * var(--universal-padding)) var(--universal-padding); + font-size: 0.875rem; } + footer a, footer a:visited { + color: var(--footer-link-color); } + +header.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + top: 0; } + +footer.sticky { + position: -webkit-sticky; + position: sticky; + z-index: 1101; + bottom: 0; } + +.drawer-toggle:before { + display: inline-block; + position: relative; + vertical-align: bottom; + content: '\00a0\2261\00a0'; + font-family: sans-serif; + font-size: 1.5em; } +@media screen and (min-width: 500px) { + .drawer-toggle:not(.persistent) { + display: none; } } + +[type="checkbox"].drawer { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].drawer + * { + display: block; + box-sizing: border-box; + position: fixed; + top: 0; + width: 320px; + height: 100vh; + overflow-y: auto; + background: var(--drawer-back-color); + border: 0.0714285714rem solid var(--drawer-border-color); + border-radius: 0; + margin: 0; + z-index: 1110; + right: -320px; + transition: right 0.3s; } + [type="checkbox"].drawer + * .drawer-close { + position: absolute; + top: var(--universal-margin); + right: var(--universal-margin); + z-index: 1111; + width: 2rem; + height: 2rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].drawer + * .drawer-close:before { + display: block; + content: '\00D7'; + color: var(--drawer-close-color); + position: relative; + font-family: sans-serif; + font-size: 2rem; + line-height: 1; + text-align: center; } + [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { + background: var(--drawer-hover-back-color); } + @media screen and (max-width: 320px) { + [type="checkbox"].drawer + * { + width: 100%; } } + [type="checkbox"].drawer:checked + * { + right: 0; } + @media screen and (min-width: 500px) { + [type="checkbox"].drawer:not(.persistent) + * { + position: static; + height: 100%; + z-index: 1100; } + [type="checkbox"].drawer:not(.persistent) + * .drawer-close { + display: none; } } + +/* + Definitions for the responsive table component. +*/ +/* Table module CSS variable definitions. */ +:root { + --table-border-color: #03234b; + --table-border-separator-color: #03234b; + --table-head-back-color: #03234b; + --table-head-fore-color: #ffffff; + --table-body-back-color: #ffffff; + --table-body-fore-color: #03234b; + --table-body-alt-back-color: #f4f4f4; } + +table { + border-collapse: separate; + border-spacing: 0; + margin: 0; + display: flex; + flex: 0 1 auto; + flex-flow: row wrap; + padding: var(--universal-padding); + padding-top: 0; } + table caption { + font-size: 1rem; + margin: calc(2 * var(--universal-margin)) 0; + max-width: 100%; + flex: 0 0 100%; } + table thead, table tbody { + display: flex; + flex-flow: row wrap; + border: 0.0714285714rem solid var(--table-border-color); } + table thead { + z-index: 999; + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; + border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } + table tbody { + border-top: 0; + margin-top: calc(0 - var(--universal-margin)); + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + table tr { + display: flex; + padding: 0; } + table th, table td { + padding: calc(0.5 * var(--universal-padding)); + font-size: 0.9rem; } + table th { + text-align: left; + background: var(--table-head-back-color); + color: var(--table-head-fore-color); } + table td { + background: var(--table-body-back-color); + color: var(--table-body-fore-color); + border-top: 0.0714285714rem solid var(--table-border-color); } + +table:not(.horizontal) { + overflow: auto; + max-height: 100%; } + table:not(.horizontal) thead, table:not(.horizontal) tbody { + max-width: 100%; + flex: 0 0 100%; } + table:not(.horizontal) tr { + flex-flow: row wrap; + flex: 0 0 100%; } + table:not(.horizontal) th, table:not(.horizontal) td { + flex: 1 0 0%; + overflow: hidden; + text-overflow: ellipsis; } + table:not(.horizontal) thead { + position: sticky; + top: 0; } + table:not(.horizontal) tbody tr:first-child td { + border-top: 0; } + +table.horizontal { + border: 0; } + table.horizontal thead, table.horizontal tbody { + border: 0; + flex: .2 0 0; + flex-flow: row nowrap; } + table.horizontal tbody { + overflow: auto; + justify-content: space-between; + flex: .8 0 0; + margin-left: 0; + padding-bottom: calc(var(--universal-padding) / 4); } + table.horizontal tr { + flex-direction: column; + flex: 1 0 auto; } + table.horizontal th, table.horizontal td { + width: auto; + border: 0; + border-bottom: 0.0714285714rem solid var(--table-border-color); } + table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { + border-top: 0; } + table.horizontal th { + text-align: right; + border-left: 0.0714285714rem solid var(--table-border-color); + border-right: 0.0714285714rem solid var(--table-border-separator-color); } + table.horizontal thead tr:first-child { + padding-left: 0; } + table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td { + border-right: 0.0714285714rem solid var(--table-border-color); } + table.horizontal tbody tr:last-child td:first-child { + border-top-right-radius: 0.25rem; } + table.horizontal tbody tr:last-child td:last-child { + border-bottom-right-radius: 0.25rem; } + table.horizontal thead tr:first-child th:first-child { + border-top-left-radius: 0.25rem; } + table.horizontal thead tr:first-child th:last-child { + border-bottom-left-radius: 0.25rem; } + +@media screen and (max-width: 499px) { + table, table.horizontal { + border-collapse: collapse; + border: 0; + width: 100%; + display: table; } + table thead, table th, table.horizontal thead, table.horizontal th { + border: 0; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + table tbody, table.horizontal tbody { + border: 0; + display: table-row-group; } + table tr, table.horizontal tr { + display: block; + border: 0.0714285714rem solid var(--table-border-color); + border-radius: var(--universal-border-radius); + background: #ffffff; + padding: var(--universal-padding); + margin: var(--universal-margin); + margin-bottom: calc(1 * var(--universal-margin)); } + table th, table td, table.horizontal th, table.horizontal td { + width: auto; } + table td, table.horizontal td { + display: block; + border: 0; + text-align: right; } + table td:before, table.horizontal td:before { + content: attr(data-label); + float: left; + font-weight: 600; } + table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { + border-top: 0; } + table tbody tr:last-child td, table.horizontal tbody tr:last-child td { + border-right: 0; } } +table tr:nth-of-type(2n) > td { + background: var(--table-body-alt-back-color); } + +@media screen and (max-width: 500px) { + table tr:nth-of-type(2n) { + background: var(--table-body-alt-back-color); } } +:root { + --table-body-hover-back-color: #90caf9; } + +table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } + +@media screen and (max-width: 500px) { + table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { + background: var(--table-body-hover-back-color); } } +/* + Definitions for contextual background elements, toasts and tooltips. +*/ +/* Contextual module CSS variable definitions */ +:root { + --mark-back-color: #3cb4e6; + --mark-fore-color: #ffffff; } + +mark { + background: var(--mark-back-color); + color: var(--mark-fore-color); + font-size: 0.95em; + line-height: 1em; + border-radius: var(--universal-border-radius); + padding: calc(var(--universal-padding) / 4) var(--universal-padding); } + mark.inline-block { + display: inline-block; + font-size: 1em; + line-height: 1.4; + padding: calc(var(--universal-padding) / 2) var(--universal-padding); } + +:root { + --toast-back-color: #424242; + --toast-fore-color: #fafafa; } + +.toast { + position: fixed; + bottom: calc(var(--universal-margin) * 3); + left: 50%; + transform: translate(-50%, -50%); + z-index: 1111; + color: var(--toast-fore-color); + background: var(--toast-back-color); + border-radius: calc(var(--universal-border-radius) * 16); + padding: var(--universal-padding) calc(var(--universal-padding) * 3); } + +:root { + --tooltip-back-color: #212121; + --tooltip-fore-color: #fafafa; } + +.tooltip { + position: relative; + display: inline-block; } + .tooltip:before, .tooltip:after { + position: absolute; + opacity: 0; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: all 0.3s; + z-index: 1010; + left: 50%; } + .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { + bottom: 75%; } + .tooltip.bottom:before, .tooltip.bottom:after { + top: 75%; } + .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { + opacity: 1; + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); } + .tooltip:before { + content: ''; + background: transparent; + border: var(--universal-margin) solid transparent; + left: calc(50% - var(--universal-margin)); } + .tooltip:not(.bottom):before { + border-top-color: #212121; } + .tooltip.bottom:before { + border-bottom-color: #212121; } + .tooltip:after { + content: attr(aria-label); + color: var(--tooltip-fore-color); + background: var(--tooltip-back-color); + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + white-space: nowrap; + transform: translateX(-50%); } + .tooltip:not(.bottom):after { + margin-bottom: calc(2 * var(--universal-margin)); } + .tooltip.bottom:after { + margin-top: calc(2 * var(--universal-margin)); } + +:root { + --modal-overlay-color: rgba(0, 0, 0, 0.45); + --modal-close-color: #e6007e; + --modal-close-hover-color: #ffe97f; } + +[type="checkbox"].modal { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + [type="checkbox"].modal + div { + position: fixed; + top: 0; + left: 0; + display: none; + width: 100vw; + height: 100vh; + background: var(--modal-overlay-color); } + [type="checkbox"].modal + div .card { + margin: 0 auto; + max-height: 50vh; + overflow: auto; } + [type="checkbox"].modal + div .card .modal-close { + position: absolute; + top: 0; + right: 0; + width: 1.75rem; + height: 1.75rem; + border-radius: var(--universal-border-radius); + padding: var(--universal-padding); + margin: 0; + cursor: pointer; + transition: background 0.3s; } + [type="checkbox"].modal + div .card .modal-close:before { + display: block; + content: '\00D7'; + color: var(--modal-close-color); + position: relative; + font-family: sans-serif; + font-size: 1.75rem; + line-height: 1; + text-align: center; } + [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { + background: var(--modal-close-hover-color); } + [type="checkbox"].modal:checked + div { + display: flex; + flex: 0 1 auto; + z-index: 1200; } + [type="checkbox"].modal:checked + div .card .modal-close { + z-index: 1211; } + +:root { + --collapse-label-back-color: #03234b; + --collapse-label-fore-color: #ffffff; + --collapse-label-hover-back-color: #3cb4e6; + --collapse-selected-label-back-color: #3cb4e6; + --collapse-border-color: var(--collapse-label-back-color); + --collapse-selected-border-color: #ceecf8; + --collapse-content-back-color: #ffffff; + --collapse-selected-label-border-color: #3cb4e6; } + +.collapse { + width: calc(100% - 2 * var(--universal-margin)); + opacity: 1; + display: flex; + flex-direction: column; + margin: var(--universal-margin); + border-radius: var(--universal-border-radius); } + .collapse > [type="radio"], .collapse > [type="checkbox"] { + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); } + .collapse > label { + flex-grow: 1; + display: inline-block; + height: 1.25rem; + cursor: pointer; + transition: background 0.2s; + color: var(--collapse-label-fore-color); + background: var(--collapse-label-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + padding: calc(1.25 * var(--universal-padding)); } + .collapse > label:hover, .collapse > label:focus { + background: var(--collapse-label-hover-back-color); } + .collapse > label + div { + flex-basis: auto; + height: 1px; + width: 1px; + margin: -1px; + overflow: hidden; + position: absolute; + clip: rect(0 0 0 0); + -webkit-clip-path: inset(100%); + clip-path: inset(100%); + transition: max-height 0.3s; + max-height: 1px; } + .collapse > :checked + label { + background: var(--collapse-selected-label-back-color); + border-color: var(--collapse-selected-label-border-color); } + .collapse > :checked + label + div { + box-sizing: border-box; + position: relative; + width: 100%; + height: auto; + overflow: auto; + margin: 0; + background: var(--collapse-content-back-color); + border: 0.0714285714rem solid var(--collapse-selected-border-color); + border-top: 0; + padding: var(--universal-padding); + clip: auto; + -webkit-clip-path: inset(0%); + clip-path: inset(0%); + max-height: 100%; } + .collapse > label:not(:first-of-type) { + border-top: 0; } + .collapse > label:first-of-type { + border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } + .collapse > label:last-of-type:not(:first-of-type) { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + .collapse > label:last-of-type:first-of-type { + border-radius: var(--universal-border-radius); } + .collapse > :checked:last-of-type:not(:first-of-type) + label { + border-radius: 0; } + .collapse > :checked:last-of-type + label + div { + border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } + +/* + Custom elements for contextual background elements, toasts and tooltips. +*/ +mark.tertiary { + --mark-back-color: #3cb4e6; } + +mark.tag { + padding: calc(var(--universal-padding)/2) var(--universal-padding); + border-radius: 1em; } + +/* + Definitions for progress elements and spinners. +*/ +/* Progress module CSS variable definitions */ +:root { + --progress-back-color: #3cb4e6; + --progress-fore-color: #555; } + +progress { + display: block; + vertical-align: baseline; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 0.75rem; + width: calc(100% - 2 * var(--universal-margin)); + margin: var(--universal-margin); + border: 0; + border-radius: calc(2 * var(--universal-border-radius)); + background: var(--progress-back-color); + color: var(--progress-fore-color); } + progress::-webkit-progress-value { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress::-webkit-progress-bar { + background: var(--progress-back-color); } + progress::-moz-progress-bar { + background: var(--progress-fore-color); + border-top-left-radius: calc(2 * var(--universal-border-radius)); + border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-webkit-progress-value { + border-radius: calc(2 * var(--universal-border-radius)); } + progress[value="1000"]::-moz-progress-bar { + border-radius: calc(2 * var(--universal-border-radius)); } + progress.inline { + display: inline-block; + vertical-align: middle; + width: 60%; } + +:root { + --spinner-back-color: #ddd; + --spinner-fore-color: #555; } + +@keyframes spinner-donut-anim { + 0% { + transform: rotate(0deg); } + 100% { + transform: rotate(360deg); } } +.spinner { + display: inline-block; + margin: var(--universal-margin); + border: 0.25rem solid var(--spinner-back-color); + border-left: 0.25rem solid var(--spinner-fore-color); + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + animation: spinner-donut-anim 1.2s linear infinite; } + +/* + Custom elements for progress bars and spinners. +*/ +progress.primary { + --progress-fore-color: #1976d2; } + +progress.secondary { + --progress-fore-color: #d32f2f; } + +progress.tertiary { + --progress-fore-color: #308732; } + +.spinner.primary { + --spinner-fore-color: #1976d2; } + +.spinner.secondary { + --spinner-fore-color: #d32f2f; } + +.spinner.tertiary { + --spinner-fore-color: #308732; } + +/* + Definitions for icons - powered by Feather (https://feathericons.com/). +*/ +span[class^='icon-'] { + display: inline-block; + height: 1em; + width: 1em; + vertical-align: -0.125em; + background-size: contain; + margin: 0 calc(var(--universal-margin) / 4); } + span[class^='icon-'].secondary { + -webkit-filter: invert(25%); + filter: invert(25%); } + span[class^='icon-'].inverse { + -webkit-filter: invert(100%); + filter: invert(100%); } + +span.icon-alert { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-bookmark { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-calendar { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-credit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-edit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } +span.icon-link { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-help { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-home { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-info { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-lock { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-mail { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } +span.icon-location { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-phone { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-rss { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } +span.icon-search { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-settings { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-share { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-cart { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } +span.icon-upload { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } +span.icon-user { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } + +/* + Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). +*/ +span.icon-st-update { + background-image: url("Update.svg"); } +span.icon-st-add { + background-image: url("Add button.svg"); } + +/* + Definitions for utilities and helper classes. +*/ +/* Utility module CSS variable definitions */ +:root { + --generic-border-color: rgba(0, 0, 0, 0.3); + --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } + +.hidden { + display: none !important; } + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } + +.bordered { + border: 0.0714285714rem solid var(--generic-border-color) !important; } + +.rounded { + border-radius: var(--universal-border-radius) !important; } + +.circular { + border-radius: 50% !important; } + +.shadowed { + box-shadow: var(--generic-box-shadow) !important; } + +.responsive-margin { + margin: calc(var(--universal-margin) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-margin { + margin: calc(var(--universal-margin) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-margin { + margin: var(--universal-margin) !important; } } + +.responsive-padding { + padding: calc(var(--universal-padding) / 4) !important; } + @media screen and (min-width: 500px) { + .responsive-padding { + padding: calc(var(--universal-padding) / 2) !important; } } + @media screen and (min-width: 1280px) { + .responsive-padding { + padding: var(--universal-padding) !important; } } + +@media screen and (max-width: 499px) { + .hidden-sm { + display: none !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .hidden-md { + display: none !important; } } +@media screen and (min-width: 1280px) { + .hidden-lg { + display: none !important; } } +@media screen and (max-width: 499px) { + .visually-hidden-sm { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 500px) and (max-width: 1279px) { + .visually-hidden-md { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } +@media screen and (min-width: 1280px) { + .visually-hidden-lg { + position: absolute !important; + width: 1px !important; + height: 1px !important; + margin: -1px !important; + border: 0 !important; + padding: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + overflow: hidden !important; } } + +/*# sourceMappingURL=mini-custom.css.map */ + +img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } +img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} + +.figure { + display: block; + margin-left: auto; + margin-right: auto; + text-align: center; +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/st_logo_2020.png b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/_htmresc/st_logo_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cebb5ac70e0594cbe37a6b60036a80ef3bed37 GIT binary patch literal 7520 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"NJQ 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 b^}%0^qYmp2WD(pA|JtZ4>nPPKybJpu3@X?! literal 0 HcmV?d00001 diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/bumpversion.cfg b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/bumpversion.cfg new file mode 100644 index 0000000..3abb847 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/bumpversion.cfg @@ -0,0 +1,27 @@ +{ + "name": "BSP Disco", + "configList": [ + { + "file": "stm32h7s78_discovery.h", + "commit": true, + "replacements": [ + { + "search":"VERSION_MAIN\\s+\\(0x[a-fA-F\\d]+U?\\)", + "replace":"'VERSION_MAIN (0x' + '{:02X}'.format(major) + 'U)'" + }, + { + "search":"VERSION_SUB1\\s+\\(0x[a-fA-F\\d]+U?\\)", + "replace":"'VERSION_SUB1 (0x' + '{:02X}'.format(minor) + 'U)'" + }, + { + "search":"VERSION_SUB2\\s+\\(0x[a-fA-F\\d]+U?\\)", + "replace":"'VERSION_SUB2 (0x' + '{:02X}'.format(patch) + 'U)'" + }, + { + "search":"VERSION_RC\\s+\\(0x[a-fA-F\\d]+U?\\)", + "replace":"'VERSION_RC (0x' + '{:02X}'.format(rc) + 'U)'" + } + ] + } + ] +} \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/md2html.sh b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/md2html.sh new file mode 100644 index 0000000..02afd71 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/md2html.sh @@ -0,0 +1 @@ +pandoc -s -r markdown -t html5 -c "_htmresc/mini-st_2020.css" Release_Notes.md > Release_Notes.html diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.c new file mode 100644 index 0000000..4f208a4 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.c @@ -0,0 +1,841 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery.c + * @author MCD Application Team + * @brief This file provides a set of firmware functions to manage + * LEDs + * push-buttons + * COM ports + * available on STM32H7S78-DK board(MB1736) from STMicroelectronics. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery.h" + +#if defined(__ICCARM__) +#include +#endif /* __ICCARM__ */ + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL LOW LEVEL + * @{ + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Private_TypesDefinitions Private Types Definitions + * @{ + */ +typedef void (* BSP_EXTI_LineCallback)(void); +/** + * @} + */ +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Private_FunctionPrototypes Private Function Prototypes + * @{ + */ +static void BUTTON_USER_EXTI_Callback(void); +#if (USE_BSP_COM_FEATURE > 0) +static void UART_MspInit(const UART_HandleTypeDef *huart); +static void UART_MspDeInit(const UART_HandleTypeDef *huart); +#endif /* USE_BSP_COM_FEATURE > 0 */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Exported_Variables Exported Variables + * @{ + */ +EXTI_HandleTypeDef hpb_exti[BUTTONn]; +#if (USE_BSP_COM_FEATURE > 0) +UART_HandleTypeDef hcom_uart[COMn]; +USART_TypeDef *COM_UART[COMn] = {COM1_UART, COM2_UART}; +#endif /* USE_BSP_COM_FEATURE > 0 */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Private_Variables Private Variables + * @{ + */ + +static GPIO_TypeDef *LED_PORT[LEDn] = {LD1_GPIO_PORT, + LD2_GPIO_PORT, + LD3_GPIO_PORT, + LD4_GPIO_PORT + }; + +static const uint16_t LED_PIN[LEDn] = {LD1_PIN, + LD2_PIN, + LD3_PIN, + LD4_PIN + }; + +static GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {BUTTON_USER_GPIO_PORT }; + +static const uint16_t BUTTON_PIN[BUTTONn] = {BUTTON_USER_PIN }; + +static const IRQn_Type BUTTON_IRQn[BUTTONn] = {BUTTON_USER_EXTI_IRQn }; + +#if (USE_COM_LOG == 1) +static COM_TypeDef COM_ActiveLogPort = COM1; + +/** + * @brief Redirect console output to COM + */ +#if defined(__ICCARM__) +/* New definition from EWARM V9, compatible with EWARM8 */ +int iar_fputc(int ch); +#define PUTCHAR_PROTOTYPE int iar_fputc(int ch) + +#elif defined (__CC_ARM) || defined(__ARMCC_VERSION) +/* ARM Compiler 5/6 */ +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) + +#elif defined(__GNUC__) +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) + +#endif /* __ICCARM__ */ +#endif /* USE_COM_LOG */ + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +static uint32_t IsComMspCbValid[COMn] = {0}; +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Private_Constants Private Constants + * @{ + */ +#define STM32H7S78_DK_PWR_FLAG_SETTING_DELAY (1000U) +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief This method returns the STM32H7S78 Discovery BSP Driver revision + * @retval version: 0xXYZR (8bits for each decimal, R for RC) + */ +int32_t BSP_GetVersion(void) +{ + return ((int32_t)STM32H7S78_DK_BSP_VERSION); +} + +/** + * @brief This method returns the board name + * @retval pointer to the board name string + */ +const uint8_t *BSP_GetBoardName(void) +{ + return (const uint8_t *) STM32H7S78_DK_BSP_BOARD_NAME; +} + +/** + * @brief This method returns the board ID + * @retval pointer to the board name string + */ +const uint8_t *BSP_GetBoardID(void) +{ + return (const uint8_t *)STM32H7S78_DK_BSP_BOARD_ID; +} + +/** + * @brief Configure LED on GPIO. + * @param Led Specifies the Led to be configured. + * This parameter can be one of the following values: + * @arg LD1 + * @arg LD2 + * @arg LD3 + * @arg LD4 + * @retval BSP error code + */ +int32_t BSP_LED_Init(Led_TypeDef Led) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure = {0}; + uint32_t tickstart; + + /* Enable the GPIO_LED clock */ + switch (Led) + { + case LD1: + /* Enable the power of PORT_O XSPIx */ + HAL_PWREx_EnableXSPIM1(); + + LD1_GPIO_CLK_ENABLE(); + break; + + case LD2: + /* Enable the power of PORT_O XSPIx */ + HAL_PWREx_EnableXSPIM1(); + + LD2_GPIO_CLK_ENABLE(); + break; + + case LD3: + /* Enable the power of PORT_M */ + if (HAL_PWREx_EnableUSBVoltageDetector() != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Wait the detection of the USB33 power */ + tickstart = HAL_GetTick(); + while ( (PWR->CSR2 & PWR_CSR2_USB33RDY)== 0U) + { + if ((HAL_GetTick() - tickstart) > STM32H7S78_DK_PWR_FLAG_SETTING_DELAY) + { + return BSP_ERROR_PERIPH_FAILURE; + } + } + + LD3_GPIO_CLK_ENABLE(); + } + break; + + default: /* LD4 */ + /* Enable the power of PORT_M */ + if (HAL_PWREx_EnableUSBVoltageDetector() != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Wait the detection of the USB33 power */ + tickstart = HAL_GetTick(); + while ( (PWR->CSR2 & PWR_CSR2_USB33RDY)== 0U) + { + if ((HAL_GetTick() - tickstart) > STM32H7S78_DK_PWR_FLAG_SETTING_DELAY) + { + return BSP_ERROR_PERIPH_FAILURE; + } + } + + LD4_GPIO_CLK_ENABLE(); + } + break; + } + + if (ret == BSP_ERROR_NONE) + { + /* configure the GPIO_LED pin */ + gpio_init_structure.Pin = LED_PIN [Led]; + gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(LED_PORT [Led], &gpio_init_structure); + + /* By default, turn off LED */ + (void) BSP_LED_Off(Led); + } + + return ret; +} + + +/** + * @brief DeInitialize LEDs. + * @param Led LED to be de-init. + * This parameter can be one of the following values: + * @arg LD1 + * @arg LD2 + * @arg LD3 + * @arg LD4 + * @note BSP_LED_DeInit() does not disable the GPIO clock + * @retval BSP error code + */ +int32_t BSP_LED_DeInit(Led_TypeDef Led) +{ + GPIO_InitTypeDef gpio_init_structure = {0}; + + /* Turn off LED */ + (void) BSP_LED_Off(Led); + + /* DeInit the GPIO_LED pin */ + gpio_init_structure.Pin = LED_PIN [Led]; + HAL_GPIO_DeInit(LED_PORT [Led], gpio_init_structure.Pin); + + return BSP_ERROR_NONE; +} + +/** + * @brief Turn selected LED On. + * @param Led Specifies the Led to be set on. + * This parameter can be one of the following values: + * @arg LD1 + * @arg LD2 + * @arg LD3 + * @arg LD4 + * @retval BSP error code + */ +int32_t BSP_LED_On(Led_TypeDef Led) +{ + if(Led <= LD2) + { + /* LD1/LD2 High active */ + HAL_GPIO_WritePin(LED_PORT [Led], (uint16_t)LED_PIN [Led], GPIO_PIN_SET); + } + else + { + /* LD3/LD4 Low active */ + HAL_GPIO_WritePin(LED_PORT [Led], (uint16_t)LED_PIN [Led], GPIO_PIN_RESET); + } + + return BSP_ERROR_NONE; +} + +/** + * @brief Turn selected LED Off. + * @param Led Specifies the Led to be set off. + * This parameter can be one of the following values: + * @arg LD1 + * @arg LD2 + * @arg LD3 + * @arg LD4 + * @retval BSP error code + */ +int32_t BSP_LED_Off(Led_TypeDef Led) +{ + if (Led <= LD2) + { + /* LD1/LD2 High active */ + HAL_GPIO_WritePin(LED_PORT [Led], (uint16_t)LED_PIN [Led], GPIO_PIN_RESET); + } + else + { + /* LD3/LD4 Low active */ + HAL_GPIO_WritePin(LED_PORT [Led], (uint16_t)LED_PIN [Led], GPIO_PIN_SET); + } + + return BSP_ERROR_NONE; +} + +/** + * @brief Toggle the selected LED. + * @param Led Specifies the Led to be toggled. + * This parameter can be one of the following values: + * @arg LD1 + * @arg LD2 + * @arg LD3 + * @arg LD4 + * @retval BSP error code + */ +int32_t BSP_LED_Toggle(Led_TypeDef Led) +{ + HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]); + + return BSP_ERROR_NONE; +} +/** + * @brief Get the state of selected LED. + * @param Led Specifies the Led. + * This parameter can be one of the following values: + * @arg LD1 + * @arg LD2 + * @arg LD3 + * @arg LD4 + * @retval 0 means off, 1 means on. + */ +int32_t BSP_LED_GetState(Led_TypeDef Led) +{ + int32_t ret; + + ret = (int32_t) HAL_GPIO_ReadPin(LED_PORT[Led], LED_PIN[Led]); + if (Led >= LD3) + { + /* LD3/LD4 is active low */ + ret = (int32_t)((ret == 1) ? 0 : 1); + } + + return ret; +} + +/** + * @brief Configure Button GPIO and EXTI Line. + * @param Button Specifies the Button to be configured. + * This parameter can be one of the following values: + * @arg BUTTON_USER: User Push Button + * @param ButtonMode Specifies Button mode. + * This parameter can be one of the following values: + * @arg BUTTON_MODE_GPIO: Button will be used as simple IO + * @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line + * with interrupt generation capability + * @retval BSP error code + */ +int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode) +{ + GPIO_InitTypeDef gpio_init_structure = {0}; + static BSP_EXTI_LineCallback ButtonCallback[BUTTONn] = {BUTTON_USER_EXTI_Callback}; + static uint32_t BSP_BUTTON_PRIO [BUTTONn] = {BSP_BUTTON_USER_IT_PRIORITY}; + static const uint32_t BUTTON_EXTI_LINE[BUTTONn] = {BUTTON_USER_EXTI_LINE}; + + /* Enable the BUTTON clock */ + BUTTON_USER_GPIO_CLK_ENABLE(); + gpio_init_structure.Pin = BUTTON_PIN [Button]; + gpio_init_structure.Pull = GPIO_PULLDOWN; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_LOW; + + if (ButtonMode == BUTTON_MODE_GPIO) + { + /* Configure Button pin as input */ + gpio_init_structure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure); + } + else /* ButtonMode == BUTTON_MODE_EXTI */ + { + /* Enable SBS clock */ + __HAL_RCC_SBS_CLK_ENABLE(); + + /* Configure Button pin as input with External interrupt */ + gpio_init_structure.Mode = GPIO_MODE_IT_FALLING; + + HAL_GPIO_Init(BUTTON_PORT[Button], &gpio_init_structure); + + (void)HAL_EXTI_GetHandle(&hpb_exti[Button], BUTTON_EXTI_LINE[Button]); + (void)HAL_EXTI_RegisterCallback(&hpb_exti[Button], HAL_EXTI_COMMON_CB_ID, ButtonCallback[Button]); + + /* Enable and set Button EXTI Interrupt to the lowest priority */ + HAL_NVIC_SetPriority((BUTTON_IRQn[Button]), BSP_BUTTON_PRIO[Button], 0x00); + HAL_NVIC_EnableIRQ((BUTTON_IRQn[Button])); + } + + return BSP_ERROR_NONE; +} + +/** + * @brief DeInitialize Push Button. + * @param Button Button to be configured. + * This parameter can be one of the following values: + * @arg BUTTON_USER: User Push Button + * @note BSP_PB_DeInit() does not disable the GPIO clock + * @retval BSP error code + */ +int32_t BSP_PB_DeInit(Button_TypeDef Button) +{ + GPIO_InitTypeDef gpio_init_structure = {0}; + + gpio_init_structure.Pin = BUTTON_PIN[Button]; + HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button])); + HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin); + + return BSP_ERROR_NONE; +} + + +/** + * @brief Return the selected button state. + * @param Button Specifies the Button to be checked. + * This parameter can be one of the following values: + * @arg BUTTON_USER: User Push Button + * @retval The Button GPIO pin value + */ +int32_t BSP_PB_GetState(Button_TypeDef Button) +{ + return (int32_t) HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]); +} +/** + * @brief This function handles Push-Button interrupt requests. + * @param Button Specifies the pin connected EXTI line + * @retval None + */ +void BSP_PB_IRQHandler(Button_TypeDef Button) +{ + HAL_EXTI_IRQHandler(&hpb_exti[Button]); +} +/** + * @brief KEY EXTI line detection callbacks. + * @retval None + */ +static void BUTTON_USER_EXTI_Callback(void) +{ + BSP_PB_Callback(BUTTON_USER); +} +/** + * @brief BSP Push Button callback + * @param Button Specifies the pin connected EXTI line + * @retval None. + */ +__weak void BSP_PB_Callback(Button_TypeDef Button) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Button); + /* This function should be implemented by the user application. + It is called into this driver when an event on Button is triggered. */ +} + +#if (USE_BSP_COM_FEATURE > 0) +/** + * @brief Configure COM port. + * @param COM COM port to be configured. + * This parameter can be COM1 or COM2. + * @param COM_Init Pointer to a UART_HandleTypeDef structure that contains the + * configuration information for the specified USART peripheral. + * @retval BSP error code + */ +int32_t BSP_COM_Init(COM_TypeDef COM, COM_InitTypeDef *COM_Init) +{ + int32_t ret = BSP_ERROR_NONE; + + if (COM >= COMn) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Initialize COM instance */ + hcom_uart[COM].Instance = COM_UART[COM]; + + /* Init the UART Msp */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 0) + UART_MspInit(&hcom_uart[COM]); +#else + if (IsComMspCbValid[COM] == 0U) + { + if (BSP_COM_RegisterDefaultMspCallbacks(COM) != BSP_ERROR_NONE) + { + return BSP_ERROR_MSP_FAILURE; + } + } +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + + if (COM == COM1) + { + if (MX_UART4_Init(&hcom_uart[COM], COM_Init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + else + { + if (MX_UART7_Init(&hcom_uart[COM], COM_Init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + } + + return ret; +} + +/** + * @brief DeInitialize COM port. + * @param COM COM port to be de_init. + * This parameter can be COM1 or COM2. + * @retval BSP error code + */ +int32_t BSP_COM_DeInit(COM_TypeDef COM) +{ + int32_t ret = BSP_ERROR_NONE; + + if (COM >= COMn) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* USART configuration */ + hcom_uart[COM].Instance = COM_UART[COM]; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 0) + UART_MspDeInit(&hcom_uart[COM]); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS == 0) */ + + if (HAL_UART_DeInit(&hcom_uart[COM]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + return ret; +} + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +/** + * @brief Register default COM msp callbacks. + * @param COM COM port. + * @retval BSP status + */ +int32_t BSP_COM_RegisterDefaultMspCallbacks(COM_TypeDef COM) +{ + int32_t ret = BSP_ERROR_NONE; + + if (COM >= COMn) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + __HAL_UART_RESET_HANDLE_STATE(&hcom_uart[COM]); + + /* Register default MspInit/MspDeInit Callback */ + if (HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPINIT_CB_ID, (pUART_CallbackTypeDef) UART_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPDEINIT_CB_ID, (pUART_CallbackTypeDef) UART_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + IsComMspCbValid[COM] = 1U; + } + } + + /* BSP status */ + return ret; +} + +/** + * @brief Register COM1 Msp Callback registering + * @param COM COM port to be configured. + * @param Callbacks pointer to COM MspInit/MspDeInit callback functions + * @retval BSP status + */ +int32_t BSP_COM_RegisterMspCallbacks(COM_TypeDef COM, BSP_COM_Cb_t *Callback) +{ + int32_t ret = BSP_ERROR_NONE; + + if (COM >= COMn) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + __HAL_UART_RESET_HANDLE_STATE(&hcom_uart[COM]); + + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPINIT_CB_ID, Callback->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_UART_RegisterCallback(&hcom_uart[COM], HAL_UART_MSPDEINIT_CB_ID, Callback->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + IsComMspCbValid[COM] = 1U; + } + } + + /* BSP status */ + return ret; +} +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +#if (USE_COM_LOG == 1) +/** + * @brief Select the active COM port. + * @param COM COM port to be activated. + * This parameter can be COM1 or COM2. + * @retval BSP status + */ +int32_t BSP_COM_SelectLogPort(COM_TypeDef COM) +{ + if (COM_ActiveLogPort != COM) + { + COM_ActiveLogPort = COM; + } + return BSP_ERROR_NONE; +} + +#if defined(__ICCARM__) +size_t __write(int file, unsigned char const *ptr, size_t len) +{ + size_t idx; + unsigned char const *pdata = ptr; + + for (idx = 0; idx < len; idx++) + { + iar_fputc((int)*pdata); + pdata++; + } + return len; +} +#endif /* __ICCARM__ */ + +/** + * @brief Redirect console output to COM + */ +PUTCHAR_PROTOTYPE +{ + HAL_UART_Transmit(&hcom_uart [COM_ActiveLogPort], (uint8_t *) &ch, 1, COM_POLL_TIMEOUT); + return ch; +} +#endif /* USE_COM_LOG */ +#endif /* USE_BSP_COM_FEATURE */ +/** + * @} + */ + +/** @defgroup STM32H7B3I_DISCO_LOW_LEVEL_Private_Functions Private Functions + * @{ + */ +#if (USE_BSP_COM_FEATURE > 0) + +/** + * @brief Initialize UART4. + * @param huart USART handle + * @param COM_Init Pointer to a UART_HandleTypeDef structure that contains the + * configuration information for the specified USART peripheral. + * @retval HAL error code + */ +__weak HAL_StatusTypeDef MX_UART4_Init(UART_HandleTypeDef *huart, MX_UART_InitTypeDef *COM_Init) +{ + /* USART configuration */ + huart->Instance = COM_UART[COM1]; + huart->Init.BaudRate = COM_Init->BaudRate; + huart->Init.Mode = UART_MODE_TX_RX; + huart->Init.Parity = (uint32_t)COM_Init->Parity; + huart->Init.WordLength = (uint32_t)COM_Init->WordLength; + huart->Init.StopBits = (uint32_t)COM_Init->StopBits; + huart->Init.HwFlowCtl = (uint32_t)COM_Init->HwFlowCtl; + huart->Init.OverSampling = UART_OVERSAMPLING_8; + + return HAL_UART_Init(huart); +} + +/** + * @brief Initialize UART7. + * @param huart USART handle + * @param COM_Init Pointer to a UART_HandleTypeDef structure that contains the + * configuration information for the specified USART peripheral. + * @retval HAL error code + */ +__weak HAL_StatusTypeDef MX_UART7_Init(UART_HandleTypeDef *huart, MX_UART_InitTypeDef *COM_Init) +{ + /* USART configuration */ + huart->Instance = COM_UART[COM2]; + huart->Init.BaudRate = COM_Init->BaudRate; + huart->Init.Mode = UART_MODE_TX_RX; + huart->Init.Parity = (uint32_t)COM_Init->Parity; + huart->Init.WordLength = (uint32_t)COM_Init->WordLength; + huart->Init.StopBits = (uint32_t)COM_Init->StopBits; + huart->Init.HwFlowCtl = (uint32_t)COM_Init->HwFlowCtl; + huart->Init.OverSampling = UART_OVERSAMPLING_8; + huart->Init.ClockPrescaler = UART_PRESCALER_DIV1; + return HAL_UART_Init(huart); +} + +/** + * @brief Initialize UART MSP. + * @param huart UART handle. + * @retval None. + */ +static void UART_MspInit(const UART_HandleTypeDef *huart) +{ + GPIO_InitTypeDef GPIO_Init; + GPIO_TypeDef *COM_TX_PORT[COMn] = {COM1_TX_GPIO_PORT, COM2_TX_GPIO_PORT}; + GPIO_TypeDef *COM_RX_PORT[COMn] = {COM1_RX_GPIO_PORT, COM2_RX_GPIO_PORT}; + const uint16_t COM_TX_PIN[COMn] = {COM1_TX_PIN, COM2_TX_PIN}; + const uint16_t COM_RX_PIN[COMn] = {COM1_RX_PIN, COM2_RX_PIN}; + const uint8_t COM_TX_AF[COMn] = {COM1_TX_AF, COM2_TX_AF}; + const uint8_t COM_RX_AF[COMn] = {COM1_RX_AF, COM2_RX_AF}; + COM_TypeDef COM; + + /* Get COM according instance */ + if (huart->Instance == COM1_UART) + { + COM = COM1; + /* Enable COM and GPIO clocks */ + COM1_TX_GPIO_CLK_ENABLE(); + COM1_RX_GPIO_CLK_ENABLE(); + COM1_CLK_ENABLE(); + } + else if (huart->Instance == COM2_UART) + { + COM = COM2; + /* Enable COM and GPIO clocks */ + COM2_TX_GPIO_CLK_ENABLE(); + COM2_RX_GPIO_CLK_ENABLE(); + COM2_CLK_ENABLE(); + } + else /* COM = ??? */ + { + return; + } + + /* Configure COM Tx as alternate function */ + GPIO_Init.Pin = COM_TX_PIN[COM]; + GPIO_Init.Mode = GPIO_MODE_AF_PP; + GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_Init.Pull = GPIO_PULLUP; + GPIO_Init.Alternate = COM_TX_AF[COM]; + HAL_GPIO_Init(COM_TX_PORT[COM], &GPIO_Init); + + /* Configure COM Rx as alternate function */ + GPIO_Init.Pin = COM_RX_PIN[COM]; + GPIO_Init.Alternate = COM_RX_AF[COM]; + HAL_GPIO_Init(COM_RX_PORT[COM], &GPIO_Init); +} + +/** + * @brief Deinitialize UART MSP. + * @param huart UART handle. + * @retval None. + */ +static void UART_MspDeInit(const UART_HandleTypeDef *huart) +{ + if (huart->Instance == COM1_UART) + { + /* Disable GPIOs used by COM1 TX/RX */ + HAL_GPIO_DeInit(COM1_TX_GPIO_PORT, COM1_TX_PIN); + HAL_GPIO_DeInit(COM1_RX_GPIO_PORT, COM1_RX_PIN); + + /* Disable UART COM1 clock */ + COM1_CLK_DISABLE(); + } + else if (huart->Instance == COM2_UART) + { + /* Disable GPIOs used by COM2 TX/RX */ + HAL_GPIO_DeInit(COM2_TX_GPIO_PORT, COM2_TX_PIN); + HAL_GPIO_DeInit(COM2_RX_GPIO_PORT, COM2_RX_PIN); + + /* Disable UART COM2 clock */ + COM2_CLK_DISABLE(); + } + else + { + /* Nothing to do */ + } +} + +#endif /* USE_BSP_COM_FEATURE > 0 */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.h new file mode 100644 index 0000000..1744167 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.h @@ -0,0 +1,336 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery.h + * @author MCD Application Team + * @brief This file contains definitions for STM32H7S78-DK: + * LEDs + * push-buttons + * COM ports + * hardware resources. + ****************************************************************************** + * @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 STM32H7S78_DISCOVERY_H +#define STM32H7S78_DISCOVERY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" + +#if (USE_BSP_COM_FEATURE > 0) +#include +#endif /* USE_BSP_COM_FEATURE */ + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup STM32H7S78_DK_LOW_LEVEL + * @{ + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Exported_Types Exported Types + * @{ + */ + +typedef enum +{ + LD1 = 0U, + LED_GREEN = LD1, + LD2 = 1U, + LED_ORANGE = LD2, + LD3 = 2U, + LED_RED = LD3, + LD4 = 3U, + LED_BLUE = LD4, + LEDn +} Led_TypeDef; + +typedef enum +{ + BUTTON_USER = 0U, + BUTTONn +} Button_TypeDef; + +typedef enum +{ + BUTTON_MODE_GPIO = 0U, + BUTTON_MODE_EXTI = 1U +} ButtonMode_TypeDef; + +#if (USE_BSP_COM_FEATURE > 0) +typedef enum +{ + COM1 = 0U, + COM2 = 1U, + COMn +} COM_TypeDef; + +typedef enum +{ + COM_STOPBITS_1 = UART_STOPBITS_1, + COM_STOPBITS_2 = UART_STOPBITS_2, +} COM_StopBitsTypeDef; + +typedef enum +{ + COM_PARITY_NONE = UART_PARITY_NONE, + COM_PARITY_EVEN = UART_PARITY_EVEN, + COM_PARITY_ODD = UART_PARITY_ODD, +} COM_ParityTypeDef; + +typedef enum +{ + COM_HWCONTROL_NONE = UART_HWCONTROL_NONE, + COM_HWCONTROL_RTS = UART_HWCONTROL_RTS, + COM_HWCONTROL_CTS = UART_HWCONTROL_CTS, + COM_HWCONTROL_RTS_CTS = UART_HWCONTROL_RTS_CTS, +} COM_HwFlowCtlTypeDef; + +typedef enum +{ + COM_WORDLENGTH_7B = UART_WORDLENGTH_7B, + COM_WORDLENGTH_8B = UART_WORDLENGTH_8B, + COM_WORDLENGTH_9B = UART_WORDLENGTH_9B, +} COM_WordLengthTypeDef; + +typedef struct +{ + uint32_t BaudRate; + COM_WordLengthTypeDef WordLength; + COM_StopBitsTypeDef StopBits; + COM_ParityTypeDef Parity; + COM_HwFlowCtlTypeDef HwFlowCtl; +} COM_InitTypeDef; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +typedef struct +{ + void (* pMspInitCb)(UART_HandleTypeDef *); + void (* pMspDeInitCb)(UART_HandleTypeDef *); +} BSP_COM_Cb_t; +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS == 1) */ +#endif /* USE_BSP_COM_FEATURE > 0 */ + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Exported_Constants Exported Constants + * @{ + */ + +/** + * @brief Define for STM32H7S78_DK board + */ + +/** + * @brief STM32H7S78 Discovery BSP Driver version number + */ +#define STM32H7S78_DK_BSP_VERSION_MAIN (0x01UL) /*!< [31:24] main version */ +#define STM32H7S78_DK_BSP_VERSION_SUB1 (0x00UL) /*!< [23:16] sub1 version */ +#define STM32H7S78_DK_BSP_VERSION_SUB2 (0x02UL) /*!< [15:8] sub2 version */ +#define STM32H7S78_DK_BSP_VERSION_RC (0x00UL) /*!< [7:0] release candidate */ +#define STM32H7S78_DK_BSP_VERSION ((STM32H7S78_DK_BSP_VERSION_MAIN << 24)\ + |(STM32H7S78_DK_BSP_VERSION_SUB1 << 16)\ + |(STM32H7S78_DK_BSP_VERSION_SUB2 << 8)\ + |(STM32H7S78_DK_BSP_VERSION_RC)) + +#define STM32H7S78_DK_BSP_BOARD_NAME "STM32H7S78-DK" +#define STM32H7S78_DK_BSP_BOARD_ID "MB1736C" + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_LED EVAL LOW LEVEL LED + * @{ + */ +#define LD1_GPIO_PORT GPIOO +#define LD1_PIN GPIO_PIN_1 + +#define LD2_GPIO_PORT GPIOO +#define LD2_PIN GPIO_PIN_5 + +#define LD3_GPIO_PORT GPIOM +#define LD3_PIN GPIO_PIN_2 + +#define LD4_GPIO_PORT GPIOM +#define LD4_PIN GPIO_PIN_3 + + +#define LD1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOO_CLK_ENABLE() +#define LD1_GPIO_CLK_DISABLE() __HAL_RCC_GPIOO_CLK_DISABLE() + +#define LD2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOO_CLK_ENABLE() +#define LD2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOO_CLK_DISABLE() + +#define LD3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOM_CLK_ENABLE() +#define LD3_GPIO_CLK_DISABLE() __HAL_RCC_GPIOM_CLK_DISABLE() + +#define LD4_GPIO_CLK_ENABLE() __HAL_RCC_GPIOM_CLK_ENABLE() +#define LD4_GPIO_CLK_DISABLE() __HAL_RCC_GPIOM_CLK_DISABLE() +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_BUTTON LOW LEVEL BUTTON + * @{ + */ +/* Button state */ +#define BUTTON_RELEASED 0U +#define BUTTON_PRESSED 1U + +/** + * @brief USER push-button + */ +#define BUTTON_USER_PIN GPIO_PIN_13 +#define BUTTON_USER_GPIO_PORT GPIOC +#define BUTTON_USER_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define BUTTON_USER_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE() +#define BUTTON_USER_EXTI_IRQn EXTI13_IRQn +#define BUTTON_USER_EXTI_LINE EXTI_LINE_13 + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_COM LOW LEVEL COM + * @{ + */ +#if (USE_BSP_COM_FEATURE > 0) +/** + * @brief Definition for COM port1, connected to UART4 + */ +#define COM1_UART UART4 + +#define COM1_CLK_ENABLE() __HAL_RCC_UART4_CLK_ENABLE() +#define COM1_CLK_DISABLE() __HAL_RCC_UART4_CLK_DISABLE() + +#define COM1_TX_PIN GPIO_PIN_1 +#define COM1_TX_GPIO_PORT GPIOD +#define COM1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define COM1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE() +#define COM1_TX_AF GPIO_AF8_UART4 + +#define COM1_RX_PIN GPIO_PIN_0 +#define COM1_RX_GPIO_PORT GPIOD +#define COM1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define COM1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE() +#define COM1_RX_AF GPIO_AF8_UART4 + +/** + * @brief Definition for COM port2, connected to UART7 + */ +#define COM2_UART UART7 +#define COM2_CLK_ENABLE() __HAL_RCC_UART7_CLK_ENABLE() +#define COM2_CLK_DISABLE() __HAL_RCC_UART7_CLK_DISABLE() + +#define COM2_TX_PIN GPIO_PIN_8 +#define COM2_TX_GPIO_PORT GPIOE +#define COM2_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define COM2_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define COM2_TX_AF GPIO_AF7_UART7 + +#define COM2_RX_PIN GPIO_PIN_7 +#define COM2_RX_GPIO_PORT GPIOE +#define COM2_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define COM2_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define COM2_RX_AF GPIO_AF7_UART7 + + +#define COM_POLL_TIMEOUT 1000 + +#define MX_UART_InitTypeDef COM_InitTypeDef +#endif /* USE_BSP_COM_FEATURE > 0 */ +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_LOW_LEVEL_Exported_Variables + * @{ + */ +extern EXTI_HandleTypeDef hpb_exti[]; +#if (USE_BSP_COM_FEATURE > 0) +extern UART_HandleTypeDef hcom_uart[]; +extern USART_TypeDef *COM_UART[]; +#endif /* USE_BSP_COM_FEATURE > 0 */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LOW_LEVEL_Exported_FunctionsPrototypes Exported Functions Prototypes + * @{ + */ +int32_t BSP_GetVersion(void); +const uint8_t *BSP_GetBoardName(void); +const uint8_t *BSP_GetBoardID(void); + +int32_t BSP_LED_Init(Led_TypeDef Led); +int32_t BSP_LED_DeInit(Led_TypeDef Led); +int32_t BSP_LED_On(Led_TypeDef Led); +int32_t BSP_LED_Off(Led_TypeDef Led); +int32_t BSP_LED_Toggle(Led_TypeDef Led); +int32_t BSP_LED_GetState(Led_TypeDef Led); + +int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode); +int32_t BSP_PB_DeInit(Button_TypeDef Button); +int32_t BSP_PB_GetState(Button_TypeDef Button); +void BSP_PB_Callback(Button_TypeDef Button); + +#if (USE_BSP_COM_FEATURE > 0) +int32_t BSP_COM_Init(COM_TypeDef COM, COM_InitTypeDef *COM_Init); +int32_t BSP_COM_DeInit(COM_TypeDef COM); +#if (USE_COM_LOG > 0) +int32_t BSP_COM_SelectLogPort(COM_TypeDef COM); +#endif /* USE_COM_LOG > 0 */ + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +int32_t BSP_COM_RegisterDefaultMspCallbacks(COM_TypeDef COM); +int32_t BSP_COM_RegisterMspCallbacks(COM_TypeDef COM, BSP_COM_Cb_t *Callback); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +HAL_StatusTypeDef MX_UART4_Init(UART_HandleTypeDef *huart, MX_UART_InitTypeDef *COM_Init); +HAL_StatusTypeDef MX_UART7_Init(UART_HandleTypeDef *huart, MX_UART_InitTypeDef *COM_Init); +#endif /* (USE_BSP_COM_FEATURE > 0) */ + +void BSP_PB_IRQHandler(Button_TypeDef Button); + +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.c new file mode 100644 index 0000000..6e35c6c --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.c @@ -0,0 +1,3352 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_audio.c + * @author MCD Application Team + * @brief This file provides the Audio driver for the STM32H7S78_DK + * discovery board. + @verbatim + How To use this driver: + ----------------------- + + This driver supports STM32H7RSxx devices on STM32H7S78_DK (MB1736) board. + + Call the function BSP_AUDIO_OUT_Init() for AUDIO OUT initialization: + Instance : Select the output instance. Can only be 0 (I2S). + AudioInit: Audio Out structure to select the following parameters. + - Device: Select the output device (headphone, speaker, ..). + - SampleRate: Select the output sample rate (8Khz .. 96Khz). + - BitsPerSample: Select the output resolution (16 or 32bits per sample). + - ChannelsNbr: Select the output channels number(1 for mono, 2 for stereo). + - Volume: Select the output volume(0% .. 100%). + + This function configures all the hardware required for the audio application (codec, I2C, I2S, + GPIOs, DMA and interrupt if needed). This function returns BSP_ERROR_NONE if configuration is OK. + If the returned value is different from BSP_ERROR_NONE or the function is stuck then the communication with + the codec has failed (try to un-plug the power or reset device in this case). + + User can update the I2S or the clock configurations by overriding the weak MX functions MX_I2S6_Init() + and MX_I2S6_ClockConfig(). + User can override the default MSP configuration and register his own MSP callbacks (defined at application level) + by calling BSP_AUDIO_OUT_RegisterMspCallbacks() function. + User can restore the default MSP configuration by calling BSP_AUDIO_OUT_RegisterDefaultMspCallbacks(). + To use these two functions, user has to enable USE_HAL_I2S_REGISTER_CALLBACKS within stm32h7rsxx_hal_conf.h file. + + + Call the function BSP_AUDIO_OUT_Play() to play audio stream: + Instance : Select the output instance. Can only be 0 (I2S). + pBuf: pointer to the audio data file address. + NbrOfBytes: Total size of the buffer to be sent in Bytes. + + + Call the function BSP_AUDIO_OUT_Pause() to pause playing. + + Call the function BSP_AUDIO_OUT_Resume() to resume playing. + Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called + for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case). + Note. This function should be called only when the audio file is played or paused (not stopped). + + Call the function BSP_AUDIO_OUT_Stop() to stop playing. + + Call the function BSP_AUDIO_OUT_Mute() to mute the player. + + Call the function BSP_AUDIO_OUT_UnMute() to unmute the player. + + Call the function BSP_AUDIO_OUT_IsMute() to get the mute state(BSP_AUDIO_MUTE_ENABLED or BSP_AUDIO_MUTE_DISABLED). + + Call the function BSP_AUDIO_OUT_SetDevice() to update the AUDIO OUT device. + + Call the function BSP_AUDIO_OUT_GetDevice() to get the AUDIO OUT device. + + Call the function BSP_AUDIO_OUT_SetSampleRate() to update the AUDIO OUT sample rate. + + Call the function BSP_AUDIO_OUT_GetSampleRate() to get the AUDIO OUT sample rate. + + Call the function BSP_AUDIO_OUT_SetBitsPerSample() to update the AUDIO OUT resolution. + + Call the function BSP_AUDIO_OUT_GetBitPerSample() to get the AUDIO OUT resolution. + + Call the function BSP_AUDIO_OUT_SetChannelsNbr() to update the AUDIO OUT number of channels. + + Call the function BSP_AUDIO_OUT_GetChannelsNbr() to get the AUDIO OUT number of channels. + + Call the function BSP_AUDIO_OUT_SetVolume() to update the AUDIO OUT volume. + + Call the function BSP_AUDIO_OUT_GetVolume() to get the AUDIO OUT volume. + + Call the function BSP_AUDIO_OUT_GetState() to get the AUDIO OUT state. + + + BSP_AUDIO_OUT_SetDevice(), BSP_AUDIO_OUT_SetSampleRate(), BSP_AUDIO_OUT_SetBitsPerSample() and + BSP_AUDIO_OUT_SetChannelsNbr() cannot be called while the state is AUDIO_OUT_STATE_PLAYING. + + For each mode, you may need to implement the relative callback functions into your code. + The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in + the stm32h7s78_discovery_audio.h file. (refer to the example for more details on the callbacks implementations). + + + + Call the function BSP_AUDIO_IN_Init() for AUDIO IN initialization: + Instance : Select the input instance. Can be 0 (I2S) or 1 (MDF). + AudioInit: Audio In structure to select the following parameters. + - Device: Select the input device (analog, digital mic1, mic2, mic1 & mic2). + - SampleRate: Select the input sample rate (8Khz .. 96Khz). + - BitsPerSample: Select the input resolution (16 or 32bits per sample). + - ChannelsNbr: Select the input channels number(1 for mono, 2 for stereo). + - Volume: Select the input volume(0% .. 100%). + + This function configures all the hardware required for the audio application (codec, I2C, I2S, MDF + GPIOs, DMA and interrupt if needed). This function returns BSP_ERROR_NONE if configuration is OK. + If the returned value is different from BSP_ERROR_NONE or the function is stuck then the communication with + the codec has failed (try to un-plug the power or reset device in this case). + + User can update the MDF/I2S or the clock configurations by overriding the weak MX functions MX_I2S6_Init(), + MX_I2S6_ClockConfig(), MX_ADF1_Init() and MX_ADF1_ClockConfig() + User can override the default MSP configuration and register his own MSP callbacks (defined at application level) + by calling BSP_AUDIO_IN_RegisterMspCallbacks() function. + User can restore the default MSP configuration by calling BSP_AUDIO_IN_RegisterDefaultMspCallbacks(). + To use these two functions, user have to enable USE_HAL_I2S_REGISTER_CALLBACKS and/or USE_HAL_MDF_REGISTER_CALLBACKS + within stm32h7rsxx_hal_conf.h file. + + + Call the function BSP_AUDIO_IN_Record() to record audio stream. The recorded data are stored to user buffer in raw + (L, R, L, R ...). + Instance : Select the input instance. Can be 0 (I2S) or 1 (MDF). + pBuf: pointer to user buffer. + NbrOfBytes: Total size of the buffer to be sent in Bytes. + + + Call the function BSP_AUDIO_IN_Pause() to pause recording. + + Call the function BSP_AUDIO_IN_Resume() to resume recording. + + Call the function BSP_AUDIO_IN_Stop() to stop recording. + + Call the function BSP_AUDIO_IN_SetDevice() to update the AUDIO IN device. + + Call the function BSP_AUDIO_IN_GetDevice() to get the AUDIO IN device. + + Call the function BSP_AUDIO_IN_SetSampleRate() to update the AUDIO IN sample rate. + + Call the function BSP_AUDIO_IN_GetSampleRate() to get the AUDIO IN sample rate. + + Call the function BSP_AUDIO_IN_SetBitPerSample() to update the AUDIO IN resolution. + + Call the function BSP_AUDIO_IN_GetBitPerSample() to get the AUDIO IN resolution. + + Call the function BSP_AUDIO_IN_SetChannelsNbr() to update the AUDIO IN number of channels. + + Call the function BSP_AUDIO_IN_GetChannelsNbr() to get the AUDIO IN number of channels. + + Call the function BSP_AUDIO_IN_SetVolume() to update the AUDIO IN volume. + + Call the function BSP_AUDIO_IN_GetVolume() to get the AUDIO IN volume. + + Call the function BSP_AUDIO_IN_GetState() to get the AUDIO IN state. + + + For each mode, you may need to implement the relative callback functions into your code. + The Callback functions are named AUDIO_IN_XXX_CallBack() and only their prototypes are declared in + the stm32h7s78_discovery_audio.h file (refer to the example for more details on the callbacks implementations). + + + The driver API and the callback functions are at the end of the stm32h7s78_discovery_audio.h file. + + Known Limitations: + ------------------ + 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second + Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams. + 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, + File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file. + + @endverbatim + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_audio.h" +#include "stm32h7s78_discovery_bus.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_AUDIO AUDIO + * @{ + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Private_Macros STM32H7S78_DK AUDIO Private Macros + * @{ + */ +#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N))) + +#define MDF_DECIMATION_RATIO(__FREQUENCY__) \ + ((__FREQUENCY__) == (AUDIO_FREQUENCY_8K)) ? (64U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_11K)) ? (64U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_16K)) ? (32U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_22K)) ? (32U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_32K)) ? (16U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_44K)) ? (16U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_48K)) ? (16U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_88K)) ? (8U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_96K)) ? (8U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_176K)) ? (4U) : (4U) + +#define MDF_GAIN(__FREQUENCY__) \ + ((__FREQUENCY__) == (AUDIO_FREQUENCY_8K)) ? (-4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_11K)) ? (-6) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_16K)) ? (2) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_22K)) ? (2) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_32K)) ? (10) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_44K)) ? (10) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_48K)) ? (10) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_88K)) ? (18) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_96K)) ? (18) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_176K)) ? (24) : (24) + +#define MDF_CIC_MODE(__FREQUENCY__) \ + ((__FREQUENCY__) == (AUDIO_FREQUENCY_8K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_11K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_16K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_22K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_32K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_44K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_48K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_88K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_96K)) ? (MDF_ONE_FILTER_SINC4) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_176K)) ? (MDF_ONE_FILTER_SINC4) : (MDF_ONE_FILTER_SINC4) + +#define MDF_PROC_CLOCK_DIVIDER(__FREQUENCY__) \ + ((__FREQUENCY__) == (AUDIO_FREQUENCY_8K)) ? (2U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_11K)) ? (1U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_16K)) ? (2U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_22K)) ? (1U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_32K)) ? (2U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_44K)) ? (1U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_48K)) ? (2U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_88K)) ? (1U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_96K)) ? (2U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_176K)) ? (1U) : (2U) + +#define MDF_OUTPUT_CLOCK_DIVIDER(__FREQUENCY__) \ + ((__FREQUENCY__) == (AUDIO_FREQUENCY_8K)) ? (12U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_11K)) ? (4U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_16K)) ? (12U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_22K)) ? (4U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_32K)) ? (12U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_44K)) ? (4U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_48K)) ? (8U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_88K)) ? (16U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_96K)) ? (16U) \ + : ((__FREQUENCY__) == (AUDIO_FREQUENCY_176K)) ? (16U) : (16U) +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Exported_Variables STM32H7S78_DK AUDIO Exported Variables + * @{ + */ +/* Audio in and out context */ +AUDIO_OUT_Ctx_t Audio_Out_Ctx[AUDIO_OUT_INSTANCES_NBR] = {{ + AUDIO_OUT_HEADPHONE, + AUDIO_FREQUENCY_8K, + AUDIO_RESOLUTION_16B, + 50U, + 2U, + AUDIO_MUTE_DISABLED, + AUDIO_OUT_STATE_RESET + } +}; + +AUDIO_IN_Ctx_t Audio_In_Ctx[AUDIO_IN_INSTANCES_NBR] = {{ + AUDIO_IN_ANALOG_MIC, + AUDIO_FREQUENCY_8K, + AUDIO_RESOLUTION_16B, + 2U, + NULL, + 0U, + 50U, + AUDIO_IN_STATE_RESET + }, + { + AUDIO_IN_DIGITAL_MIC, + AUDIO_FREQUENCY_8K, + AUDIO_RESOLUTION_16B, + 2U, + NULL, + 0U, + 50U, + AUDIO_IN_STATE_RESET + } +}; + +/* Audio component object */ +void *Audio_CompObj = NULL; + +/* Audio driver */ +AUDIO_Drv_t *Audio_Drv = NULL; + +/* Audio in and out I2S handles */ +I2S_HandleTypeDef haudio_out_i2s = {0}; +I2S_HandleTypeDef haudio_in_i2s = {0}; + +/* Audio in ADF handles */ +MDF_HandleTypeDef haudio_in_mdf = {0}; + +/* Audio ADF filter configuration */ +static MDF_FilterConfigTypeDef Audio_AdfFilterConfig; + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Private_Variables STM32H7S78_DK AUDIO Private Variables + * @{ + */ +/* Audio in and out DMA handles used by I2S */ +static DMA_HandleTypeDef hDmaI2sTx, hDmaI2sRx; + +/* Audio in DMA handle used by MDF */ +static DMA_HandleTypeDef hDmaMdf; + +#if ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) +static uint32_t AudioOut_IsMspCbValid[AUDIO_OUT_INSTANCES_NBR] = {0}; +static uint32_t AudioIn_IsMspCbValid[AUDIO_IN_INSTANCES_NBR] = {0, 0}; +#endif + +/* Queue variables declaration */ +static DMA_QListTypeDef I2sTxQueue, I2sRxQueue, MdfRxQueue; + +/* Audio in MDF internal buffer */ +static int32_t Audio_DigMicRecBuff[DEFAULT_AUDIO_IN_BUFFER_SIZE]; + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Private_Function_Prototypes STM32H7S78_DK AUDIO Private Function Prototypes + * @{ + */ +static int32_t WM8904_Probe(void); +static void I2S_MspInit(I2S_HandleTypeDef *hi2s); +static void I2S_MspDeInit(I2S_HandleTypeDef *hi2s); +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) +static void I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s); +static void I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +static void I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s); +static void I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +static void I2S_ErrorCallback(I2S_HandleTypeDef *hi2s); +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + +static void MDF_MspInit(MDF_HandleTypeDef *hmdf); +static void MDF_MspDeInit(MDF_HandleTypeDef *hmdf); +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +static void MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf); +static void MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf); +static void MDF_ErrorCallback(MDF_HandleTypeDef *hmdf); +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_AUDIO_OUT_Exported_Functions + * @{ + */ +/** + * @brief Initialize the audio out peripherals. + * @param Instance Audio out instance. + * @param AudioInit Audio out init structure. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_Init(uint32_t Instance, BSP_AUDIO_Init_t *AudioInit) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if ((Instance == 0U) && ((AudioInit->BitsPerSample == AUDIO_RESOLUTION_32B) + || (AudioInit->BitsPerSample == AUDIO_RESOLUTION_8B))) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if ((Instance == 0U) && (AudioInit->ChannelsNbr != 2U)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if ((Instance == 0U) && (Audio_In_Ctx[0].State != AUDIO_IN_STATE_RESET)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Fill audio out context structure */ + Audio_Out_Ctx[Instance].Device = AudioInit->Device; + Audio_Out_Ctx[Instance].SampleRate = AudioInit->SampleRate; + Audio_Out_Ctx[Instance].BitsPerSample = AudioInit->BitsPerSample; + Audio_Out_Ctx[Instance].ChannelsNbr = AudioInit->ChannelsNbr; + Audio_Out_Ctx[Instance].Volume = AudioInit->Volume; + + /* Probe the audio codec */ + if (WM8904_Probe() != BSP_ERROR_NONE) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Set I2S instance and state */ + haudio_out_i2s.Instance = SPI6; + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_INIT; + + /* Configure the I2S PLL according to the requested audio frequency */ + if (MX_I2S6_ClockConfig(&haudio_out_i2s, AudioInit->SampleRate) != HAL_OK) + { + status = BSP_ERROR_CLOCK_FAILURE; + } + else + { +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 0) + I2S_MspInit(&haudio_out_i2s); +#else + /* Register the I2S MSP Callbacks */ + if (AudioOut_IsMspCbValid[Instance] == 0U) + { + if (BSP_AUDIO_OUT_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 0) */ + } + + if (status == BSP_ERROR_NONE) + { + /* Prepare I2S peripheral initialization */ + MX_I2S_Config_t mxI2sInit; + mxI2sInit.AudioFrequency = AudioInit->SampleRate; + mxI2sInit.Mode = I2S_MODE_MASTER_TX; + mxI2sInit.DataFormat = (AudioInit->BitsPerSample == AUDIO_RESOLUTION_16B) ? I2S_DATAFORMAT_16B : + I2S_DATAFORMAT_24B; + + /* I2S peripheral initialization */ + if (MX_I2S6_Init(&haudio_out_i2s, &mxI2sInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) + /* Register I2S TC, HT and Error callbacks */ + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_TX_COMPLETE_CB_ID, I2S_TxCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_TX_HALF_COMPLETE_CB_ID, I2S_TxHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_ERROR_CB_ID, I2S_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + else + { + /* Initialize audio codec */ + WM8904_Init_t codec_init; + codec_init.InputDevice = WM8904_IN_NONE; + codec_init.OutputDevice = WM8904_OUT_HEADPHONE; + codec_init.Resolution = WM8904_RESOLUTION_16B; + codec_init.Frequency = AudioInit->SampleRate; + codec_init.Volume = AudioInit->Volume; + if (Audio_Drv->Init(Audio_CompObj, &codec_init) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update audio out context state */ + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_STOP; + } + } + } + } + } + return status; +} + +/** + * @brief De-initialize the audio out peripherals. + * @param Instance Audio out instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_DeInit(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_RESET) + { + /* I2S peripheral de-initialization */ + if (HAL_I2S_DeInit(&haudio_out_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + /* De-initialize audio codec */ + else + { +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 0) + I2S_MspDeInit(&haudio_out_i2s); +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 0) */ + if (Audio_Drv->DeInit(Audio_CompObj) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + } + + if (status == BSP_ERROR_NONE) + { + /* Update audio out context */ + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_RESET; + Audio_Out_Ctx[Instance].IsMute = 0U; + } + } + else + { + /* Nothing to do */ + } + return status; +} + +/** + * @brief Start playing audio stream from a data buffer for a determined size. + * @param Instance Audio out instance. + * @param pData Pointer on data buffer. + * @param NbrOfBytes Size of buffer in bytes. Maximum size is 65535 bytes. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_Play(uint32_t Instance, uint8_t *pData, uint32_t NbrOfBytes) +{ + int32_t status = BSP_ERROR_NONE; + uint16_t NbrOfDmaDatas; + + if ((Instance >= AUDIO_OUT_INSTANCES_NBR) || (pData == NULL) || (NbrOfBytes > 65535U)) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Compute number of DMA data to transfer according resolution */ + if (Audio_Out_Ctx[Instance].BitsPerSample == AUDIO_RESOLUTION_16B) + { + NbrOfDmaDatas = (uint16_t)(NbrOfBytes / 2U); + } + else /* AUDIO_RESOLUTION_24b */ + { + NbrOfDmaDatas = (uint16_t)(NbrOfBytes / 4U); + } + + /* Initiate a DMA transfer of audio samples towards the serial audio interface */ + /* Disable I2S to be able to configure TxDMAEN */ + __HAL_I2S_DISABLE(&haudio_out_i2s); + if (HAL_I2S_Transmit_DMA(&haudio_out_i2s, (uint16_t *) pData, NbrOfDmaDatas) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + /* Call the audio codec play function */ + else if (Audio_Drv->Play(Audio_CompObj) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update audio out state */ + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_PLAYING; + } + } + return status; +} + +/** + * @brief Pause playback of audio stream. + * @param Instance Audio out instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_Pause(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_PLAYING) + { + status = BSP_ERROR_BUSY; + } + /* Call the audio codec pause function */ + else if (Audio_Drv->Pause(Audio_CompObj) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + /* Pause DMA transfer of audio samples towards the serial audio interface */ + else if (HAL_I2S_DMAPause(&haudio_out_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Update audio out state */ + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_PAUSE; + } + return status; +} + +/** + * @brief Resume playback of audio stream. + * @param Instance Audio out instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_Resume(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_PAUSE) + { + status = BSP_ERROR_BUSY; + } + /* Resume DMA transfer of audio samples towards the serial audio interface */ + else if (HAL_I2S_DMAResume(&haudio_out_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + /* Call the audio codec resume function */ + else if (Audio_Drv->Resume(Audio_CompObj) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update audio out state */ + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_PLAYING; + } + return status; +} + +/** + * @brief Stop playback of audio stream. + * @param Instance Audio out instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_Stop(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_STOP) + { + /* Nothing to do */ + } + else if ((Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_PLAYING) && + (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_PAUSE)) + { + status = BSP_ERROR_BUSY; + } + /* Call the audio codec stop function */ + else if (Audio_Drv->Stop(Audio_CompObj, WM8904_PDWN_SW) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + /* Stop DMA transfer of audio samples towards the serial audio interface */ + else if (HAL_I2S_DMAStop(&haudio_out_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Update audio out state */ + Audio_Out_Ctx[Instance].State = AUDIO_OUT_STATE_STOP; + } + return status; +} + +/** + * @brief Mute playback of audio stream. + * @param Instance Audio out instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_Mute(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Check audio out mute status */ + else if (Audio_Out_Ctx[Instance].IsMute == 1U) + { + /* Nothing to do */ + } + /* Call the audio codec mute function */ + else if (Audio_Drv->SetMute(Audio_CompObj, WM8904_MUTE_ON) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update audio out mute status */ + Audio_Out_Ctx[Instance].IsMute = 1U; + } + return status; +} + +/** + * @brief Unmute playback of audio stream. + * @param Instance Audio out instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_UnMute(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Check audio out mute status */ + else if (Audio_Out_Ctx[Instance].IsMute == 0U) + { + /* Nothing to do */ + } + /* Call the audio codec mute function */ + else if (Audio_Drv->SetMute(Audio_CompObj, WM8904_MUTE_OFF) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update audio out mute status */ + Audio_Out_Ctx[Instance].IsMute = 0U; + } + return status; +} + +/** + * @brief Check audio out mute status. + * @param Instance Audio out instance. + * @param IsMute Pointer to mute status. Value is 1 for mute, 0 for unmute status. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_IsMute(uint32_t Instance, uint32_t *IsMute) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current audio out mute status */ + else + { + *IsMute = Audio_Out_Ctx[Instance].IsMute; + } + return status; +} + +/** + * @brief Set audio out volume. + * @param Instance Audio out instance. + * @param Volume Volume level in percentage from 0% to 100%. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_SetVolume(uint32_t Instance, uint32_t Volume) +{ + int32_t status = BSP_ERROR_NONE; + + if ((Instance >= AUDIO_OUT_INSTANCES_NBR) || (Volume > 100U)) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Call the audio codec volume control function */ + if (Audio_Drv->SetVolume(Audio_CompObj, VOLUME_OUTPUT, (uint8_t) Volume) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Store volume on audio out context */ + Audio_Out_Ctx[Instance].Volume = Volume; + } + } + return status; +} + +/** + * @brief Get audio out volume. + * @param Instance Audio out instance. + * @param Volume Pointer to volume level in percentage from 0% to 100%. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_GetVolume(uint32_t Instance, uint32_t *Volume) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current audio out volume */ + else + { + *Volume = Audio_Out_Ctx[Instance].Volume; + } + return status; +} + +/** + * @brief Set audio out sample rate. + * @param Instance Audio out instance. + * @param SampleRate Sample rate of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_SetSampleRate(uint32_t Instance, uint32_t SampleRate) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + /* Check if sample rate is modified */ + else if (Audio_Out_Ctx[Instance].SampleRate == SampleRate) + { + /* Nothing to do */ + } + else + { + /* Update I2S6 clock config */ + haudio_out_i2s.Init.AudioFreq = SampleRate; + if (MX_I2S6_ClockConfig(&haudio_out_i2s, SampleRate) != HAL_OK) + { + status = BSP_ERROR_CLOCK_FAILURE; + } + /* Re-initialize I2S6 with new sample rate */ + else if (HAL_I2S_Init(&haudio_out_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) + /* Register I2S TC, HT and Error callbacks */ + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_TX_COMPLETE_CB_ID, I2S_TxCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_TX_HALF_COMPLETE_CB_ID, I2S_TxHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_ERROR_CB_ID, I2S_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + /* Store new sample rate on audio out context */ + else + { + Audio_Out_Ctx[Instance].SampleRate = SampleRate; + } + } + return status; +} + +/** + * @brief Get audio out sample rate. + * @param Instance Audio out instance. + * @param SampleRate Pointer to sample rate of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_GetSampleRate(uint32_t Instance, uint32_t *SampleRate) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current audio out sample rate */ + else + { + *SampleRate = Audio_Out_Ctx[Instance].SampleRate; + } + return status; +} + +/** + * @brief Set audio out device. + * @param Instance Audio out instance. + * @param Device Device of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_SetDevice(uint32_t Instance, uint32_t Device) +{ + int32_t status = BSP_ERROR_NONE; + + UNUSED(Device); + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Nothing to do because there is only one device (AUDIO_OUT_HEADPHONE) */ + } + return status; +} + +/** + * @brief Get audio out device. + * @param Instance Audio out instance. + * @param Device Pointer to device of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_GetDevice(uint32_t Instance, uint32_t *Device) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current audio out device */ + else + { + *Device = Audio_Out_Ctx[Instance].Device; + } + return status; +} + +/** + * @brief Set bits per sample for the audio out stream. + * @param Instance Audio out instance. + * @param BitsPerSample Bits per sample of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_SetBitsPerSample(uint32_t Instance, uint32_t BitsPerSample) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if ((Instance == 0U) && ((BitsPerSample == AUDIO_RESOLUTION_32B) || (BitsPerSample == AUDIO_RESOLUTION_8B))) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else if (Audio_Out_Ctx[Instance].BitsPerSample == BitsPerSample) + { + /* nothing to do */ + } + else + { + /* Store new bits per sample on audio out context */ + Audio_Out_Ctx[Instance].BitsPerSample = BitsPerSample; + + /* Update data size, frame length and active frame length parameters of I2S handle */ + if (BitsPerSample == AUDIO_RESOLUTION_24B) + { + haudio_out_i2s.Init.DataFormat = I2S_DATAFORMAT_24B; + } + else + { + haudio_out_i2s.Init.DataFormat = I2S_DATAFORMAT_16B; + } + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 0) + I2S_MspInit(&haudio_out_i2s); +#else + /* Update I2S state only to keep current MSP functions */ + haudio_out_i2s.State = HAL_I2S_STATE_RESET; +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 0) */ + + /* Re-initialize I2S1 with new parameters */ + if (HAL_I2S_Init(&haudio_out_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) + /* Register I2S TC, HT and Error callbacks */ + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_TX_COMPLETE_CB_ID, I2S_TxCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_TX_HALF_COMPLETE_CB_ID, I2S_TxHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_ERROR_CB_ID, I2S_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + else + { + /* Nothing to do */ + } + } + return status; +} + +/** + * @brief Get bits per sample for the audio out stream. + * @param Instance Audio out instance. + * @param BitsPerSample Pointer to bits per sample of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_GetBitsPerSample(uint32_t Instance, uint32_t *BitsPerSample) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current bits per sample of audio out stream */ + else + { + *BitsPerSample = Audio_Out_Ctx[Instance].BitsPerSample; + } + return status; +} + +/** + * @brief Set channels number for the audio out stream. + * @param Instance Audio out instance. + * @param ChannelNbr Channels number of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_SetChannelsNbr(uint32_t Instance, uint32_t ChannelNbr) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if ((Instance == 0U) && (ChannelNbr != 2U)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State != AUDIO_OUT_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Nothing to do because only stereo playback is supported */ + } + return status; +} + +/** + * @brief Get channels number for the audio out stream. + * @param Instance Audio out instance. + * @param ChannelNbr Pointer to channels number of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_GetChannelsNbr(uint32_t Instance, uint32_t *ChannelNbr) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio out state */ + else if (Audio_Out_Ctx[Instance].State == AUDIO_OUT_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current channels number of audio out stream */ + else + { + *ChannelNbr = Audio_Out_Ctx[Instance].ChannelsNbr; + } + return status; +} + +/** + * @brief Get current state for the audio out stream. + * @param Instance Audio out instance. + * @param State Pointer to state of the audio out stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_GetState(uint32_t Instance, uint32_t *State) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Get the current state of audio out stream */ + else + { + *State = Audio_Out_Ctx[Instance].State; + } + return status; +} + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) +/** + * @brief Register default BSP AUDIO OUT msp callbacks. + * @param Instance AUDIO OUT Instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_OUT_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit callbacks */ + if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_MSPINIT_CB_ID, I2S_MspInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_MSPDEINIT_CB_ID, I2S_MspDeInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + AudioOut_IsMspCbValid[Instance] = 1U; + } + } + /* Return BSP status */ + return status; +} + +/** + * @brief Register BSP AUDIO OUT msp callbacks. + * @param Instance AUDIO OUT Instance. + * @param CallBacks Pointer to MspInit/MspDeInit callback functions. + * @retval BSP status + */ +int32_t BSP_AUDIO_OUT_RegisterMspCallbacks(uint32_t Instance, BSP_AUDIO_OUT_Cb_t *CallBacks) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_OUT_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit callbacks */ + if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_MSPINIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_out_i2s, HAL_I2S_MSPDEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + AudioOut_IsMspCbValid[Instance] = 1U; + } + } + /* Return BSP status */ + return status; +} +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Manage the BSP audio out transfer complete event. + * @param Instance Audio out instance. + * @retval None. + */ +__weak void BSP_AUDIO_OUT_TransferComplete_CallBack(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief Manage the BSP audio out half transfer complete event. + * @param Instance Audio out instance. + * @retval None. + */ +__weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief Manages the BSP audio out error event. + * @param Instance Audio out instance. + * @retval None. + */ +__weak void BSP_AUDIO_OUT_Error_CallBack(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief BSP AUDIO OUT interrupt handler. + * @param Instance Audio out instance. + * @param Device Device of the audio out stream. + * @retval None. + */ +void BSP_AUDIO_OUT_IRQHandler(uint32_t Instance, uint32_t Device) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); + UNUSED(Device); + + HAL_DMA_IRQHandler(haudio_out_i2s.hdmatx); +} + +/** + * @brief I2S6 clock Config. + * @param hi2s I2S handle. + * @param SampleRate Audio sample rate used to play the audio stream. + * @note The PLL configuration done within this function assumes that + * the PLL input is HSI clock and that HSI is already enabled. + * @retval HAL status. + */ +__weak HAL_StatusTypeDef MX_I2S6_ClockConfig(I2S_HandleTypeDef *hi2s, uint32_t SampleRate) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + HAL_StatusTypeDef status; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL2.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL2.PLLM = 32; /* 2MHz */ + if ((SampleRate == AUDIO_FREQUENCY_11K) || (SampleRate == AUDIO_FREQUENCY_22K) || (SampleRate == AUDIO_FREQUENCY_44K)) + { + RCC_OscInitStruct.PLL2.PLLN = 96; /* 96*2 = 192MHz */ + RCC_OscInitStruct.PLL2.PLLQ = 17; /* 192/17 = 11,294Mhz */ + } + else if ((SampleRate == AUDIO_FREQUENCY_88K) || (SampleRate == AUDIO_FREQUENCY_176K)) + { + RCC_OscInitStruct.PLL2.PLLN = 384; /* 384*2 = 768MHz */ + RCC_OscInitStruct.PLL2.PLLQ = 17; /* 768/17 = 45.176Mhz */ + } + else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_32K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K or AUDIO_FREQUENCY_192K */ + { + RCC_OscInitStruct.PLL2.PLLN = 172; /* 172*2 = 344MHz */ + RCC_OscInitStruct.PLL2.PLLQ = 7; /* 344/7 = 49,142Mhz */ + } + RCC_OscInitStruct.PLL2.PLLP = 128; /* NOT USED */ + RCC_OscInitStruct.PLL2.PLLR = 128; /* NOT USED */ + RCC_OscInitStruct.PLL2.PLLS = 8; /* NOT USED */ + RCC_OscInitStruct.PLL2.PLLT = 8; /* NOT USED */ + RCC_OscInitStruct.PLL2.PLLFractional = 0; + RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6; + PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_PLL2Q; + + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + } + + return status; +} + +/** + * @brief Initialize I2S6. + * @param hi2s I2S handle. + * @param MXInit I2S configuration structure. + * @retval HAL status. + */ +__weak HAL_StatusTypeDef MX_I2S6_Init(I2S_HandleTypeDef *hi2s, MX_I2S_Config_t *MXInit) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Disable I2S peripheral to allow access to I2S internal registers */ + __HAL_I2S_DISABLE(hi2s); + + /* I2S peripheral configuration */ + hi2s->Init.Mode = MXInit->Mode; + hi2s->Init.Standard = I2S_STANDARD_PHILIPS; + hi2s->Init.DataFormat = MXInit->DataFormat; + hi2s->Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; + hi2s->Init.AudioFreq = MXInit->AudioFrequency; + hi2s->Init.CPOL = I2S_CPOL_LOW; + hi2s->Init.FirstBit = I2S_FIRSTBIT_MSB; + hi2s->Init.WSInversion = I2S_WS_INVERSION_DISABLE; + hi2s->Init.Data24BitAlignment = I2S_DATA_24BIT_ALIGNMENT_RIGHT; + hi2s->Init.MasterKeepIOState = I2S_MASTER_KEEP_IO_STATE_ENABLE; + + if (HAL_I2S_Init(hi2s) != HAL_OK) + { + status = HAL_ERROR; + } + + /* Enable I2S to generate master clock */ + __HAL_I2S_ENABLE(hi2s); + + return status; +} +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_AUDIO_IN_Exported_Functions + * @{ + */ +/** + * @brief Initialize the audio in peripherals. + * @param Instance Audio in instance. + * @param AudioInit Audio in init structure. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_Init(uint32_t Instance, BSP_AUDIO_Init_t *AudioInit) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + else if (AudioInit->BitsPerSample != AUDIO_RESOLUTION_16B) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if ((Instance == 0U) && (AudioInit->ChannelsNbr != 2U)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if ((Instance == 1U) && (AudioInit->ChannelsNbr != 1U)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if ((Instance == 0U) && (Audio_Out_Ctx[0].State != AUDIO_OUT_STATE_RESET)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else + { + if (Instance == 0U) + { + /* Fill audio in context structure */ + Audio_In_Ctx[Instance].Device = AudioInit->Device; + Audio_In_Ctx[Instance].SampleRate = AudioInit->SampleRate; + Audio_In_Ctx[Instance].BitsPerSample = AudioInit->BitsPerSample; + Audio_In_Ctx[Instance].ChannelsNbr = AudioInit->ChannelsNbr; + Audio_In_Ctx[Instance].Volume = AudioInit->Volume; + + /* Probe the audio codec */ + if (WM8904_Probe() != BSP_ERROR_NONE) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Set I2S instance and state */ + haudio_in_i2s.Instance = SPI6; + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_INIT; + + /* Configure the I2S PLL according to the requested audio frequency */ + if (MX_I2S6_ClockConfig(&haudio_in_i2s, AudioInit->SampleRate) != HAL_OK) + { + status = BSP_ERROR_CLOCK_FAILURE; + } + else + { +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 0) + I2S_MspInit(&haudio_in_i2s); +#else + /* Register the I2S MSP Callbacks */ + if (AudioIn_IsMspCbValid[Instance] == 0U) + { + if (BSP_AUDIO_IN_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } +#endif /* #if (USE_HAL_I2S_REGISTER_CALLBACKS == 0) */ + } + + if (status == BSP_ERROR_NONE) + { + /* Prepare I2S peripheral initialization */ + MX_I2S_Config_t mxI2sInit; + mxI2sInit.AudioFrequency = AudioInit->SampleRate; + mxI2sInit.Mode = I2S_MODE_MASTER_RX; + mxI2sInit.DataFormat = I2S_DATAFORMAT_16B; + + /* I2S peripheral initialization */ + if (MX_I2S6_Init(&haudio_in_i2s, &mxI2sInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) + /* Register I2S TC, HT and Error callbacks */ + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_RX_COMPLETE_CB_ID, I2S_RxCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_RX_HALF_COMPLETE_CB_ID, I2S_RxHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_ERROR_CB_ID, I2S_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + else + { + /* Initialize audio codec */ + WM8904_Init_t codec_init; + codec_init.InputDevice = WM8904_IN_MIC1; + codec_init.OutputDevice = WM8904_OUT_NONE; + codec_init.Resolution = WM8904_RESOLUTION_16B; /* Not used */ + codec_init.Frequency = AudioInit->SampleRate; + codec_init.Volume = Audio_In_Ctx[0].Volume; + if (Audio_Drv->Init(Audio_CompObj, &codec_init) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update audio in context state */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_STOP; + } + } + } + } + } + else /* Instance = 1 */ + { + /* Fill audio in context structure */ + Audio_In_Ctx[Instance].Device = AudioInit->Device; + Audio_In_Ctx[Instance].SampleRate = AudioInit->SampleRate; + Audio_In_Ctx[Instance].BitsPerSample = AudioInit->BitsPerSample; + Audio_In_Ctx[Instance].ChannelsNbr = AudioInit->ChannelsNbr; + Audio_In_Ctx[Instance].Volume = AudioInit->Volume; + + /* Set MDF instances */ + haudio_in_mdf.Instance = ADF1_Filter0; + + /* Configure MDF clock according to the requested audio frequency */ + if (MX_ADF1_ClockConfig(&haudio_in_mdf, AudioInit->SampleRate) != HAL_OK) + { + status = BSP_ERROR_CLOCK_FAILURE; + } + else + { +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 0) + MDF_MspInit(&haudio_in_mdf); +#else + /* Register the MDF MSP Callbacks */ + if (AudioIn_IsMspCbValid[Instance] == 0U) + { + if (BSP_AUDIO_IN_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + if (status == BSP_ERROR_NONE) + { +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 0) */ + /* Prepare MDF peripheral initialization */ + /* MX_MDF_Config_t mxMdfInit; + mxMdfInit.Gain = MDF_GAIN(AudioInit->SampleRate); + mxMdfInit.DecimationRatio = MDF_DECIMATION_RATIO(AudioInit->SampleRate); + mxMdfInit.CicMode = MDF_CIC_MODE(AudioInit->SampleRate); + mxMdfInit.ProcClockDivider = MDF_PROC_CLOCK_DIVIDER(AudioInit->SampleRate); + mxMdfInit.OutputClockDivider = MDF_OUTPUT_CLOCK_DIVIDER(AudioInit->SampleRate); + if (MX_ADF1_Init(&haudio_in_mdf, &mxMdfInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + }*/ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + if (status == BSP_ERROR_NONE) + { + /* Register MDF filter TC, HT and Error callbacks */ + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_ACQ_COMPLETE_CB_ID, MDF_AcqCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_ACQ_HALFCOMPLETE_CB_ID, MDF_AcqHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_ERROR_CB_ID, MDF_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + } +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ + if (status == BSP_ERROR_NONE) + { + /* Update audio in context state */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_STOP; + } +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + } +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ + } + } + } + return status; +} + +/** + * @brief De-initialize the audio in peripherals. + * @param Instance Audio in instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_DeInit(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_RESET) + { + if (Instance == 0U) + { + /* I2S peripheral de-initialization */ + if (HAL_I2S_DeInit(&haudio_in_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + /* De-initialize audio codec */ + else + { +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 0) + I2S_MspDeInit(&haudio_in_i2s); +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 0) */ + if (Audio_Drv->DeInit(Audio_CompObj) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + } + + if (status == BSP_ERROR_NONE) + { + /* Update audio in context */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_RESET; + } + } + else /* Instance = 1 */ + { + /* MDF peripheral de-initialization */ + if (HAL_MDF_DeInit(&haudio_in_mdf) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 0) + MDF_MspDeInit(&haudio_in_mdf); +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 0) */ + } + + if (status == BSP_ERROR_NONE) + { + /* Update audio in context */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_RESET; + } + } + } + else + { + /* Nothing to do */ + } + return status; +} + +/** + * @brief Start recording audio stream to a data buffer for a determined size. + * @param Instance Audio in instance. + * @param pData Pointer on data buffer. + * @param NbrOfBytes Size of buffer in bytes. Maximum size is 65535 bytes. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_Record(uint32_t Instance, uint8_t *pData, uint32_t NbrOfBytes) +{ + int32_t status = BSP_ERROR_NONE; + + if ((Instance >= AUDIO_IN_INSTANCES_NBR) || (pData == NULL) || (NbrOfBytes > 65535U)) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check the internal buffer size */ + else if ((Instance == 1U) && ((NbrOfBytes / 2U) > DEFAULT_AUDIO_IN_BUFFER_SIZE)) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + if (Instance == 0U) + { + Audio_In_Ctx[Instance].pBuff = pData; + Audio_In_Ctx[Instance].Size = NbrOfBytes; + + /* Call the audio Codec Play function */ + if (Audio_Drv->Play(Audio_CompObj) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Initiate a DMA transfer of audio samples from the serial audio interface */ + /* Disable I2S to be able to configure RxDMAEN */ + __HAL_I2S_DISABLE(&haudio_in_i2s); + if (HAL_I2S_Receive_DMA(&haudio_in_i2s, (uint16_t *) pData, (uint16_t)(NbrOfBytes / 2U)) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + } + else /* Instance = 1 */ + { + MDF_DmaConfigTypeDef dmaConfig; + + Audio_In_Ctx[Instance].pBuff = pData; + Audio_In_Ctx[Instance].Size = NbrOfBytes; + + /* Call the MDF acquisition start function */ + dmaConfig.Address = (uint32_t) Audio_DigMicRecBuff; + dmaConfig.DataLength = 2U * NbrOfBytes; + dmaConfig.MsbOnly = DISABLE; + if (HAL_MDF_AcqStart_DMA(&haudio_in_mdf, &Audio_AdfFilterConfig, &dmaConfig) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + if (status == BSP_ERROR_NONE) + { + /* Update audio in state */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_RECORDING; + } + } + return status; +} + +/** + * @brief Pause record of audio stream. + * @param Instance Audio in instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_Pause(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_RECORDING) + { + status = BSP_ERROR_BUSY; + } + else + { + if (Instance == 0U) + { + /* Pause DMA transfer of audio samples from the serial audio interface */ + if (HAL_I2S_DMAPause(&haudio_in_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + else /* Instance = 1 */ + { + /* Call the MDF acquisition stop function */ + if (HAL_MDF_AcqStop_DMA(&haudio_in_mdf) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + if (status == BSP_ERROR_NONE) + { + /* Update audio in state */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_PAUSE; + } + } + return status; +} + +/** + * @brief Resume record of audio stream. + * @param Instance Audio in instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_Resume(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_PAUSE) + { + status = BSP_ERROR_BUSY; + } + else + { + if (Instance == 0U) + { + /* Resume DMA transfer of audio samples from the serial audio interface */ + if (HAL_I2S_DMAResume(&haudio_in_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + else /* Instance = 1 */ + { + MDF_DmaConfigTypeDef dmaConfig; + + /* Call the MDF acquisition start function */ + dmaConfig.Address = (uint32_t) Audio_DigMicRecBuff; + dmaConfig.DataLength = 2U * Audio_In_Ctx[Instance].Size; + dmaConfig.MsbOnly = DISABLE; + if (HAL_MDF_AcqStart_DMA(&haudio_in_mdf, &Audio_AdfFilterConfig, &dmaConfig) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + if (status == BSP_ERROR_NONE) + { + /* Update audio in state */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_RECORDING; + } + } + return status; +} + +/** + * @brief Stop record of audio stream. + * @param Instance Audio in instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_Stop(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State == AUDIO_IN_STATE_STOP) + { + /* Nothing to do */ + } + else if ((Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_RECORDING) && + (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_PAUSE)) + { + status = BSP_ERROR_BUSY; + } + else + { + if (Instance == 0U) + { + /* Call the audio codec stop function */ + if (Audio_Drv->Stop(Audio_CompObj, WM8904_PDWN_SW) < 0) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + /* Stop DMA transfer of audio samples from the serial audio interface */ + else + { + if (HAL_I2S_DMAStop(&haudio_in_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + } + else /* Instance = 1 */ + { + /* Call the MDF acquisition stop function */ + if (HAL_MDF_AcqStop_DMA(&haudio_in_mdf) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + if (status == BSP_ERROR_NONE) + { + /* Update audio in state */ + Audio_In_Ctx[Instance].State = AUDIO_IN_STATE_STOP; + } + } + return status; +} + +/** + * @brief Set audio in volume. + * @param Instance Audio in instance. + * @param Volume Volume level in percentage from 0% to 100%. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_SetVolume(uint32_t Instance, uint32_t Volume) +{ + int32_t status; + + if ((Instance >= AUDIO_IN_INSTANCES_NBR) || (Volume > 100U)) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Feature not supported */ + else + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + return status; +} + +/** + * @brief Get audio in volume. + * @param Instance Audio in instance. + * @param Volume Pointer to volume level in percentage from 0% to 100%. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_GetVolume(uint32_t Instance, uint32_t *Volume) +{ + int32_t status; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Feature not supported */ + else + { + *Volume = 0U; + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + return status; +} + +/** + * @brief Set audio in sample rate. + * @param Instance Audio in instance. + * @param SampleRate Sample rate of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_SetSampleRate(uint32_t Instance, uint32_t SampleRate) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + /* Check if sample rate is modified */ + else if (Audio_In_Ctx[Instance].SampleRate == SampleRate) + { + /* Nothing to do */ + } + else + { + if (Instance == 0U) + { + /* Update I2S6 clock config */ + haudio_in_i2s.Init.AudioFreq = SampleRate; + if (MX_I2S6_ClockConfig(&haudio_in_i2s, SampleRate) != HAL_OK) + { + status = BSP_ERROR_CLOCK_FAILURE; + } + /* Re-initialize I2S6 with new sample rate */ + else if (HAL_I2S_Init(&haudio_in_i2s) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) + /* Register I2S TC, HT and Error callbacks */ + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_RX_COMPLETE_CB_ID, I2S_RxCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_RX_HALF_COMPLETE_CB_ID, I2S_RxHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_ERROR_CB_ID, I2S_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + /* Store new sample rate on audio out context */ + else + { + Audio_In_Ctx[Instance].SampleRate = SampleRate; + } + } + else /* Instance = 1 */ + { + /* Update ADF1 clock config */ + if (MX_ADF1_ClockConfig(&haudio_in_mdf, SampleRate) != HAL_OK) + { + status = BSP_ERROR_CLOCK_FAILURE; + } + /* Re-initialize ADF1 with new sample rate */ + else if (HAL_MDF_DeInit(&haudio_in_mdf) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* MX_MDF_Config_t mxMdfInit; + mxMdfInit.Gain = MDF_GAIN(SampleRate); + mxMdfInit.DecimationRatio = MDF_DECIMATION_RATIO(SampleRate); + mxMdfInit.CicMode = MDF_CIC_MODE(SampleRate); + mxMdfInit.ProcClockDivider = MDF_PROC_CLOCK_DIVIDER(SampleRate); + mxMdfInit.OutputClockDivider = MDF_OUTPUT_CLOCK_DIVIDER(SampleRate); + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 0) + MDF_MspInit(&haudio_in_mdf); +#endif + if (MX_ADF1_Init(&haudio_in_mdf, &mxMdfInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + }*/ + } +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + if (status == BSP_ERROR_NONE) + { + /* Register MDF filter TC, HT and Error callbacks */ + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_ACQ_COMPLETE_CB_ID, MDF_AcqCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_ACQ_HALFCOMPLETE_CB_ID, MDF_AcqHalfCpltCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_ERROR_CB_ID, MDF_ErrorCallback) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + } +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ + /* Store new sample rate on audio in context */ + if (status == BSP_ERROR_NONE) + { + Audio_In_Ctx[Instance].SampleRate = SampleRate; + } + } + } + return status; +} + +/** + * @brief Get audio in sample rate. + * @param Instance Audio in instance. + * @param SampleRate Pointer to sample rate of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_GetSampleRate(uint32_t Instance, uint32_t *SampleRate) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State == AUDIO_IN_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current audio in sample rate */ + else + { + *SampleRate = Audio_In_Ctx[Instance].SampleRate; + } + return status; +} + +/** + * @brief Set audio in device. + * @param Instance Audio in instance. + * @param Device Device of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_SetDevice(uint32_t Instance, uint32_t Device) +{ + int32_t status = BSP_ERROR_NONE; + + UNUSED(Device); + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Nothing to do because there is only one device for each instance */ + } + return status; +} + +/** + * @brief Get audio in device. + * @param Instance Audio in instance. + * @param Device Pointer to device of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_GetDevice(uint32_t Instance, uint32_t *Device) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State == AUDIO_IN_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current audio in device */ + else + { + *Device = Audio_In_Ctx[Instance].Device; + } + return status; +} + +/** + * @brief Set bits per sample for the audio in stream. + * @param Instance Audio in instance. + * @param BitsPerSample Bits per sample of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_SetBitsPerSample(uint32_t Instance, uint32_t BitsPerSample) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if (BitsPerSample != AUDIO_RESOLUTION_16B) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + /* nothing to do because only 16 bits per sample is supported */ + } + return status; +} + +/** + * @brief Get bits per sample for the audio in stream. + * @param Instance Audio in instance. + * @param BitsPerSample Pointer to bits per sample of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_GetBitsPerSample(uint32_t Instance, uint32_t *BitsPerSample) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State == AUDIO_IN_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current bits per sample of audio in stream */ + else + { + *BitsPerSample = Audio_In_Ctx[Instance].BitsPerSample; + } + return status; +} + +/** + * @brief Set channels number for the audio in stream. + * @param Instance Audio in instance. + * @param ChannelNbr Channels number of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_SetChannelsNbr(uint32_t Instance, uint32_t ChannelNbr) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else if ((Instance == 0U) && (ChannelNbr != 2U)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + else if ((Instance == 1U) && (ChannelNbr != 1U)) + { + status = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State != AUDIO_IN_STATE_STOP) + { + status = BSP_ERROR_BUSY; + } + else + { + /* Nothing to do because channels are already configurated and can't be modified */ + } + return status; +} + +/** + * @brief Get channels number for the audio in stream. + * @param Instance Audio in instance. + * @param ChannelNbr Pointer to channels number of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_GetChannelsNbr(uint32_t Instance, uint32_t *ChannelNbr) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Check audio in state */ + else if (Audio_In_Ctx[Instance].State == AUDIO_IN_STATE_RESET) + { + status = BSP_ERROR_BUSY; + } + /* Get the current channels number of audio in stream */ + else + { + *ChannelNbr = Audio_In_Ctx[Instance].ChannelsNbr; + } + return status; +} + +/** + * @brief Get current state for the audio in stream. + * @param Instance Audio in instance. + * @param State Pointer to state of the audio in stream. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_GetState(uint32_t Instance, uint32_t *State) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + /* Get the current state of audio in stream */ + else + { + *State = Audio_In_Ctx[Instance].State; + } + return status; +} + +#if ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) +/** + * @brief Register default BSP AUDIO IN msp callbacks. + * @param Instance AUDIO IN Instance. + * @retval BSP status. + */ +int32_t BSP_AUDIO_IN_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Instance == 0U) + { + /* Register MspInit/MspDeInit callbacks */ + if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_MSPINIT_CB_ID, I2S_MspInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_MSPDEINIT_CB_ID, I2S_MspDeInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + AudioIn_IsMspCbValid[Instance] = 1U; + } + } + else /* Instance = 1 */ + { + /* Register MspInit/MspDeInit callbacks */ + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_MSPINIT_CB_ID, MDF_MspInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_MSPDEINIT_CB_ID, MDF_MspDeInit) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + + if (status == BSP_ERROR_NONE) + { + AudioIn_IsMspCbValid[Instance] = 1U; + } + } + } + /* Return BSP status */ + return status; +} + +/** + * @brief Register BSP AUDIO IN msp callbacks. + * @param Instance AUDIO IN Instance. + * @param CallBacks Pointer to MspInit/MspDeInit callback functions. + * @retval BSP status + */ +int32_t BSP_AUDIO_IN_RegisterMspCallbacks(uint32_t Instance, BSP_AUDIO_IN_Cb_t *CallBacks) +{ + int32_t status = BSP_ERROR_NONE; + + if (Instance >= AUDIO_IN_INSTANCES_NBR) + { + status = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Instance == 0U) + { + /* Register MspInit/MspDeInit callbacks */ + if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_MSPINIT_CB_ID, CallBacks->pMspI2sInitCb) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2S_RegisterCallback(&haudio_in_i2s, HAL_I2S_MSPDEINIT_CB_ID, CallBacks->pMspI2sDeInitCb) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + AudioIn_IsMspCbValid[Instance] = 1U; + } + } + else /* Instance = 1 */ + { + /* Register MspInit/MspDeInit callbacks */ + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_MSPINIT_CB_ID, CallBacks->pMspMdfInitCb) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_MDF_RegisterCallback(&haudio_in_mdf, HAL_MDF_MSPDEINIT_CB_ID, CallBacks->pMspMdfDeInitCb) != HAL_OK) + { + status = BSP_ERROR_PERIPH_FAILURE; + } + } + + if (status == BSP_ERROR_NONE) + { + AudioIn_IsMspCbValid[Instance] = 1U; + } + } + } + /* Return BSP status */ + return status; +} +#endif /* ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) */ + +/** + * @brief Manage the BSP audio in transfer complete event. + * @param Instance Audio in instance. + * @retval None. + */ +__weak void BSP_AUDIO_IN_TransferComplete_CallBack(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief Manage the BSP audio in half transfer complete event. + * @param Instance Audio in instance. + * @retval None. + */ +__weak void BSP_AUDIO_IN_HalfTransfer_CallBack(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief Manages the BSP audio in error event. + * @param Instance Audio in instance. + * @retval None. + */ +__weak void BSP_AUDIO_IN_Error_CallBack(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief BSP AUDIO IN interrupt handler. + * @param Instance Audio in instance. + * @param Device Device of the audio in stream. + * @retval None. + */ +void BSP_AUDIO_IN_IRQHandler(uint32_t Instance, uint32_t Device) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Device); + + if (Instance == 0U) + { + HAL_DMA_IRQHandler(haudio_in_i2s.hdmarx); + } + else + { + HAL_DMA_IRQHandler(haudio_in_mdf.hdma); + } +} + +/** + * @brief ADF1 clock Config. + * @param hmdf MDF handle. + * @param SampleRate Audio sample rate used to record the audio stream. + * @retval HAL status. + */ +__weak HAL_StatusTypeDef MX_ADF1_ClockConfig(MDF_HandleTypeDef *hmdf, uint32_t SampleRate) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + HAL_StatusTypeDef status; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL3.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL3.PLLM = 32; /* 2MHz */ + if ((SampleRate == AUDIO_FREQUENCY_11K) || (SampleRate == AUDIO_FREQUENCY_22K) || (SampleRate == AUDIO_FREQUENCY_44K)) + { + RCC_OscInitStruct.PLL3.PLLN = 96; /* 96*2 = 192MHz */ + RCC_OscInitStruct.PLL3.PLLP = 17; /* 192/17 = 11,294Mhz */ + } + else if ((SampleRate == AUDIO_FREQUENCY_88K) || (SampleRate == AUDIO_FREQUENCY_176K)) + { + RCC_OscInitStruct.PLL3.PLLN = 384; /* 384*2 = 768MHz */ + RCC_OscInitStruct.PLL3.PLLP = 17; /* 768/17 = 45,176Mhz */ + } + else if ((SampleRate == AUDIO_FREQUENCY_96K) || (SampleRate == AUDIO_FREQUENCY_192K)) + { + RCC_OscInitStruct.PLL3.PLLN = 344; /* 344*2 = 688MHz */ + RCC_OscInitStruct.PLL3.PLLP = 7; /* 688/7 = 98,285Mhz */ + } + else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_32K, AUDIO_FREQUENCY_48K */ + { + RCC_OscInitStruct.PLL3.PLLN = 172; /* 172*2 = 344MHz */ + RCC_OscInitStruct.PLL3.PLLP = 7; /* 344/7 = 49,142Mhz */ + } + RCC_OscInitStruct.PLL3.PLLQ = 128; /* NOT USED */ + RCC_OscInitStruct.PLL3.PLLR = 128; /* NOT USED */ + RCC_OscInitStruct.PLL3.PLLS = 8; /* NOT USED */ + RCC_OscInitStruct.PLL3.PLLT = 8; /* NOT USED */ + RCC_OscInitStruct.PLL3.PLLFractional = 0; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADF1; + PeriphClkInitStruct.Adf1ClockSelection = RCC_ADF1CLKSOURCE_PLL3P; + + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + } + + return status; +} + + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Private_Functions STM32H7S78_DK AUDIO Private Functions + * @{ + */ +/** + * @brief Probe the WM8904 audio codec. + * @retval BSP status. + */ +static int32_t WM8904_Probe(void) +{ + int32_t status = BSP_ERROR_NONE; + WM8904_IO_t IOCtx; + uint32_t wm8904_id; + static WM8904_Object_t WM8904Obj; + + /* Configure the audio driver */ + IOCtx.Address = AUDIO_I2C_ADDRESS; + IOCtx.Init = BSP_I2C1_Init; + IOCtx.DeInit = BSP_I2C1_DeInit; + IOCtx.ReadReg = BSP_I2C1_ReadReg; + IOCtx.WriteReg = BSP_I2C1_WriteReg; + IOCtx.GetTick = BSP_GetTick; + + if (WM8904_RegisterBusIO(&WM8904Obj, &IOCtx) != WM8904_OK) + { + status = BSP_ERROR_BUS_FAILURE; + } + else if (WM8904_ReadID(&WM8904Obj, &wm8904_id) != WM8904_OK) + { + status = BSP_ERROR_COMPONENT_FAILURE; + } + else if ((wm8904_id & WM8904_ID_MASK) != WM8904_ID) + { + status = BSP_ERROR_UNKNOWN_COMPONENT; + } + else + { + Audio_Drv = (AUDIO_Drv_t *) &WM8904_Driver; + Audio_CompObj = &WM8904Obj; + } + + return status; +} + +/** + * @brief Initialize I2S MSP. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_MspInit(I2S_HandleTypeDef *hi2s) +{ + GPIO_InitTypeDef GPIO_InitStruct; + static DMA_NodeTypeDef TxNode = {0}; + static DMA_NodeTypeDef RxNode = {0}; + static DMA_NodeConfTypeDef dmaNodeConfig = {0}; + + /* Enable I2S clock */ + AUDIO_I2S6_CLK_ENABLE(); + + /* I2S pins configuration: MCK, CK, WS, SDI and SDO pins */ + AUDIO_I2S6_MCK_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = AUDIO_I2S6_MCK_SDI_GPIO_AF; + GPIO_InitStruct.Pin = AUDIO_I2S6_MCK_GPIO_PIN; + HAL_GPIO_Init(AUDIO_I2S6_MCK_GPIO_PORT, &GPIO_InitStruct); + + AUDIO_I2S6_CK_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Alternate = AUDIO_I2S6_CK_WS_SDO_GPIO_AF; + GPIO_InitStruct.Pin = AUDIO_I2S6_CK_GPIO_PIN; + HAL_GPIO_Init(AUDIO_I2S6_CK_GPIO_PORT, &GPIO_InitStruct); + + AUDIO_I2S6_WS_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Pin = AUDIO_I2S6_WS_GPIO_PIN; + HAL_GPIO_Init(AUDIO_I2S6_WS_GPIO_PORT, &GPIO_InitStruct); + + AUDIO_I2S6_SDI_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Alternate = AUDIO_I2S6_MCK_SDI_GPIO_AF; + GPIO_InitStruct.Pin = AUDIO_I2S6_SDI_GPIO_PIN; + HAL_GPIO_Init(AUDIO_I2S6_SDI_GPIO_PORT, &GPIO_InitStruct); + + AUDIO_I2S6_SDO_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Alternate = AUDIO_I2S6_CK_WS_SDO_GPIO_AF; + GPIO_InitStruct.Pin = AUDIO_I2S6_SDO_GPIO_PIN; + HAL_GPIO_Init(AUDIO_I2S6_SDO_GPIO_PORT, &GPIO_InitStruct); + + /* DMA for Tx */ + if (Audio_Out_Ctx[0].State != AUDIO_OUT_STATE_RESET) + { + if (I2sTxQueue.Head == NULL) + { + AUDIO_OUT_I2S6_DMA_CLK_ENABLE(); + + /* Set node type */ + dmaNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE; + /* Set common node parameters */ + dmaNodeConfig.Init.Request = AUDIO_OUT_I2S6_DMA_REQUEST; + dmaNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + dmaNodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH; + dmaNodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED; + dmaNodeConfig.Init.DestInc = DMA_DINC_FIXED; + if (Audio_Out_Ctx[0].BitsPerSample == AUDIO_RESOLUTION_16B) + { + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD; + } + else /* AUDIO_RESOLUTION_24b */ + { + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + } + dmaNodeConfig.Init.SrcBurstLength = 1; + dmaNodeConfig.Init.DestBurstLength = 1; + dmaNodeConfig.Init.Priority = DMA_HIGH_PRIORITY; + dmaNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + dmaNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1; + /* Set node data handling parameters */ + dmaNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + dmaNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + /* Set node trigger parameters */ + dmaNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED; + + /* Build NodeTx */ + if (HAL_DMAEx_List_BuildNode(&dmaNodeConfig, &TxNode) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + + /* Insert NodeTx to I2S queue */ + else if (HAL_DMAEx_List_InsertNode_Tail(&I2sTxQueue, &TxNode) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + + /* Set queue circular mode for I2S queue */ + else if (HAL_DMAEx_List_SetCircularMode(&I2sTxQueue) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + else + { + hDmaI2sTx.Instance = AUDIO_OUT_I2S6_DMA_CHANNEL; + + hDmaI2sTx.InitLinkedList.Priority = DMA_HIGH_PRIORITY; + hDmaI2sTx.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION; + hDmaI2sTx.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1; + hDmaI2sTx.InitLinkedList.TransferEventMode = DMA_TCEM_LAST_LL_ITEM_TRANSFER; + hDmaI2sTx.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR; + + /* DMA linked list init */ + if (HAL_DMAEx_List_Init(&hDmaI2sTx) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + + /* Link I2S queue to DMA channel */ + else if (HAL_DMAEx_List_LinkQ(&hDmaI2sTx, &I2sTxQueue) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + else + { + /* Associate the DMA handle */ + __HAL_LINKDMA(hi2s, hdmatx, hDmaI2sTx); + + /* I2S DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_OUT_I2S6_DMA_IRQ, BSP_AUDIO_OUT_IT_PRIORITY, 0); + HAL_NVIC_EnableIRQ(AUDIO_OUT_I2S6_DMA_IRQ); + } + } + } + else + { + /* Set node type */ + dmaNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE; + /* Set common node parameters */ + dmaNodeConfig.Init.Request = AUDIO_OUT_I2S6_DMA_REQUEST; + dmaNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + dmaNodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH; + dmaNodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED; + dmaNodeConfig.Init.DestInc = DMA_DINC_FIXED; + if (Audio_Out_Ctx[0].BitsPerSample == AUDIO_RESOLUTION_16B) + { + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD; + } + else /* AUDIO_RESOLUTION_24b */ + { + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + } + dmaNodeConfig.Init.SrcBurstLength = 1; + dmaNodeConfig.Init.DestBurstLength = 1; + dmaNodeConfig.Init.Priority = DMA_HIGH_PRIORITY; + dmaNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + dmaNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1; + /* Set node data handling parameters */ + dmaNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + dmaNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + /* Set node trigger parameters */ + dmaNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED; + + /* Build NodeTx */ + if (HAL_DMAEx_List_BuildNode(&dmaNodeConfig, &TxNode) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + + /* Replace NodeTx in I2S queue */ + else if (HAL_DMAEx_List_ReplaceNode_Head(&I2sTxQueue, &TxNode) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + + /* Set queue circular mode for I2S queue */ + else if (HAL_DMAEx_List_ClearCircularMode(&I2sTxQueue) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + else + { + /* Set queue circular mode for I2S queue */ + if (HAL_DMAEx_List_SetCircularMode(&I2sTxQueue) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + } + } + } + + /* DMA for Rx */ + if (Audio_In_Ctx[0].State != AUDIO_IN_STATE_RESET) + { + if (I2sRxQueue.Head == NULL) + { + AUDIO_IN_I2S6_DMA_CLK_ENABLE(); + + /* Set node type */ + dmaNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE; + /* Set common node parameters */ + dmaNodeConfig.Init.Request = AUDIO_IN_I2S6_DMA_REQUEST; + dmaNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + dmaNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY; + dmaNodeConfig.Init.SrcInc = DMA_SINC_FIXED; + dmaNodeConfig.Init.DestInc = DMA_DINC_INCREMENTED; + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD; + dmaNodeConfig.Init.SrcBurstLength = 1; + dmaNodeConfig.Init.DestBurstLength = 1; + dmaNodeConfig.Init.Priority = DMA_HIGH_PRIORITY; + dmaNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + dmaNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1; + /* Set node data handling parameters */ + dmaNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + dmaNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + /* Set node trigger parameters */ + dmaNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED; + + /* Build NodeRx */ + if (HAL_DMAEx_List_BuildNode(&dmaNodeConfig, &RxNode) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + + /* Insert NodeRx to I2S queue */ + else if (HAL_DMAEx_List_InsertNode_Tail(&I2sRxQueue, &RxNode) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + + /* Set queue circular mode for I2S queue */ + else if (HAL_DMAEx_List_SetCircularMode(&I2sRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + else + { + hDmaI2sRx.Instance = AUDIO_IN_I2S6_DMA_CHANNEL; + + hDmaI2sRx.InitLinkedList.Priority = DMA_HIGH_PRIORITY; + hDmaI2sRx.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION; + hDmaI2sRx.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0; + hDmaI2sRx.InitLinkedList.TransferEventMode = DMA_TCEM_LAST_LL_ITEM_TRANSFER; + hDmaI2sRx.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR; + + /* DMA linked list init */ + if (HAL_DMAEx_List_Init(&hDmaI2sRx) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + + /* Link I2S queue to DMA channel */ + else if (HAL_DMAEx_List_LinkQ(&hDmaI2sRx, &I2sRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + else + { + /* Associate the DMA handle */ + __HAL_LINKDMA(hi2s, hdmarx, hDmaI2sRx); + + /* SAI DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_IN_I2S6_DMA_IRQ, BSP_AUDIO_IN_IT_PRIORITY, 0); + HAL_NVIC_EnableIRQ(AUDIO_IN_I2S6_DMA_IRQ); + } + } + } + else + { + /* Set node type */ + dmaNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE; + /* Set common node parameters */ + dmaNodeConfig.Init.Request = AUDIO_IN_I2S6_DMA_REQUEST; + dmaNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + dmaNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY; + dmaNodeConfig.Init.SrcInc = DMA_SINC_FIXED; + dmaNodeConfig.Init.DestInc = DMA_DINC_INCREMENTED; + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD; + dmaNodeConfig.Init.SrcBurstLength = 1; + dmaNodeConfig.Init.DestBurstLength = 1; + dmaNodeConfig.Init.Priority = DMA_HIGH_PRIORITY; + dmaNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + dmaNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1; + /* Set node data handling parameters */ + dmaNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + dmaNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + /* Set node trigger parameters */ + dmaNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED; + + /* Build NodeRx */ + if (HAL_DMAEx_List_BuildNode(&dmaNodeConfig, &RxNode) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + + /* Replace NodeRx in I2S queue */ + else if (HAL_DMAEx_List_ReplaceNode_Head(&I2sRxQueue, &RxNode) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + + /* Set queue circular mode for I2S queue */ + else if (HAL_DMAEx_List_ClearCircularMode(&I2sRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + else + { + /* Set queue circular mode for I2S queue */ + if (HAL_DMAEx_List_SetCircularMode(&I2sRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + } + } + } +} + +/** + * @brief Deinitialize I2S MSP. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_MspDeInit(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + if (Audio_Out_Ctx[0].State != AUDIO_OUT_STATE_RESET) + { + /* Disable I2S DMA Channel IRQ */ + HAL_NVIC_DisableIRQ(AUDIO_OUT_I2S6_DMA_IRQ); + + /* Reset the DMA Channel configuration*/ + if (HAL_DMAEx_List_DeInit(&hDmaI2sTx) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + + /* Reset RxQueue */ + if (HAL_DMAEx_List_ResetQ(&I2sTxQueue) != HAL_OK) + { + BSP_AUDIO_OUT_Error_CallBack(0); + } + } + + if (Audio_In_Ctx[0].State != AUDIO_IN_STATE_RESET) + { + /* Disable I2S DMA Channel IRQ */ + HAL_NVIC_DisableIRQ(AUDIO_IN_I2S6_DMA_IRQ); + + /* Reset the DMA Channel configuration*/ + if (HAL_DMAEx_List_DeInit(&hDmaI2sRx) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + + /* Reset RxQueue */ + if (HAL_DMAEx_List_ResetQ(&I2sRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(0); + } + } + + /* De-initialize MCK, CK, WS, SDI and SDO pins */ + HAL_GPIO_DeInit(AUDIO_I2S6_MCK_GPIO_PORT, AUDIO_I2S6_MCK_GPIO_PIN); + HAL_GPIO_DeInit(AUDIO_I2S6_CK_GPIO_PORT, AUDIO_I2S6_CK_GPIO_PIN); + HAL_GPIO_DeInit(AUDIO_I2S6_WS_GPIO_PORT, AUDIO_I2S6_WS_GPIO_PIN); + HAL_GPIO_DeInit(AUDIO_I2S6_SDI_GPIO_PORT, AUDIO_I2S6_SDI_GPIO_PIN); + HAL_GPIO_DeInit(AUDIO_I2S6_SDO_GPIO_PORT, AUDIO_I2S6_SDO_GPIO_PIN); + + /* Disable I2S clock */ + AUDIO_I2S6_CLK_DISABLE(); +} + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) +/** + * @brief I2S Tx transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + BSP_AUDIO_OUT_TransferComplete_CallBack(0); +} + +/** + * @brief I2S Tx half transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + BSP_AUDIO_OUT_HalfTransfer_CallBack(0); +} + +/** + * @brief I2S Rx transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + uint32_t index; + uint16_t *RecBuff; + + UNUSED(hi2s); + + /* Only left channel of recorded data is relevant, copy it on right channel */ + RecBuff = (uint16_t *) (Audio_In_Ctx[0].pBuff + (Audio_In_Ctx[0].Size / 2U)); + for (index = 0; index < (Audio_In_Ctx[0].Size / 8U); index++) + { + RecBuff[(2U * index) + 1U] = RecBuff[2U * index]; + } + BSP_AUDIO_IN_TransferComplete_CallBack(0); +} + +/** + * @brief I2S Rx half transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + uint32_t index; + uint16_t *RecBuff; + + UNUSED(hi2s); + + /* Only left channel of recorded data is relevant, copy it on right channel */ + RecBuff = (uint16_t *) Audio_In_Ctx[0].pBuff; + for (index = 0; index < (Audio_In_Ctx[0].Size / 8U); index++) + { + RecBuff[(2U * index) + 1U] = RecBuff[2U * index]; + } + BSP_AUDIO_IN_HalfTransfer_CallBack(0); +} + +/** + * @brief I2S error callback. + * @param hi2s I2S handle. + * @retval None. + */ +static void I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + BSP_AUDIO_OUT_Error_CallBack(0); + BSP_AUDIO_IN_Error_CallBack(0); +} +#else /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ +/** + * @brief I2S Tx transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + BSP_AUDIO_OUT_TransferComplete_CallBack(0); +} + +/** + * @brief I2S Tx half transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + BSP_AUDIO_OUT_HalfTransfer_CallBack(0); +} + +/** + * @brief I2S Rx transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + uint32_t index; + uint16_t *RecBuff; + + UNUSED(hi2s); + + /* Only left channel of recorded data is relevant, copy it on right channel */ + RecBuff = (uint16_t *) (Audio_In_Ctx[0].pBuff + (Audio_In_Ctx[0].Size / 2U)); + for (index = 0; index < (Audio_In_Ctx[0].Size / 8U); index++) + { + RecBuff[(2U * index) + 1U] = RecBuff[2U * index]; + } + BSP_AUDIO_IN_TransferComplete_CallBack(0); +} + +/** + * @brief I2S Rx half transfer complete callback. + * @param hi2s I2S handle. + * @retval None. + */ +void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + uint32_t index; + uint16_t *RecBuff; + + UNUSED(hi2s); + + /* Only left channel of recorded data is relevant, copy it on right channel */ + RecBuff = (uint16_t *) Audio_In_Ctx[0].pBuff; + for (index = 0; index < (Audio_In_Ctx[0].Size / 8U); index++) + { + RecBuff[(2U * index) + 1U] = RecBuff[2U * index]; + } + BSP_AUDIO_IN_HalfTransfer_CallBack(0); +} + +/** + * @brief I2S error callback. + * @param hi2s I2S handle. + * @retval None. + */ +void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) +{ + UNUSED(hi2s); + + BSP_AUDIO_OUT_Error_CallBack(0); + BSP_AUDIO_IN_Error_CallBack(0); +} +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Initialize MDF MSP. + * @param hmdf handle. + * @retval None. + */ +static void MDF_MspInit(MDF_HandleTypeDef *hmdf) +{ + GPIO_InitTypeDef GPIO_InitStruct; + static DMA_NodeTypeDef RxNode; + static DMA_NodeConfTypeDef dmaNodeConfig; + + /* Enable ADF1 clock */ + AUDIO_ADF1_CLK_ENABLE(); + + /* ADF pins configuration: DATIN0 and CCK0 pins */ + AUDIO_ADF1_DATIN0_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = AUDIO_ADF1_DATIN0_GPIO_AF; + GPIO_InitStruct.Pin = AUDIO_ADF1_DATIN0_GPIO_PIN; + HAL_GPIO_Init(AUDIO_ADF1_DATIN0_GPIO_PORT, &GPIO_InitStruct); + + AUDIO_ADF1_CCK0_GPIO_CLK_ENABLE(); + GPIO_InitStruct.Alternate = AUDIO_ADF1_CCK0_GPIO_AF; + GPIO_InitStruct.Pin = AUDIO_ADF1_CCK0_GPIO_PIN; + HAL_GPIO_Init(AUDIO_ADF1_CCK0_GPIO_PORT, &GPIO_InitStruct); + + /* DMA configuration */ + if (MdfRxQueue.Head == NULL) + { + AUDIO_IN_ADF1_DMA_CLK_ENABLE(); + + /* Set node type */ + dmaNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE; + /* Set common node parameters */ + dmaNodeConfig.Init.Request = AUDIO_IN_ADF1_DMA_REQUEST; + dmaNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST; + dmaNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY; + dmaNodeConfig.Init.SrcInc = DMA_SINC_FIXED; + dmaNodeConfig.Init.DestInc = DMA_DINC_INCREMENTED; + dmaNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + dmaNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + dmaNodeConfig.Init.SrcBurstLength = 1; + dmaNodeConfig.Init.DestBurstLength = 1; + dmaNodeConfig.Init.Priority = DMA_HIGH_PRIORITY; + dmaNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + dmaNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1; + /* Set node data handling parameters */ + dmaNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE; + dmaNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + /* Set node trigger parameters */ + dmaNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED; + + /* Build NodeRx */ + if (HAL_DMAEx_List_BuildNode(&dmaNodeConfig, &RxNode) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + + /* Insert NodeRx to ADF queue */ + else if (HAL_DMAEx_List_InsertNode_Tail(&MdfRxQueue, &RxNode) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + + /* Set queue circular mode for ADF queue */ + else if (HAL_DMAEx_List_SetCircularMode(&MdfRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + else + { + hDmaMdf.Instance = AUDIO_IN_ADF1_DMA_CHANNEL; + + hDmaMdf.InitLinkedList.Priority = DMA_HIGH_PRIORITY; + hDmaMdf.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION; + hDmaMdf.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1; + hDmaMdf.InitLinkedList.TransferEventMode = DMA_TCEM_LAST_LL_ITEM_TRANSFER; + hDmaMdf.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR; + + /* DMA linked list init */ + if (HAL_DMAEx_List_Init(&hDmaMdf) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + + /* Link MDF queue to DMA channel */ + else if (HAL_DMAEx_List_LinkQ(&hDmaMdf, &MdfRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + else + { + /* Associate the DMA handle */ + __HAL_LINKDMA(hmdf, hdma, hDmaMdf); + + /* MDF DMA IRQ Channel configuration */ + HAL_NVIC_SetPriority(AUDIO_IN_ADF1_DMA_IRQ, BSP_AUDIO_OUT_IT_PRIORITY, 0); + HAL_NVIC_EnableIRQ(AUDIO_IN_ADF1_DMA_IRQ); + } + } + } +} + +/** + * @brief DeInitialize MDF MSP. + * @param hmdf MDF handle. + * @retval None. + */ +static void MDF_MspDeInit(MDF_HandleTypeDef *hmdf) +{ + UNUSED(hmdf); + + /* Disable MDF DMA Channel IRQ */ + HAL_NVIC_DisableIRQ(AUDIO_IN_ADF1_DMA_IRQ); + + /* Reset the DMA Channel configuration*/ + if (HAL_DMAEx_List_DeInit(&hDmaMdf) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + + /* Reset RxQueue */ + if (HAL_DMAEx_List_ResetQ(&MdfRxQueue) != HAL_OK) + { + BSP_AUDIO_IN_Error_CallBack(1); + } + + /* De-initialize DATIN0 and CCK0 pins */ + HAL_GPIO_DeInit(AUDIO_ADF1_DATIN0_GPIO_PORT, AUDIO_ADF1_DATIN0_GPIO_PIN); + HAL_GPIO_DeInit(AUDIO_ADF1_CCK0_GPIO_PORT, AUDIO_ADF1_CCK0_GPIO_PIN); + + /* Disable MDF clock */ + AUDIO_ADF1_CLK_DISABLE(); +} + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +/** + * @brief MDF acquisition complete callback. + * @param hmdf MDF handle. + * @retval None. + */ +static void MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf) +{ + uint32_t index; + uint32_t recbufsize = Audio_In_Ctx[1].Size / 2U; + __IO int32_t tmp; + + UNUSED(hmdf); + + for (index = (recbufsize / 2U); index < recbufsize; index++) + { + tmp = Audio_DigMicRecBuff[index] / 256; + tmp = SaturaLH(tmp, -32768, 32767); + Audio_In_Ctx[1].pBuff[2U * index] = (uint8_t) tmp; + Audio_In_Ctx[1].pBuff[(2U * index) + 1U] = (uint8_t)((uint32_t) tmp >> 8); + } + + /* Invoke 'TransferCompete' callback function */ + BSP_AUDIO_IN_TransferComplete_CallBack(1); +} + +/** + * @brief MDF acquisition half complete callback. + * @param hmdf MDF handle. + * @retval None. + */ +static void MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf) +{ + uint32_t index; + uint32_t recbufsize = Audio_In_Ctx[1].Size / 2U; + __IO int32_t tmp; + + UNUSED(hmdf); + + for (index = 0; index < (recbufsize / 2U); index++) + { + tmp = Audio_DigMicRecBuff[index] / 256; + tmp = SaturaLH(tmp, -32768, 32767); + Audio_In_Ctx[1].pBuff[2U * index] = (uint8_t) tmp; + Audio_In_Ctx[1].pBuff[(2U * index) + 1U] = (uint8_t)((uint32_t) tmp >> 8); + } + + /* Invoke the 'HalfTransfer' callback function */ + BSP_AUDIO_IN_HalfTransfer_CallBack(1); +} + +/** + * @brief MDF error callback. + * @param hmdf MDF handle. + * @retval None. + */ +static void MDF_ErrorCallback(MDF_HandleTypeDef *hmdf) +{ + UNUSED(hmdf); + + BSP_AUDIO_IN_Error_CallBack(1); +} +#else /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ +/** + * @brief MDF acquisition complete callback. + * @param hmdf MDF handle. + * @retval None. + */ +void HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf) +{ + uint32_t index; + uint32_t recbufsize = Audio_In_Ctx[1].Size / 2U; + __IO int32_t tmp; + + UNUSED(hmdf); + + for (index = (recbufsize / 2U); index < recbufsize; index++) + { + tmp = Audio_DigMicRecBuff[index] / 256; + tmp = SaturaLH(tmp, -32768, 32767); + Audio_In_Ctx[1].pBuff[2U * index] = (uint8_t) tmp; + Audio_In_Ctx[1].pBuff[(2U * index) + 1U] = (uint8_t)((uint32_t) tmp >> 8); + } + + /* Invoke 'TransferCompete' callback function */ + BSP_AUDIO_IN_TransferComplete_CallBack(1); +} + +/** + * @brief MDF acquisition half complete callback. + * @param hmdf MDF handle. + * @retval None. + */ +void HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf) +{ + uint32_t index; + uint32_t recbufsize = Audio_In_Ctx[1].Size / 2U; + __IO int32_t tmp; + + UNUSED(hmdf); + + for (index = 0; index < (recbufsize / 2U); index++) + { + tmp = Audio_DigMicRecBuff[index] / 256; + tmp = SaturaLH(tmp, -32768, 32767); + Audio_In_Ctx[1].pBuff[2U * index] = (uint8_t) tmp; + Audio_In_Ctx[1].pBuff[(2U * index) + 1U] = (uint8_t)((uint32_t) tmp >> 8); + } + + /* Invoke the 'HalfTransfer' callback function */ + BSP_AUDIO_IN_HalfTransfer_CallBack(1); +} + +/** + * @brief MDF error callback. + * @param hmdf MDF handle. + * @retval None. + */ +void HAL_MDF_ErrorCallback(MDF_HandleTypeDef *hmdf) +{ + UNUSED(hmdf); + + BSP_AUDIO_IN_Error_CallBack(1); +} +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.h new file mode 100644 index 0000000..ef367b3 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.h @@ -0,0 +1,358 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_audio.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32h7s78_discovery_audio.c driver. + ****************************************************************************** + * @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 STM32H7S78_DISCOVERY_AUDIO_H +#define STM32H7S78_DISCOVERY_AUDIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" +#include "../Components/Common/audio.h" +#include "../Components/wm8904/wm8904.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup STM32H7S78_DK_AUDIO + * @{ + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Exported_Types STM32H7S78_DK AUDIO Exported Types + * @{ + */ +typedef struct +{ + uint32_t Device; /* Output or input device */ + uint32_t SampleRate; /* From 8kHz to 192 kHz */ + uint32_t BitsPerSample; /* From 8 bits per sample to 32 bits per sample */ + uint32_t ChannelsNbr; /* 1 for mono and 2 for stereo */ + uint32_t Volume; /* In percentage from 0 to 100 */ +} BSP_AUDIO_Init_t; + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) +typedef struct +{ + pI2S_CallbackTypeDef pMspInitCb; + pI2S_CallbackTypeDef pMspDeInitCb; +} BSP_AUDIO_OUT_Cb_t; +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + +#if ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) +typedef struct +{ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) + pI2S_CallbackTypeDef pMspI2sInitCb; + pI2S_CallbackTypeDef pMspI2sDeInitCb; +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + pMDF_CallbackTypeDef pMspMdfInitCb; + pMDF_CallbackTypeDef pMspMdfDeInitCb; +#endif /* (USE_HAL_MDF_REGISTER_CALLBACKS == 1) */ +} BSP_AUDIO_IN_Cb_t; +#endif /* ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) */ + +typedef struct +{ + uint32_t AudioFrequency; + uint32_t Mode; + uint32_t DataFormat; +} MX_I2S_Config_t; + +typedef struct +{ + int32_t Gain; + uint32_t DecimationRatio; + uint32_t CicMode; + uint32_t ProcClockDivider; + uint32_t OutputClockDivider; +} MX_MDF_Config_t; + +/* Audio in and out context */ +typedef struct +{ + uint32_t Device; /* Audio IN device to be used */ + uint32_t SampleRate; /* Audio IN Sample rate */ + uint32_t BitsPerSample; /* Audio IN Sample resolution */ + uint32_t ChannelsNbr; /* Audio IN number of channel */ + uint8_t *pBuff; /* Audio IN record buffer */ + uint32_t Size; /* Audio IN record buffer size */ + uint32_t Volume; /* Audio IN volume */ + uint32_t State; /* Audio IN State */ +} AUDIO_IN_Ctx_t; + +typedef struct +{ + uint32_t Device; /* Audio out device */ + uint32_t SampleRate; /* Audio out sample rate */ + uint32_t BitsPerSample; /* Audio out bits per sample */ + uint32_t Volume; /* Audio out volume */ + uint32_t ChannelsNbr; /* Audio out number of channels */ + uint32_t IsMute; /* Audio out mute state */ + uint32_t State; /* Audio out state */ +} AUDIO_OUT_Ctx_t; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_Exported_Constants STM32H7S78_DK AUDIO Exported Constants + * @{ + */ +/* Audio out instances */ +#define AUDIO_OUT_INSTANCES_NBR 1U + +/* Audio in instances */ +#define AUDIO_IN_INSTANCES_NBR 2U + +/* Audio out devices */ +#define AUDIO_OUT_HEADPHONE 1U + +/* Audio input devices */ +#define AUDIO_IN_ANALOG_MIC 0x01U +#define AUDIO_IN_DIGITAL_MIC 0x10U /* Digital microphone */ + +/* Audio out states */ +#define AUDIO_OUT_STATE_RESET 0U +#define AUDIO_OUT_STATE_PLAYING 1U +#define AUDIO_OUT_STATE_STOP 2U +#define AUDIO_OUT_STATE_PAUSE 3U +#define AUDIO_OUT_STATE_INIT 4U + +/* Audio in states */ +#define AUDIO_IN_STATE_RESET 0U +#define AUDIO_IN_STATE_RECORDING 1U +#define AUDIO_IN_STATE_STOP 2U +#define AUDIO_IN_STATE_PAUSE 3U +#define AUDIO_IN_STATE_INIT 4U + +/* Audio sample rate */ +#define AUDIO_FREQUENCY_192K 192000U +#define AUDIO_FREQUENCY_176K 176400U +#define AUDIO_FREQUENCY_96K 96000U +#define AUDIO_FREQUENCY_88K 88200U +#define AUDIO_FREQUENCY_48K 48000U +#define AUDIO_FREQUENCY_44K 44100U +#define AUDIO_FREQUENCY_32K 32000U +#define AUDIO_FREQUENCY_22K 22050U +#define AUDIO_FREQUENCY_16K 16000U +#define AUDIO_FREQUENCY_11K 11025U +#define AUDIO_FREQUENCY_8K 8000U + +/* Audio bits per sample */ +#define AUDIO_RESOLUTION_8B 8U +#define AUDIO_RESOLUTION_16B 16U +#define AUDIO_RESOLUTION_24B 24U +#define AUDIO_RESOLUTION_32B 32U + +/* Audio mute state */ +#define AUDIO_MUTE_DISABLED 0U +#define AUDIO_MUTE_ENABLED 1U + +/* Audio I2C address */ +#define AUDIO_I2C_ADDRESS 0x34U + +/* Audio in and out GPIOs */ +#define AUDIO_I2S6_MCK_GPIO_PORT GPIOA +#define AUDIO_I2S6_MCK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define AUDIO_I2S6_MCK_GPIO_PIN GPIO_PIN_3 +#define AUDIO_I2S6_MCK_SDI_GPIO_AF GPIO_AF5_SPI6 + +#define AUDIO_I2S6_CK_GPIO_PORT GPIOA +#define AUDIO_I2S6_CK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define AUDIO_I2S6_CK_GPIO_PIN GPIO_PIN_5 +#define AUDIO_I2S6_CK_WS_SDO_GPIO_AF GPIO_AF8_SPI6 + +#define AUDIO_I2S6_WS_GPIO_PORT GPIOA +#define AUDIO_I2S6_WS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define AUDIO_I2S6_WS_GPIO_PIN GPIO_PIN_4 + +#define AUDIO_I2S6_SDO_GPIO_PORT GPIOB +#define AUDIO_I2S6_SDO_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define AUDIO_I2S6_SDO_GPIO_PIN GPIO_PIN_5 + +#define AUDIO_I2S6_SDI_GPIO_PORT GPIOG +#define AUDIO_I2S6_SDI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define AUDIO_I2S6_SDI_GPIO_PIN GPIO_PIN_12 + +#define AUDIO_I2S6_CLK_ENABLE() __HAL_RCC_SPI6_CLK_ENABLE() +#define AUDIO_I2S6_CLK_DISABLE() __HAL_RCC_SPI6_CLK_DISABLE() + +#define AUDIO_OUT_I2S6_DMA_CLK_ENABLE() __HAL_RCC_GPDMA1_CLK_ENABLE() +#define AUDIO_OUT_I2S6_DMA_CHANNEL GPDMA1_Channel2 +#define AUDIO_OUT_I2S6_DMA_REQUEST GPDMA1_REQUEST_SPI6_TX +#define AUDIO_OUT_I2S6_DMA_IRQ GPDMA1_Channel2_IRQn +#define AUDIO_OUT_I2S6_DMA_IRQHandler GPDMA1_Channel2_IRQHandler + +#define AUDIO_IN_I2S6_DMA_CLK_ENABLE() __HAL_RCC_GPDMA1_CLK_ENABLE() +#define AUDIO_IN_I2S6_DMA_CHANNEL GPDMA1_Channel3 +#define AUDIO_IN_I2S6_DMA_REQUEST GPDMA1_REQUEST_SPI6_RX +#define AUDIO_IN_I2S6_DMA_IRQ GPDMA1_Channel3_IRQn +#define AUDIO_IN_I2S6_DMA_IRQHandler GPDMA1_Channel3_IRQHandler + +#define AUDIO_ADF1_CCK0_GPIO_PORT GPIOE +#define AUDIO_ADF1_CCK0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define AUDIO_ADF1_CCK0_GPIO_PIN GPIO_PIN_2 +#define AUDIO_ADF1_CCK0_GPIO_AF GPIO_AF1_ADF1 + +#define AUDIO_ADF1_DATIN0_GPIO_PORT GPIOD +#define AUDIO_ADF1_DATIN0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define AUDIO_ADF1_DATIN0_GPIO_PIN GPIO_PIN_6 +#define AUDIO_ADF1_DATIN0_GPIO_AF GPIO_AF3_ADF1 + +#define AUDIO_ADF1_CLK_ENABLE() __HAL_RCC_ADF1_CLK_ENABLE() +#define AUDIO_ADF1_CLK_DISABLE() __HAL_RCC_ADF1_CLK_DISABLE() + +#define AUDIO_IN_ADF1_DMA_CLK_ENABLE() __HAL_RCC_GPDMA1_CLK_ENABLE() +#define AUDIO_IN_ADF1_DMA_CHANNEL GPDMA1_Channel4 +#define AUDIO_IN_ADF1_DMA_REQUEST GPDMA1_REQUEST_ADF1_FLT0 +#define AUDIO_IN_ADF1_DMA_IRQ GPDMA1_Channel4_IRQn +#define AUDIO_IN_ADF1_DMA_IRQHandler GPDMA1_Channel4_IRQHandler + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_AUDIO_Exported_Variables + * @{ + */ +/* Audio in and out context */ +extern AUDIO_OUT_Ctx_t Audio_Out_Ctx[AUDIO_OUT_INSTANCES_NBR]; +extern AUDIO_IN_Ctx_t Audio_In_Ctx[AUDIO_IN_INSTANCES_NBR]; + +/* Audio component object */ +extern void *Audio_CompObj; + +/* Audio driver */ +extern AUDIO_Drv_t *Audio_Drv; + +/* Audio in and out I2S handles */ +extern I2S_HandleTypeDef haudio_out_i2s; +extern I2S_HandleTypeDef haudio_in_i2s; + +/* Audio in MDF handles */ +extern MDF_HandleTypeDef haudio_in_mdf; + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_OUT_Exported_Functions STM32H7S78_DK AUDIO_OUT Exported Functions + * @{ + */ +int32_t BSP_AUDIO_OUT_Init(uint32_t Instance, BSP_AUDIO_Init_t *AudioInit); +int32_t BSP_AUDIO_OUT_DeInit(uint32_t Instance); +int32_t BSP_AUDIO_OUT_Play(uint32_t Instance, uint8_t *pData, uint32_t NbrOfBytes); +int32_t BSP_AUDIO_OUT_Pause(uint32_t Instance); +int32_t BSP_AUDIO_OUT_Resume(uint32_t Instance); +int32_t BSP_AUDIO_OUT_Stop(uint32_t Instance); +int32_t BSP_AUDIO_OUT_Mute(uint32_t Instance); +int32_t BSP_AUDIO_OUT_UnMute(uint32_t Instance); +int32_t BSP_AUDIO_OUT_IsMute(uint32_t Instance, uint32_t *IsMute); +int32_t BSP_AUDIO_OUT_SetVolume(uint32_t Instance, uint32_t Volume); +int32_t BSP_AUDIO_OUT_GetVolume(uint32_t Instance, uint32_t *Volume); +int32_t BSP_AUDIO_OUT_SetSampleRate(uint32_t Instance, uint32_t SampleRate); +int32_t BSP_AUDIO_OUT_GetSampleRate(uint32_t Instance, uint32_t *SampleRate); +int32_t BSP_AUDIO_OUT_SetDevice(uint32_t Instance, uint32_t Device); +int32_t BSP_AUDIO_OUT_GetDevice(uint32_t Instance, uint32_t *Device); +int32_t BSP_AUDIO_OUT_SetBitsPerSample(uint32_t Instance, uint32_t BitsPerSample); +int32_t BSP_AUDIO_OUT_GetBitsPerSample(uint32_t Instance, uint32_t *BitsPerSample); +int32_t BSP_AUDIO_OUT_SetChannelsNbr(uint32_t Instance, uint32_t ChannelNbr); +int32_t BSP_AUDIO_OUT_GetChannelsNbr(uint32_t Instance, uint32_t *ChannelNbr); +int32_t BSP_AUDIO_OUT_GetState(uint32_t Instance, uint32_t *State); + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1) +int32_t BSP_AUDIO_OUT_RegisterDefaultMspCallbacks(uint32_t Instance); +int32_t BSP_AUDIO_OUT_RegisterMspCallbacks(uint32_t Instance, BSP_AUDIO_OUT_Cb_t *CallBacks); +#endif /* (USE_HAL_I2S_REGISTER_CALLBACKS == 1) */ + +void BSP_AUDIO_OUT_TransferComplete_CallBack(uint32_t Instance); +void BSP_AUDIO_OUT_HalfTransfer_CallBack(uint32_t Instance); +void BSP_AUDIO_OUT_Error_CallBack(uint32_t Instance); + +void BSP_AUDIO_OUT_IRQHandler(uint32_t Instance, uint32_t Device); + +HAL_StatusTypeDef MX_I2S6_ClockConfig(I2S_HandleTypeDef *hi2s, uint32_t SampleRate); +HAL_StatusTypeDef MX_I2S6_Init(I2S_HandleTypeDef *hi2s, MX_I2S_Config_t *MXInit); +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_AUDIO_IN_Exported_Functions STM32H7S78_DK AUDIO_IN Exported Functions + * @{ + */ +int32_t BSP_AUDIO_IN_Init(uint32_t Instance, BSP_AUDIO_Init_t *AudioInit); +int32_t BSP_AUDIO_IN_DeInit(uint32_t Instance); +int32_t BSP_AUDIO_IN_Record(uint32_t Instance, uint8_t *pData, uint32_t NbrOfBytes); +int32_t BSP_AUDIO_IN_Pause(uint32_t Instance); +int32_t BSP_AUDIO_IN_Resume(uint32_t Instance); +int32_t BSP_AUDIO_IN_Stop(uint32_t Instance); +int32_t BSP_AUDIO_IN_SetVolume(uint32_t Instance, uint32_t Volume); +int32_t BSP_AUDIO_IN_GetVolume(uint32_t Instance, uint32_t *Volume); +int32_t BSP_AUDIO_IN_SetSampleRate(uint32_t Instance, uint32_t SampleRate); +int32_t BSP_AUDIO_IN_GetSampleRate(uint32_t Instance, uint32_t *SampleRate); +int32_t BSP_AUDIO_IN_SetDevice(uint32_t Instance, uint32_t Device); +int32_t BSP_AUDIO_IN_GetDevice(uint32_t Instance, uint32_t *Device); +int32_t BSP_AUDIO_IN_SetBitsPerSample(uint32_t Instance, uint32_t BitsPerSample); +int32_t BSP_AUDIO_IN_GetBitsPerSample(uint32_t Instance, uint32_t *BitsPerSample); +int32_t BSP_AUDIO_IN_SetChannelsNbr(uint32_t Instance, uint32_t ChannelNbr); +int32_t BSP_AUDIO_IN_GetChannelsNbr(uint32_t Instance, uint32_t *ChannelNbr); +int32_t BSP_AUDIO_IN_GetState(uint32_t Instance, uint32_t *State); + +#if ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) +int32_t BSP_AUDIO_IN_RegisterDefaultMspCallbacks(uint32_t Instance); +int32_t BSP_AUDIO_IN_RegisterMspCallbacks(uint32_t Instance, BSP_AUDIO_IN_Cb_t *CallBacks); +#endif /* ((USE_HAL_MDF_REGISTER_CALLBACKS == 1) || (USE_HAL_I2S_REGISTER_CALLBACKS == 1)) */ + +void BSP_AUDIO_IN_TransferComplete_CallBack(uint32_t Instance); +void BSP_AUDIO_IN_HalfTransfer_CallBack(uint32_t Instance); +void BSP_AUDIO_IN_Error_CallBack(uint32_t Instance); + +void BSP_AUDIO_IN_IRQHandler(uint32_t Instance, uint32_t Device); + +HAL_StatusTypeDef MX_ADF1_ClockConfig(MDF_HandleTypeDef *hmdf, uint32_t SampleRate); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_AUDIO_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.c new file mode 100644 index 0000000..d86d3aa --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.c @@ -0,0 +1,885 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_bus.c + * @author MCD Application Team + * @brief This file provides a set of firmware functions to communicate + * with external devices available on STM32H7S78-DK board (MB1736) from + * STMicroelectronics + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_bus.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_BUS BUS + * @{ + */ + +/** @defgroup STM32H7S78_DK_BUS_Private_Constants Private Constants + * @{ + */ +#ifndef I2C_VALID_TIMING_NBR +#define I2C_VALID_TIMING_NBR 128U +#endif /* I2C_VALID_TIMING_NBR */ +#define I2C_SPEED_FREQ_STANDARD 0U /* 100 kHz */ +#define I2C_SPEED_FREQ_FAST 1U /* 400 kHz */ +#define I2C_SPEED_FREQ_FAST_PLUS 2U /* 1 MHz */ +#define I2C_ANALOG_FILTER_DELAY_MIN 50U /* ns */ +#define I2C_ANALOG_FILTER_DELAY_MAX 260U /* ns */ +#define I2C_USE_ANALOG_FILTER 1U +#define I2C_DIGITAL_FILTER_COEF 0U +#define I2C_PRESC_MAX 16U +#define I2C_SCLDEL_MAX 16U +#define I2C_SDADEL_MAX 16U +#define I2C_SCLH_MAX 256U +#define I2C_SCLL_MAX 256U +#define SEC2NSEC 1000000000UL +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_BUS_Private_Types Private Types + * @{ + */ +typedef struct +{ + uint32_t freq; /* Frequency in Hz */ + uint32_t freq_min; /* Minimum frequency in Hz */ + uint32_t freq_max; /* Maximum frequency in Hz */ + uint32_t hddat_min; /* Minimum data hold time in ns */ + uint32_t vddat_max; /* Maximum data valid time in ns */ + uint32_t sudat_min; /* Minimum data setup time in ns */ + uint32_t lscl_min; /* Minimum low period of the SCL clock in ns */ + uint32_t hscl_min; /* Minimum high period of SCL clock in ns */ + uint32_t trise; /* Rise time in ns */ + uint32_t tfall; /* Fall time in ns */ + uint32_t dnf; /* Digital noise filter coefficient */ +} I2C_Charac_t; + +typedef struct +{ + uint32_t presc; /* Timing prescaler */ + uint32_t tscldel; /* SCL delay */ + uint32_t tsdadel; /* SDA delay */ + uint32_t sclh; /* SCL high period */ + uint32_t scll; /* SCL low period */ +} I2C_Timings_t; +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_BUS_Private_Constants + * @{ + */ +static const I2C_Charac_t I2C_Charac[] = +{ + [I2C_SPEED_FREQ_STANDARD] = + { + .freq = 100000, + .freq_min = 80000, + .freq_max = 120000, + .hddat_min = 0, + .vddat_max = 3450, + .sudat_min = 250, + .lscl_min = 4700, + .hscl_min = 4000, + .trise = 640, + .tfall = 20, + .dnf = I2C_DIGITAL_FILTER_COEF, + }, + [I2C_SPEED_FREQ_FAST] = + { + .freq = 400000, + .freq_min = 320000, + .freq_max = 480000, + .hddat_min = 0, + .vddat_max = 900, + .sudat_min = 100, + .lscl_min = 1300, + .hscl_min = 600, + .trise = 250, + .tfall = 100, + .dnf = I2C_DIGITAL_FILTER_COEF, + }, + [I2C_SPEED_FREQ_FAST_PLUS] = + { + .freq = 1000000, + .freq_min = 800000, + .freq_max = 1200000, + .hddat_min = 0, + .vddat_max = 450, + .sudat_min = 50, + .lscl_min = 500, + .hscl_min = 260, + .trise = 60, + .tfall = 100, + .dnf = I2C_DIGITAL_FILTER_COEF, + }, +}; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_BUS_Private_Variables Private Variables + * @{ + */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +static uint32_t IsI2c1MspCbValid = 0; +#endif /* (USE_HAL_I2C_REGISTER_CALLBACKS == 1) */ +static uint32_t I2c1InitCounter = 0; +static I2C_Timings_t I2c_valid_timing[I2C_VALID_TIMING_NBR]; +static uint32_t I2c_valid_timing_nbr = 0; +#if defined(BSP_USE_CMSIS_OS) +static osSemaphoreId BspI2cSemaphore = 0; +#endif /* BSP_USE_CMSIS_OS */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_BUS_Exported_Variables Exported Variables + * @{ + */ +I2C_HandleTypeDef hbus_i2c1; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_BUS_Private_FunctionPrototypes BUS Private FunctionPrototypes + * @{ + */ +static void I2C1_MspInit(I2C_HandleTypeDef *phi2c); +static void I2C1_MspDeInit(I2C_HandleTypeDef *phi2c); +static int32_t I2C1_WriteReg(uint16_t DevAddr, uint16_t MemAddSize, uint16_t Reg, uint8_t *pData, uint16_t Length); +static int32_t I2C1_ReadReg(uint16_t DevAddr, uint16_t MemAddSize, uint16_t Reg, uint8_t *pData, uint16_t Length); +static uint32_t I2C_GetTiming(uint32_t clock_src_freq, uint32_t i2c_freq); +static uint32_t I2C_Compute_SCLL_SCLH(uint32_t clock_src_freq, uint32_t I2C_speed); +static void I2C_Compute_PRESC_SCLDEL_SDADEL(uint32_t clock_src_freq, uint32_t I2C_speed); +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_BUS_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes I2C HAL. + * @retval BSP status + */ +int32_t BSP_I2C1_Init(void) +{ + int32_t ret = BSP_ERROR_NONE; + + hbus_i2c1.Instance = BUS_I2C1; + + if (I2c1InitCounter == 0U) + { + I2c1InitCounter++; + + if (HAL_I2C_GetState(&hbus_i2c1) == HAL_I2C_STATE_RESET) + { +#if defined(BSP_USE_CMSIS_OS) + if (BspI2cSemaphore == NULL) + { + /* Create semaphore to prevent multiple I2C access */ + osSemaphoreDef(BSP_I2C_SEM); + BspI2cSemaphore = osSemaphoreCreate(osSemaphore(BSP_I2C_SEM), 1); + } +#endif /* BSP_USE_CMSIS_OS */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 0) + /* Init the I2C1 Msp */ + I2C1_MspInit(&hbus_i2c1); +#else + if (IsI2c1MspCbValid == 0U) + { + if (BSP_I2C1_RegisterDefaultMspCallbacks() != BSP_ERROR_NONE) + { + ret = BSP_ERROR_MSP_FAILURE; + } + } + if (ret == BSP_ERROR_NONE) + { +#endif /* (USE_HAL_I2C_REGISTER_CALLBACKS == 0) */ + if (MX_I2C1_Init(&hbus_i2c1, I2C_GetTiming(HAL_RCC_GetPCLK2Freq(), BUS_I2C1_FREQUENCY)) != HAL_OK) + { + ret = BSP_ERROR_BUS_FAILURE; + } +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + } +#endif /* (USE_HAL_I2C_REGISTER_CALLBACKS == 1) */ + } + } + + return ret; +} + +/** + * @brief DeInitializes I2C HAL. + * @retval BSP status + */ +int32_t BSP_I2C1_DeInit(void) +{ + int32_t ret = BSP_ERROR_NONE; + + I2c1InitCounter--; + + if (I2c1InitCounter == 0U) + { +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 0) + I2C1_MspDeInit(&hbus_i2c1); +#endif /* (USE_HAL_I2C_REGISTER_CALLBACKS == 0) */ + + /* Init the I2C */ + if (HAL_I2C_DeInit(&hbus_i2c1) != HAL_OK) + { + ret = BSP_ERROR_BUS_FAILURE; + } + } + + return ret; +} + +/** + * @brief MX I2C1 initialization. + * @param hi2c I2C handle + * @param timing I2C timing + * @retval HAL status + */ +__weak HAL_StatusTypeDef MX_I2C1_Init(I2C_HandleTypeDef *hi2c, uint32_t timing) +{ + HAL_StatusTypeDef status = HAL_OK; + + hi2c->Init.Timing = timing; + hi2c->Init.OwnAddress1 = 0; + hi2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c->Init.OwnAddress2 = 0; + hi2c->Init.OwnAddress2Masks = I2C_OA2_NOMASK; + hi2c->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + + if (HAL_I2C_Init(hi2c) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + uint32_t analog_filter; + + analog_filter = I2C_ANALOGFILTER_ENABLE; + if (HAL_I2CEx_ConfigAnalogFilter(hi2c, analog_filter) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + if (HAL_I2CEx_ConfigDigitalFilter(hi2c, I2C_DIGITAL_FILTER_COEF) != HAL_OK) + { + status = HAL_ERROR; + } + } + } + + return status; +} + +/** + * @brief Write a 8bit value in a register of the device through BUS. + * @param DevAddr Device address on Bus. + * @param Reg The target register address to write + * @param pData The target register value to be written + * @param Length buffer size to be written + * @retval BSP status + */ +int32_t BSP_I2C1_WriteReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) +{ + int32_t ret; +#if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + if (I2C1_WriteReg(DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length) == 0) + { + ret = BSP_ERROR_NONE; + } + else + { + if ( HAL_I2C_GetError(&hbus_i2c1) == HAL_I2C_ERROR_AF) + { + ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; + } + else + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + return ret; +} + +/** + * @brief Read a 8bit register of the device through BUS + * @param DevAddr Device address on BUS + * @param Reg The target register address to read + * @param pData Pointer to data buffer + * @param Length Length of the data + * @retval BSP status + */ +int32_t BSP_I2C1_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) +{ + int32_t ret; +#if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + if (I2C1_ReadReg(DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length) == 0) + { + ret = BSP_ERROR_NONE; + } + else + { + if ( HAL_I2C_GetError(&hbus_i2c1) == HAL_I2C_ERROR_AF) + { + ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; + } + else + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + return ret; +} + +/** + * @brief Write a 16bit value in a register of the device through BUS. + * @param DevAddr Device address on Bus. + * @param Reg The target register address to write + * @param pData The target register value to be written + * @param Length buffer size to be written + * @retval BSP status + */ +int32_t BSP_I2C1_WriteReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) +{ + int32_t ret; + #if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + if (I2C1_WriteReg(DevAddr, Reg, I2C_MEMADD_SIZE_16BIT, pData, Length) == 0) + { + ret = BSP_ERROR_NONE; + } + else + { + if ( HAL_I2C_GetError(&hbus_i2c1) == HAL_I2C_ERROR_AF) + { + ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; + } + else + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + return ret; +} + +/** + * @brief Read a 16bit register of the device through BUS + * @param DevAddr Device address on BUS + * @param Reg The target register address to read + * @param pData Pointer to data buffer + * @param Length Length of the data + * @retval BSP status + */ +int32_t BSP_I2C1_ReadReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) +{ + int32_t ret; +#if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + if (I2C1_ReadReg(DevAddr, Reg, I2C_MEMADD_SIZE_16BIT, pData, Length) == 0) + { + ret = BSP_ERROR_NONE; + } + else + { + if ( HAL_I2C_GetError(&hbus_i2c1) == HAL_I2C_ERROR_AF) + { + ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; + } + else + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + return ret; +} + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param DevAddr Target device address + * @param Trials Number of trials + * @retval BSP status + */ +int32_t BSP_I2C1_IsReady(uint16_t DevAddr, uint32_t Trials) +{ + int32_t ret = BSP_ERROR_NONE; +#if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + if (HAL_I2C_IsDeviceReady(&hbus_i2c1, DevAddr, Trials, 1000) != HAL_OK) + { + ret = BSP_ERROR_BUSY; + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + return ret; +} + +/** + * @brief Delay function + * @retval Tick value + */ +int32_t BSP_GetTick(void) +{ + return (int32_t)HAL_GetTick(); +} + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +/** + * @brief Register Default I2C1 Bus Msp Callbacks + * @retval BSP status + */ +int32_t BSP_I2C1_RegisterDefaultMspCallbacks (void) +{ + int32_t ret = BSP_ERROR_NONE; +#if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + __HAL_I2C_RESET_HANDLE_STATE(&hbus_i2c1); + + /* Register default MspInit/MspDeInit Callback */ + if (HAL_I2C_RegisterCallback(&hbus_i2c1, HAL_I2C_MSPINIT_CB_ID, I2C1_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2C_RegisterCallback(&hbus_i2c1, HAL_I2C_MSPDEINIT_CB_ID, I2C1_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + IsI2c1MspCbValid = 1U; + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + /* BSP status */ + return ret; +} + +/** + * @brief Register I2C1 Bus Msp Callback registering + * @param Callbacks pointer to I2C1 MspInit/MspDeInit callback functions + * @retval BSP status + */ +int32_t BSP_I2C1_RegisterMspCallbacks (BSP_I2C_Cb_t *Callback) +{ + int32_t ret = BSP_ERROR_NONE; +#if defined(BSP_USE_CMSIS_OS) + /* Get semaphore to prevent multiple I2C access */ + osSemaphoreWait(BspI2cSemaphore, osWaitForever); +#endif /* BSP_USE_CMSIS_OS */ + __HAL_I2C_RESET_HANDLE_STATE(&hbus_i2c1); + + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_I2C_RegisterCallback(&hbus_i2c1, HAL_I2C_MSPINIT_CB_ID, Callback->pMspI2cInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_I2C_RegisterCallback(&hbus_i2c1, HAL_I2C_MSPDEINIT_CB_ID, Callback->pMspI2cDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + IsI2c1MspCbValid = 1U; + } +#if defined(BSP_USE_CMSIS_OS) + /* Release semaphore to prevent multiple I2C access */ + osSemaphoreRelease(BspI2cSemaphore); +#endif /* BSP_USE_CMSIS_OS */ + /* BSP status */ + return ret; +} +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_BUS_Private_Functions Private Functions + * @{ + */ +/** + * @brief Compute I2C timing according current I2C clock source and required I2C clock. + * @param clock_src_freq I2C clock source in Hz. + * @param i2c_freq Required I2C clock in Hz. + * @retval I2C timing or 0 in case of error. + */ +static uint32_t I2C_GetTiming(uint32_t clock_src_freq, uint32_t i2c_freq) +{ + uint32_t ret = 0; + uint32_t speed; + uint32_t idx; + + if ((clock_src_freq != 0U) && (i2c_freq != 0U)) + { + for ( speed = 0 ; speed <= (uint32_t)I2C_SPEED_FREQ_FAST_PLUS ; speed++) + { + if ((i2c_freq >= I2C_Charac[speed].freq_min) && + (i2c_freq <= I2C_Charac[speed].freq_max)) + { + I2C_Compute_PRESC_SCLDEL_SDADEL(clock_src_freq, speed); + idx = I2C_Compute_SCLL_SCLH(clock_src_freq, speed); + + if (idx < I2C_VALID_TIMING_NBR) + { + ret = ((I2c_valid_timing[idx].presc & 0x0FU) << 28) | \ + ((I2c_valid_timing[idx].tscldel & 0x0FU) << 20) | \ + ((I2c_valid_timing[idx].tsdadel & 0x0FU) << 16) | \ + ((I2c_valid_timing[idx].sclh & 0xFFU) << 8) | \ + ((I2c_valid_timing[idx].scll & 0xFFU) << 0); + } + break; + } + } + } + + return ret; +} + +/** + * @brief Compute PRESC, SCLDEL and SDADEL. + * @param clock_src_freq I2C source clock in HZ. + * @param I2C_speed I2C frequency (index). + * @retval None. + */ +static void I2C_Compute_PRESC_SCLDEL_SDADEL(uint32_t clock_src_freq, uint32_t I2C_speed) +{ + uint32_t prev_presc = I2C_PRESC_MAX; + uint32_t ti2cclk; + int32_t tsdadel_min; + int32_t tsdadel_max; + int32_t tscldel_min; + uint32_t presc; + uint32_t scldel; + uint32_t sdadel; + uint32_t tafdel_min; + uint32_t tafdel_max; + + ti2cclk = (SEC2NSEC + (clock_src_freq / 2U)) / clock_src_freq; + + tafdel_min = I2C_ANALOG_FILTER_DELAY_MIN; + tafdel_max = I2C_ANALOG_FILTER_DELAY_MAX; + + /** + * tDNF = DNF x tI2CCLK + * tPRESC = (PRESC+1) x tI2CCLK + * SDADEL >= {tf +tHD;DAT(min) - tAF(min) - tDNF - [3 x tI2CCLK]} / {tPRESC} + * SDADEL <= {tVD;DAT(max) - tr - tAF(max) - tDNF- [4 x tI2CCLK]} / {tPRESC} + **/ + + tsdadel_min = (int32_t)I2C_Charac[I2C_speed].tfall + (int32_t)I2C_Charac[I2C_speed].hddat_min - + (int32_t)tafdel_min - (int32_t)(((int32_t)I2C_Charac[I2C_speed].dnf + 3) * (int32_t)ti2cclk); + + tsdadel_max = (int32_t)I2C_Charac[I2C_speed].vddat_max - (int32_t)I2C_Charac[I2C_speed].trise - + (int32_t)tafdel_max - (int32_t)(((int32_t)I2C_Charac[I2C_speed].dnf + 4) * (int32_t)ti2cclk); + + + /* {[tr+ tSU;DAT(min)] / [tPRESC]} - 1 <= SCLDEL */ + tscldel_min = (int32_t)I2C_Charac[I2C_speed].trise + (int32_t)I2C_Charac[I2C_speed].sudat_min; + + if (tsdadel_min <= 0) + { + tsdadel_min = 0; + } + + if (tsdadel_max <= 0) + { + tsdadel_max = 0; + } + + for (presc = 0; presc < I2C_PRESC_MAX; presc++) + { + for (scldel = 0; scldel < I2C_SCLDEL_MAX; scldel++) + { + /* TSCLDEL = (SCLDEL+1) * (PRESC+1) * TI2CCLK */ + uint32_t tscldel = (scldel + 1U) * (presc + 1U) * ti2cclk; + + if (tscldel >= (uint32_t)tscldel_min) + { + for (sdadel = 0; sdadel < I2C_SDADEL_MAX; sdadel++) + { + /* TSDADEL = SDADEL * (PRESC+1) * TI2CCLK */ + uint32_t tsdadel = (sdadel * (presc + 1U)) * ti2cclk; + + if ((tsdadel >= (uint32_t)tsdadel_min) && (tsdadel <= (uint32_t)tsdadel_max)) + { + if (presc != prev_presc) + { + I2c_valid_timing[I2c_valid_timing_nbr].presc = presc; + I2c_valid_timing[I2c_valid_timing_nbr].tscldel = scldel; + I2c_valid_timing[I2c_valid_timing_nbr].tsdadel = sdadel; + prev_presc = presc; + I2c_valid_timing_nbr ++; + + if (I2c_valid_timing_nbr >= I2C_VALID_TIMING_NBR) + { + return; + } + } + } + } + } + } + } +} + +/** + * @brief Calculate SCLL and SCLH and find best configuration. + * @param clock_src_freq I2C source clock in HZ. + * @param I2C_speed I2C frequency (index). + * @retval config index (0 to I2C_VALID_TIMING_NBR], 0xFFFFFFFF for no valid config. + */ +static uint32_t I2C_Compute_SCLL_SCLH (uint32_t clock_src_freq, uint32_t I2C_speed) +{ + uint32_t ret = 0xFFFFFFFFU; + uint32_t ti2cclk; + uint32_t ti2cspeed; + uint32_t prev_error; + uint32_t dnf_delay; + uint32_t clk_min; + uint32_t clk_max; + uint32_t scll; + uint32_t sclh; + uint32_t tafdel_min; + + ti2cclk = (SEC2NSEC + (clock_src_freq / 2U)) / clock_src_freq; + ti2cspeed = (SEC2NSEC + (I2C_Charac[I2C_speed].freq / 2U)) / I2C_Charac[I2C_speed].freq; + + tafdel_min = I2C_ANALOG_FILTER_DELAY_MIN; + + /* tDNF = DNF x tI2CCLK */ + dnf_delay = I2C_Charac[I2C_speed].dnf * ti2cclk; + + clk_max = SEC2NSEC / I2C_Charac[I2C_speed].freq_min; + clk_min = SEC2NSEC / I2C_Charac[I2C_speed].freq_max; + + prev_error = ti2cspeed; + + for (uint32_t count = 0; count < I2c_valid_timing_nbr; count++) + { + /* tPRESC = (PRESC+1) x tI2CCLK*/ + uint32_t tpresc = (I2c_valid_timing[count].presc + 1U) * ti2cclk; + + for (scll = 0; scll < I2C_SCLL_MAX; scll++) + { + /* tLOW(min) <= tAF(min) + tDNF + 2 x tI2CCLK + [(SCLL+1) x tPRESC ] */ + uint32_t tscl_l = tafdel_min + dnf_delay + (2U * ti2cclk) + ((scll + 1U) * tpresc); + + + /* The I2CCLK period tI2CCLK must respect the following conditions: + tI2CCLK < (tLOW - tfilters) / 4 and tI2CCLK < tHIGH */ + if ((tscl_l > I2C_Charac[I2C_speed].lscl_min) && (ti2cclk < ((tscl_l - tafdel_min - dnf_delay) / 4U))) + { + for (sclh = 0; sclh < I2C_SCLH_MAX; sclh++) + { + /* tHIGH(min) <= tAF(min) + tDNF + 2 x tI2CCLK + [(SCLH+1) x tPRESC] */ + uint32_t tscl_h = tafdel_min + dnf_delay + (2U * ti2cclk) + ((sclh + 1U) * tpresc); + + /* tSCL = tf + tLOW + tr + tHIGH */ + uint32_t tscl = tscl_l + tscl_h + I2C_Charac[I2C_speed].trise + I2C_Charac[I2C_speed].tfall; + + if ((tscl >= clk_min) && (tscl <= clk_max) && (tscl_h >= I2C_Charac[I2C_speed].hscl_min) && (ti2cclk < tscl_h)) + { + int32_t error = (int32_t)tscl - (int32_t)ti2cspeed; + + if (error < 0) + { + error = -error; + } + + /* look for the timings with the lowest clock error */ + if ((uint32_t)error < prev_error) + { + prev_error = (uint32_t)error; + I2c_valid_timing[count].scll = scll; + I2c_valid_timing[count].sclh = sclh; + ret = count; + } + } + } + } + } + } + + return ret; +} + +/** + * @brief Initializes I2C MSP. + * @param phi2c I2C handler + * @retval None + */ +static void I2C1_MspInit(I2C_HandleTypeDef *phi2c) +{ + GPIO_InitTypeDef gpio_init_structure; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(phi2c); + + /*** Configure the GPIOs ***/ + /* Enable SCL GPIO clock */ + BUS_I2C1_SCL_GPIO_CLK_ENABLE(); + /* Enable SDA GPIO clock */ + BUS_I2C1_SDA_GPIO_CLK_ENABLE(); + + /* Configure I2C Tx as alternate function */ + gpio_init_structure.Pin = BUS_I2C1_SCL_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_OD; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Alternate = BUS_I2C1_SCL_AF; + HAL_GPIO_Init(BUS_I2C1_SCL_GPIO_PORT, &gpio_init_structure); + + /* Configure I2C Rx as alternate function */ + gpio_init_structure.Pin = BUS_I2C1_SDA_PIN; + gpio_init_structure.Alternate = BUS_I2C1_SDA_AF; + HAL_GPIO_Init(BUS_I2C1_SDA_GPIO_PORT, &gpio_init_structure); + + /*** Configure the I2C peripheral ***/ + /* Enable I2C clock */ + BUS_I2C1_CLK_ENABLE(); + + /* Force the I2C peripheral clock reset */ + BUS_I2C1_FORCE_RESET(); + + /* Release the I2C peripheral clock reset */ + BUS_I2C1_RELEASE_RESET(); +} + +/** + * @brief DeInitializes I2C MSP. + * @param phi2c I2C handler + * @retval None + */ +static void I2C1_MspDeInit(I2C_HandleTypeDef *phi2c) +{ + GPIO_InitTypeDef gpio_init_structure; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(phi2c); + + /* Configure I2C Tx, Rx as alternate function */ + gpio_init_structure.Pin = BUS_I2C1_SCL_PIN; + HAL_GPIO_DeInit(BUS_I2C1_SCL_GPIO_PORT, gpio_init_structure.Pin); + gpio_init_structure.Pin = BUS_I2C1_SDA_PIN; + HAL_GPIO_DeInit(BUS_I2C1_SDA_GPIO_PORT, gpio_init_structure.Pin); + + /* Disable I2C clock */ + BUS_I2C1_CLK_DISABLE(); +} + +/** + * @brief Write a value in a register of the device through BUS. + * @param DevAddr Device address on Bus. + * @param MemAddSize Size of internal memory address + * @param Reg The target register address to write + * @param pData The target register value to be written + * @param Length data length in bytes + * @retval BSP status + */ +static int32_t I2C1_WriteReg(uint16_t DevAddr, uint16_t Reg, uint16_t MemAddSize, uint8_t *pData, uint16_t Length) +{ + if (HAL_I2C_Mem_Write(&hbus_i2c1, DevAddr, Reg, MemAddSize, pData, Length, 1000) == HAL_OK) + { + return BSP_ERROR_NONE; + } + + return BSP_ERROR_BUS_FAILURE; +} + +/** + * @brief Read a register of the device through BUS + * @param DevAddr Device address on BUS + * @param MemAddSize Size of internal memory address + * @param Reg The target register address to read + * @param pData The target register value to be read + * @param Length data length in bytes + * @retval BSP status + */ +static int32_t I2C1_ReadReg(uint16_t DevAddr, uint16_t Reg, uint16_t MemAddSize, uint8_t *pData, uint16_t Length) +{ + if (HAL_I2C_Mem_Read(&hbus_i2c1, DevAddr, Reg, MemAddSize, pData, Length, 1000) == HAL_OK) + { + return BSP_ERROR_NONE; + } + + return BSP_ERROR_BUS_FAILURE; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.h new file mode 100644 index 0000000..bc76a6d --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.h @@ -0,0 +1,135 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_bus.h + * @author MCD Application Team + * @brief This file is the header of stm32h7s78_discovery_bus.c 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7S78_DISCOVERY_BUS_H +#define STM32H7S78_DISCOVERY_BUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" +#if defined(BSP_USE_CMSIS_OS) +#include "cmsis_os.h" +#endif /* BSP_USE_CMSIS_OS */ +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup STM32H7S78_DK_BUS + * @{ + */ +/** @defgroup STM32H7S78_DK_BUS_Exported_Types Exported Types + * @{ + */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +typedef struct +{ + void (* pMspI2cInitCb)(I2C_HandleTypeDef *); + void (* pMspI2cDeInitCb)(I2C_HandleTypeDef *); +} BSP_I2C_Cb_t; +#endif /* (USE_HAL_I2C_REGISTER_CALLBACKS == 1) */ + +/** + * @} + */ +/** @defgroup STM32H7S78_DK_BUS_Exported_Constants Exported Constants + * @{ + */ +/* Definition for I2C1 clock resources */ +#define BUS_I2C1 I2C1 +#define BUS_I2C1_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE() +#define BUS_I2C1_CLK_DISABLE() __HAL_RCC_I2C1_CLK_DISABLE() +#define BUS_I2C1_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define BUS_I2C1_SCL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define BUS_I2C1_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define BUS_I2C1_SDA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() + +#define BUS_I2C1_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET() +#define BUS_I2C1_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET() + +/* Definition for I2C1 Pins */ +#define BUS_I2C1_SCL_PIN GPIO_PIN_6 +#define BUS_I2C1_SDA_PIN GPIO_PIN_9 +#define BUS_I2C1_SCL_GPIO_PORT GPIOB +#define BUS_I2C1_SDA_GPIO_PORT GPIOB +#define BUS_I2C1_SCL_AF GPIO_AF4_I2C1 +#define BUS_I2C1_SDA_AF GPIO_AF4_I2C1 + +#ifndef BUS_I2C1_FREQUENCY +#define BUS_I2C1_FREQUENCY 100000U /* Frequency of I2Cn = 100 KHz*/ +#endif /* BUS_I2C1_FREQUENCY */ + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_BUS_Exported_Variables + * @{ + */ +extern I2C_HandleTypeDef hbus_i2c1; +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_BUS_Exported_Functions + * @{ + */ +int32_t BSP_I2C1_Init(void); +int32_t BSP_I2C1_DeInit(void); +int32_t BSP_I2C1_WriteReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length); +int32_t BSP_I2C1_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length); +int32_t BSP_I2C1_WriteReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length); +int32_t BSP_I2C1_ReadReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length); +int32_t BSP_I2C1_Recv(uint16_t DevAddr, uint16_t Reg, uint16_t MemAddSize, uint8_t *pData, uint16_t Length); +int32_t BSP_I2C1_Send(uint16_t DevAddr, uint16_t Reg, uint16_t MemAddSize, uint8_t *pData, uint16_t Length); +int32_t BSP_I2C1_IsReady(uint16_t DevAddr, uint32_t Trials); +int32_t BSP_GetTick(void); +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +int32_t BSP_I2C1_RegisterDefaultMspCallbacks(void); +int32_t BSP_I2C1_RegisterMspCallbacks(BSP_I2C_Cb_t *Callback); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +HAL_StatusTypeDef MX_I2C1_Init(I2C_HandleTypeDef *hi2c, uint32_t timing); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_BUS_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_conf_template.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_conf_template.h new file mode 100644 index 0000000..07d4e02 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_conf_template.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_conf_template.h + * @author MCD Application Team + * This file should be copied to the application folder and renamed + * to stm32h7s78_discovery_conf.h + ****************************************************************************** + * @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 STM32H7S78_DISCOVERY_CONF_H +#define STM32H7S78_DISCOVERY_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/* COM defines */ +#define USE_COM_LOG 0U +#define USE_BSP_COM_FEATURE 0U + +/* Touch Sensing controller defines */ +#define USE_FT5336_TS_CTRL 1U +/* TS supported features defines */ +#define USE_TS_GESTURE 1U +#define USE_TS_MULTI_TOUCH 1U +/* Default TS touch number */ +#define TS_TOUCH_NBR 2U + +/* LCD defines */ +#define LCD_LAYER_0_ADDRESS 0x90000000U +#define LCD_LAYER_1_ADDRESS 0x90200000U + +/* Default Audio IN internal buffer size */ +#define DEFAULT_AUDIO_IN_BUFFER_SIZE 2048U + +/* IRQ priorities (Default is 15 as lowest priority level) */ +#define BSP_SDRAM_IT_PRIORITY 15U +#define BSP_BUTTON_USER_IT_PRIORITY 15U +#define BSP_AUDIO_OUT_IT_PRIORITY 14U +#define BSP_AUDIO_IN_IT_PRIORITY 15U +#define BSP_SD_IT_PRIORITY 14U +#define BSP_SD_RX_IT_PRIORITY 14U +#define BSP_SD_TX_IT_PRIORITY 15U +#define BSP_TS_IT_PRIORITY 15U +#define BSP_XSPI_RAM_IT_PRIORITY 15U +#define BSP_XSPI_RAM_DMA_IT_PRIORITY 15U + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_CONF_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_errno.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_errno.h new file mode 100644 index 0000000..9e085bf --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_errno.h @@ -0,0 +1,70 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_errno.h + * @author MCD Application Team + * @brief Error code definitions. + * + ****************************************************************************** + * @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 STM32H7S78_DISCOVERY_ERRNO_H +#define STM32H7S78_DISCOVERY_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Common Error codes */ +#define BSP_ERROR_NONE 0 +#define BSP_ERROR_NO_INIT -1 +#define BSP_ERROR_WRONG_PARAM -2 +#define BSP_ERROR_BUSY -3 +#define BSP_ERROR_PERIPH_FAILURE -4 +#define BSP_ERROR_COMPONENT_FAILURE -5 +#define BSP_ERROR_UNKNOWN_FAILURE -6 +#define BSP_ERROR_UNKNOWN_COMPONENT -7 +#define BSP_ERROR_BUS_FAILURE -8 +#define BSP_ERROR_CLOCK_FAILURE -9 +#define BSP_ERROR_MSP_FAILURE -10 +#define BSP_ERROR_FEATURE_NOT_SUPPORTED -11 + +/* BSP XSPI error codes */ +#define BSP_ERROR_XSPI_SUSPENDED -20 +#define BSP_ERROR_XSPI_ASSIGN_FAILURE -24 +#define BSP_ERROR_XSPI_SETUP_FAILURE -25 +#define BSP_ERROR_XSPI_MMP_LOCK_FAILURE -26 +#define BSP_ERROR_XSPI_MMP_UNLOCK_FAILURE -27 + +/* BSP TS error code */ +#define BSP_ERROR_TS_TOUCH_NOT_DETECTED -30 + +/* BSP SD error code */ +#define BSP_ERROR_SD_NOT_DETECTED -40 + +/* BSP BUS error codes */ +#define BSP_ERROR_BUS_TRANSACTION_FAILURE -100 +#define BSP_ERROR_BUS_ARBITRATION_LOSS -101 +#define BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE -102 +#define BSP_ERROR_BUS_PROTOCOL_FAILURE -103 + +#define BSP_ERROR_BUS_MODE_FAULT -104 +#define BSP_ERROR_BUS_FRAME_ERROR -105 +#define BSP_ERROR_BUS_CRC_ERROR -106 +#define BSP_ERROR_BUS_DMA_FAILURE -107 + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_ERRNO_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.c new file mode 100644 index 0000000..3a752da --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.c @@ -0,0 +1,1613 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_lcd.c + * @author MCD Application Team + * @brief This file includes the driver for Liquid Crystal Display (LCD) module + * mounted on STM32H7S78_DK board. + ****************************************************************************** + * @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 used to drive directly a LCD TFT using the LTDC controller. + - This driver uses the adequate timing and setting for the RK050HR18 LCD component + + Driver description: + --------------------- + + Initialization steps: + o Initialize the LCD in default mode using the BSP_LCD_Init() function with the + following settings: + - Pixelformat : LCD_PIXEL_FORMAT_RGB888 + - Orientation : LCD_ORIENTATION_LANDSCAPE. + - Width : LCD_DEFAULT_WIDTH (800) + - Height : LCD_DEFAULT_HEIGHT(480) + The default LTDC layer configured is layer 0. + BSP_LCD_Init() includes LTDC, LTDC Layer and clock configurations by calling: + - MX_LTDC_ClockConfig() + - MX_LTDC_Init() + - MX_LTDC_ConfigLayer() + + o Initialize the LCD with required parameters using the BSP_LCD_InitEx() function. + + o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function. + o Enable the LCD display using the BSP_LCD_DisplayOn() function. + o Disable the LCD display using the BSP_LCD_DisplayOff() function. + o Write a pixel to the LCD memory using the BSP_LCD_WritePixel() function. + o Read a pixel from the LCD memory using the BSP_LCD_ReadPixel() function. + o Draw an horizontal line using the BSP_LCD_DrawHLine() function. + o Draw a vertical line using the BSP_LCD_DrawVLine() function. + o Draw a bitmap image using the BSP_LCD_DrawBitmap() function. + + + Options + o Configure the LTDC reload mode by calling BSP_LCD_Reload(). By default, the + reload mode is set to BSP_LCD_RELOAD_IMMEDIATE then LTDC is reloaded immediately. + To control the reload mode: + - Call BSP_LCD_Reload() with ReloadType parameter set to BSP_LCD_RELOAD_NONE + - Configure LTDC (color keying, transparency ..) + - Call BSP_LCD_Reload() with ReloadType parameter set to BSP_LCD_RELOAD_IMMEDIATE + for immediate reload or BSP_LCD_RELOAD_VERTICAL_BLANKING for LTDC reload + in the next vertical blanking + o Configure LTDC layers using BSP_LCD_ConfigLayer() + o Control layer visibility using BSP_LCD_SetLayerVisible() + o Configure and enable the color keying functionality using the + BSP_LCD_SetColorKeying() function. + o Disable the color keying functionality using the BSP_LCD_ResetColorKeying() function. + o Modify on the fly the transparency and/or the frame buffer address + using the following functions: + - BSP_LCD_SetTransparency() + - BSP_LCD_SetLayerAddress() + + + Display on LCD + o To draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap) + on LCD and display text, utility basic_gui.c/.h must be called. Once the LCD is initialized, + user should call GUI_SetFuncDriver() API to link board LCD drivers to BASIC GUI LCD drivers. + The basic gui services, defined in basic_gui utility, are ready for use. + + Note: + -------- + Regarding the "Instance" parameter, needed for all functions, it is used to select + an LCD instance. On the STM32H7B3I-EVAL board, there's one instance. Then, this + parameter should be 0. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_lcd.h" +#include "stm32h7s78_discovery_xspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_LCD LCD + * @{ + */ + +/** @defgroup STM32H7S78_DK_LCD_Private_Variables STM32H7S78_DK LCD Private Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LCD_Private_TypesDefinitions STM32H7S78_DK LCD Private TypesDefinitions + * @{ + */ +/* LPTimer handler declaration */ +static LPTIM_HandleTypeDef hlcd_lptim; +static LPTIM_OC_ConfigTypeDef hlcd_lptim_config = {0}; +/** @defgroup STM32H573I_DK_LCD_Private_Types LCD Private Types + * @{ + */ +const LCD_UTILS_Drv_t LCD_Driver = +{ + BSP_LCD_DrawBitmap, + BSP_LCD_FillRGBRect, + BSP_LCD_DrawHLine, + BSP_LCD_DrawVLine, + BSP_LCD_FillRect, + BSP_LCD_ReadPixel, + BSP_LCD_WritePixel, + BSP_LCD_GetXSize, + BSP_LCD_GetYSize, + BSP_LCD_SetActiveLayer, + BSP_LCD_GetPixelFormat +}; + +/** + * @} + */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LCD_Exported_Variables STM32H7S78_DK LCD Exported Variables + * @{ + */ +DMA2D_HandleTypeDef hlcd_dma2d; +LTDC_HandleTypeDef hlcd_ltdc; +BSP_LCD_Ctx_t Lcd_Ctx[LCD_INSTANCES_NBR]; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LCD_Private_FunctionPrototypes STM32H7S78_DK LCD Private Function Prototypes + * @{ + */ + +static void LTDC_MspInit(LTDC_HandleTypeDef *hltdc); +static void LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc); +static void DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d); +static void DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d); +static void LL_FillBuffer(uint32_t Instance, uint32_t *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t Color); +static void LL_ConvertLineToRGB(uint32_t Instance, uint32_t *pSrc, uint32_t *pDst, uint32_t xSize, uint32_t ColorMode); +static void LPTIMx_PWM_MspInit(LPTIM_HandleTypeDef *hlptim); +static void LPTIMx_PWM_MspDeInit(LPTIM_HandleTypeDef *hlptim); +static void LPTIMx_PWM_DeInit(LPTIM_HandleTypeDef *hlptim); +static void LPTIMx_PWM_Init(LPTIM_HandleTypeDef *hlptim); +/** + * @} + */ +/** @defgroup STM32H7S78_DK_LCD_Private_Macros STM32H7S78_DK LCD Private Macros + * @{ + */ +#define CONVERTRGB5652ARGB8888(Color)((((((((Color) >> (11U)) & 0x1FU) * 527U) + 23U) >> (6U)) << (16U)) |\ + (((((((Color) >> (5U)) & 0x3FU) * 259U) + 33U) >> (6U)) << (8U)) |\ + (((((Color) & 0x1FU) * 527U) + 23U) >> (6U)) | (0xFF000000U)) +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LCD_Exported_Functions STM32H7S78_DK LCD Exported Functions + * @{ + */ +/** + * @brief Initializes the LCD in default mode. + * @param Instance LCD Instance + * @param Orientation LCD_ORIENTATION_LANDSCAPE + * @retval BSP status + */ + +int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation) +{ + return BSP_LCD_InitEx(Instance, Orientation, LCD_PIXEL_FORMAT_RGB888, LCD_DEFAULT_WIDTH, LCD_DEFAULT_HEIGHT); +} + +/** + * @brief Initializes the LCD. + * @param Instance LCD Instance + * @param Orientation LCD_ORIENTATION_LANDSCAPE + * @param PixelFormat LCD_PIXEL_FORMAT_RGB565 or LCD_PIXEL_FORMAT_RGB888 + * @param Width Display width + * @param Height Display height + * @retval BSP status + */ +int32_t BSP_LCD_InitEx(uint32_t Instance, uint32_t Orientation, uint32_t PixelFormat, uint32_t Width, uint32_t Height) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t ltdc_pixel_format; + MX_LTDC_LayerConfig_t config; +#if !defined(DATA_IN_ExtRAM) + BSP_XSPI_RAM_Cfg_t xspi_init = { + BSP_XSPI_RAM_VARIABLE_LATENCY, + BSP_XSPI_RAM_READ_LATENCY_7, + BSP_XSPI_RAM_WRITE_LATENCY_7, + BSP_XSPI_RAM_IO_X16_MODE + }; +#endif /* DATA_IN_ExtRAM */ + + if ((Orientation > LCD_ORIENTATION_LANDSCAPE) || (Instance >= LCD_INSTANCES_NBR) || \ + ((PixelFormat != LCD_PIXEL_FORMAT_RGB565) && (PixelFormat != LTDC_PIXEL_FORMAT_RGB888))) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (PixelFormat == LCD_PIXEL_FORMAT_RGB565) + { + ltdc_pixel_format = LTDC_PIXEL_FORMAT_RGB565; + Lcd_Ctx[Instance].BppFactor = 2U; + } + else /* LCD_PIXEL_FORMAT_RGB888 */ + { + ltdc_pixel_format = LTDC_PIXEL_FORMAT_ARGB8888; + Lcd_Ctx[Instance].BppFactor = 4U; + } + + /* Store pixel format, xsize and ysize information */ + Lcd_Ctx[Instance].PixelFormat = PixelFormat; + Lcd_Ctx[Instance].XSize = Width; + Lcd_Ctx[Instance].YSize = Height; + + /* Initializes peripherals instance value */ + hlcd_ltdc.Instance = LTDC; + hlcd_dma2d.Instance = DMA2D; + + /* MSP initialization */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + /* Register the LTDC MSP Callbacks */ + if (Lcd_Ctx[Instance].IsMspCallbacksValid == 0U) + { + if (BSP_LCD_RegisterDefaultMspCallbacks(0) != BSP_ERROR_NONE) + { + return BSP_ERROR_PERIPH_FAILURE; + } + } +#else + LTDC_MspInit(&hlcd_ltdc); +#endif + + /* Assert display enable LCD_DISP_CTRL pin */ + HAL_GPIO_WritePin(LCD_DISP_EN_GPIO_PORT, LCD_DISP_EN_PIN, GPIO_PIN_SET); + + DMA2D_MspInit(&hlcd_dma2d); + + if (MX_LTDC_ClockConfig(&hlcd_ltdc) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (MX_LTDC_Init(&hlcd_ltdc, Width, Height) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + if (ret == BSP_ERROR_NONE) + { +#if !defined(DATA_IN_ExtRAM) + /* Before configuring LTDC layer, ensure XSPI RAM is initialized */ + /* Initialize the XSPI RAM */ + if (BSP_XSPI_RAM_Init(0, &xspi_init) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_NO_INIT; + } + else if (BSP_XSPI_RAM_EnableMemoryMappedMode(0) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { +#endif /* DATA_IN_ExtRAM */ + /* Configure default LTDC Layer 0. This configuration can be override by calling + BSP_LCD_ConfigLayer() at application level */ + config.X0 = 0; + config.X1 = Width; + config.Y0 = 0; + config.Y1 = Height; + config.PixelFormat = ltdc_pixel_format; + config.Address = LCD_LAYER_0_ADDRESS; + + if (MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, &config) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Initialize LPTIM in PWM mode to control brightness */ + LPTIMx_PWM_Init(&hlcd_lptim); + /* By default the reload is activated and executed immediately */ + Lcd_Ctx[Instance].ReloadEnable = 1U; +#if !defined(DATA_IN_ExtRAM) + } +#endif /* DATA_IN_ExtRAM */ + } + } + + /* Enable Display */ + (void)BSP_LCD_DisplayOn(Instance); + + return ret; +} + +/** + * @brief De-Initializes the LCD resources. + * @param Instance LCD Instance + * @retval BSP status + */ +int32_t BSP_LCD_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 0) + LTDC_MspDeInit(&hlcd_ltdc); +#endif /* (USE_HAL_LTDC_REGISTER_CALLBACKS == 0) */ + + DMA2D_MspDeInit(&hlcd_dma2d); + + (void)HAL_LTDC_DeInit(&hlcd_ltdc); + if (HAL_DMA2D_DeInit(&hlcd_dma2d) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + Lcd_Ctx[Instance].IsMspCallbacksValid = 0; + } + +#if !defined(DATA_IN_ExtRAM) + if(BSP_XSPI_RAM_DeInit(0) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } +#endif /* DATA_IN_ExtRAM */ + } + + /* DeInit LPTIM PWM */ + LPTIMx_PWM_DeInit(&hlcd_lptim); + + /* Disable Display */ + (void)BSP_LCD_DisplayOff(Instance); + + return ret; +} + +/** + * @brief Initializes the LTDC. + * @param hltdc LTDC handle + * @param Width LTDC width + * @param Height LTDC height + * @retval HAL status + */ +__weak HAL_StatusTypeDef MX_LTDC_Init(LTDC_HandleTypeDef *hltdc, uint32_t Width, uint32_t Height) +{ + hltdc->Instance = LTDC; + hltdc->Init.HSPolarity = LTDC_HSPOLARITY_AL; + hltdc->Init.VSPolarity = LTDC_VSPOLARITY_AL; + hltdc->Init.DEPolarity = LTDC_DEPOLARITY_AL; + hltdc->Init.PCPolarity = LTDC_PCPOLARITY_IPC; + + hltdc->Init.HorizontalSync = RK050HR18_HSYNC; + hltdc->Init.AccumulatedHBP = RK050HR18_HSYNC + RK050HR18_HBP; + hltdc->Init.AccumulatedActiveW = RK050HR18_HSYNC + Width + RK050HR18_HBP; + hltdc->Init.TotalWidth = RK050HR18_HSYNC + Width + RK050HR18_HBP + RK050HR18_HFP; + hltdc->Init.VerticalSync = RK050HR18_VSYNC; + hltdc->Init.AccumulatedVBP = RK050HR18_VSYNC + RK050HR18_VBP; + hltdc->Init.AccumulatedActiveH = RK050HR18_VSYNC + Height + RK050HR18_VBP; + hltdc->Init.TotalHeigh = RK050HR18_VSYNC + Height + RK050HR18_VBP + RK050HR18_VFP; + + hltdc->Init.Backcolor.Blue = 0xFF; + hltdc->Init.Backcolor.Green = 0xFF; + hltdc->Init.Backcolor.Red = 0xFF; + + return HAL_LTDC_Init(hltdc); +} + +/** + * @brief MX LTDC layer configuration. + * @param hltdc LTDC handle + * @param LayerIndex Layer 0 or 1 + * @param Config Layer configuration + * @retval HAL status + */ +__weak HAL_StatusTypeDef MX_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, uint32_t LayerIndex, MX_LTDC_LayerConfig_t *Config) +{ + LTDC_LayerCfgTypeDef pLayerCfg = {0}; + + pLayerCfg.WindowX0 = Config->X0; + pLayerCfg.WindowX1 = Config->X1; + pLayerCfg.WindowY0 = Config->Y0; + pLayerCfg.WindowY1 = Config->Y1; + pLayerCfg.PixelFormat = Config->PixelFormat; + pLayerCfg.Alpha = 255; + pLayerCfg.Alpha0 = 0; + pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; + pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; + pLayerCfg.FBStartAdress = Config->Address; + pLayerCfg.ImageWidth = (Config->X1 - Config->X0); + pLayerCfg.ImageHeight = (Config->Y1 - Config->Y0); + pLayerCfg.Backcolor.Blue = 0; + pLayerCfg.Backcolor.Green = 0; + pLayerCfg.Backcolor.Red = 0; + return HAL_LTDC_ConfigLayer(hltdc, &pLayerCfg, LayerIndex); +} + +/** + * @brief LTDC Clock Config for LCD DPI display. + * @param hltdc LTDC Handle + * Being __weak it can be overwritten by the application + * @retval HAL_status + */ +__weak HAL_StatusTypeDef MX_LTDC_ClockConfig(LTDC_HandleTypeDef *hltdc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hltdc); + + HAL_StatusTypeDef status; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + RCC_OscInitTypeDef rcc_oscinitstruct = {0}; + + /* LCD clock configuration */ + /* Typical PCLK is 25 MHz so the PLL3R is configured to provide this clock */ + /* LCD clock configuration */ + /* PLL3_VCO Input = HSI_VALUE/PLL3M = 64 Mhz / 4 = 16 */ + /* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 16 Mhz * 25 = 400 */ + /* PLLLCDCLK = PLL3_VCO Output/PLL3R = 400/16 = 25Mhz */ + /* LTDC clock frequency = PLLLCDCLK = 25 Mhz */ + rcc_oscinitstruct.PLL3.PLLState = RCC_PLL_ON; + rcc_oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + rcc_oscinitstruct.HSIState = RCC_HSI_ON; + rcc_oscinitstruct.HSIDiv = RCC_HSI_DIV1; + rcc_oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + rcc_oscinitstruct.PLL1.PLLState = RCC_PLL_NONE; + rcc_oscinitstruct.PLL2.PLLState = RCC_PLL_NONE; + rcc_oscinitstruct.PLL3.PLLSource = RCC_PLLSOURCE_HSI; + rcc_oscinitstruct.PLL3.PLLM = 4; + rcc_oscinitstruct.PLL3.PLLN = 25; + rcc_oscinitstruct.PLL3.PLLP = 2; + rcc_oscinitstruct.PLL3.PLLQ = 1; + rcc_oscinitstruct.PLL3.PLLR = 16; + rcc_oscinitstruct.PLL3.PLLS = 1; + rcc_oscinitstruct.PLL3.PLLT = 1; + rcc_oscinitstruct.PLL3.PLLFractional = 0; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC; + PeriphClkInitStruct.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R; + + if (HAL_RCC_OscConfig(&rcc_oscinitstruct) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + } + + return status; +} + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +/** + * @brief Default BSP LCD Msp Callbacks + * @param Instance BSP LCD Instance + * @retval BSP status + */ +int32_t BSP_LCD_RegisterDefaultMspCallbacks (uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPINIT_CB_ID, LTDC_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPDEINIT_CB_ID, LTDC_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + Lcd_Ctx[Instance].IsMspCallbacksValid = 1; + } + + return ret; +} + +/** + * @brief BSP LCD Msp Callback registering + * @param Instance LCD Instance + * @param CallBacks pointer to LCD MspInit/MspDeInit functions + * @retval BSP status + */ +int32_t BSP_LCD_RegisterMspCallbacks (uint32_t Instance, BSP_LCD_Cb_t *CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPINIT_CB_ID, CallBacks->pMspLtdcInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPDEINIT_CB_ID, CallBacks->pMspLtdcDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + Lcd_Ctx[Instance].IsMspCallbacksValid = 1; + } + + return ret; +} +#endif /*(USE_HAL_LTDC_REGISTER_CALLBACKS == 1) */ + +/** + * @brief LTDC layer configuration. + * @param Instance LCD instance + * @param LayerIndex Layer 0 or 1 + * @param Config Layer configuration + * @retval HAL status + */ +int32_t BSP_LCD_ConfigLayer(uint32_t Instance, uint32_t LayerIndex, BSP_LCD_LayerConfig_t *Config) +{ + int32_t ret = BSP_ERROR_NONE; + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (MX_LTDC_ConfigLayer(&hlcd_ltdc, LayerIndex, Config) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + return ret; +} + +/** + * @brief Gets the LCD Active LCD Pixel Format. + * @param Instance LCD Instance + * @param PixelFormat Active LCD Pixel Format + * @retval BSP status + */ +int32_t BSP_LCD_GetPixelFormat(uint32_t Instance, uint32_t *PixelFormat) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + *PixelFormat = Lcd_Ctx[Instance].PixelFormat; + } + + return ret; +} + +/** + * @brief Set the LCD Active Layer. + * @param Instance LCD Instance + * @param LayerIndex LCD layer index + * @retval BSP status + */ +int32_t BSP_LCD_SetActiveLayer(uint32_t Instance, uint32_t LayerIndex) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + Lcd_Ctx[Instance].ActiveLayer = LayerIndex; + } + + return ret; +} + +/** + * @brief Control the LTDC reload + * @param Instance LCD Instance + * @param ReloadType can be one of the following values + * - BSP_LCD_RELOAD_NONE + * - BSP_LCD_RELOAD_IMMEDIATE + * - BSP_LCD_RELOAD_VERTICAL_BLANKING + * @retval BSP status + */ +int32_t BSP_LCD_Reload(uint32_t Instance, uint32_t ReloadType) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (ReloadType == BSP_LCD_RELOAD_NONE) + { + Lcd_Ctx[Instance].ReloadEnable = 0U; + } + else if (HAL_LTDC_Reload (&hlcd_ltdc, ReloadType) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + Lcd_Ctx[Instance].ReloadEnable = 1U; + } + + return ret; +} + +/** + * @brief Sets an LCD Layer visible + * @param Instance LCD Instance + * @param LayerIndex Visible Layer + * @param State New state of the specified layer + * This parameter can be one of the following values: + * @arg ENABLE + * @arg DISABLE + * @retval BSP status + */ +int32_t BSP_LCD_SetLayerVisible(uint32_t Instance, uint32_t LayerIndex, FunctionalState State) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (State == ENABLE) + { + __HAL_LTDC_LAYER_ENABLE(&hlcd_ltdc, LayerIndex); + } + else + { + __HAL_LTDC_LAYER_DISABLE(&hlcd_ltdc, LayerIndex); + } + + if (Lcd_Ctx[Instance].ReloadEnable == 1U) + { + __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hlcd_ltdc); + } + } + + return ret; +} + +/** + * @brief Configures the transparency. + * @param Instance LCD Instance + * @param LayerIndex Layer foreground or background. + * @param Transparency Transparency + * This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF + * @retval BSP status + */ +int32_t BSP_LCD_SetTransparency(uint32_t Instance, uint32_t LayerIndex, uint8_t Transparency) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Lcd_Ctx[Instance].ReloadEnable == 1U) + { + (void)HAL_LTDC_SetAlpha(&hlcd_ltdc, Transparency, LayerIndex); + } + else + { + (void)HAL_LTDC_SetAlpha_NoReload(&hlcd_ltdc, Transparency, LayerIndex); + } + } + + return ret; +} + +/** + * @brief Sets an LCD layer frame buffer address. + * @param Instance LCD Instance + * @param LayerIndex Layer foreground or background + * @param Address New LCD frame buffer value + * @retval BSP status + */ +int32_t BSP_LCD_SetLayerAddress(uint32_t Instance, uint32_t LayerIndex, uint32_t Address) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Lcd_Ctx[Instance].ReloadEnable == 1U) + { + (void)HAL_LTDC_SetAddress(&hlcd_ltdc, Address, LayerIndex); + } + else + { + (void)HAL_LTDC_SetAddress_NoReload(&hlcd_ltdc, Address, LayerIndex); + } + } + + return ret; +} + +/** + * @brief Sets display window. + * @param Instance LCD Instance + * @param LayerIndex Layer index + * @param Xpos LCD X position + * @param Ypos LCD Y position + * @param Width LCD window width + * @param Height LCD window height + * @retval BSP status + */ +int32_t BSP_LCD_SetLayerWindow(uint32_t Instance, uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Lcd_Ctx[Instance].ReloadEnable == 1U) + { + /* Reconfigure the layer size and position */ + (void)HAL_LTDC_SetWindowSize(&hlcd_ltdc, Width, Height, LayerIndex); + (void)HAL_LTDC_SetWindowPosition(&hlcd_ltdc, Xpos, Ypos, LayerIndex); + } + else + { + /* Reconfigure the layer size and position */ + (void)HAL_LTDC_SetWindowSize_NoReload(&hlcd_ltdc, Width, Height, LayerIndex); + (void)HAL_LTDC_SetWindowPosition_NoReload(&hlcd_ltdc, Xpos, Ypos, LayerIndex); + } + + Lcd_Ctx[Instance].XSize = Width; + Lcd_Ctx[Instance].YSize = Height; + } + + return ret; +} + +/** + * @brief Configures and sets the color keying. + * @param Instance LCD Instance + * @param LayerIndex Layer foreground or background + * @param Color Color reference + * @retval BSP status + */ +int32_t BSP_LCD_SetColorKeying(uint32_t Instance, uint32_t LayerIndex, uint32_t Color) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Lcd_Ctx[Instance].ReloadEnable == 1U) + { + /* Configure and Enable the color Keying for LCD Layer */ + (void)HAL_LTDC_ConfigColorKeying(&hlcd_ltdc, Color, LayerIndex); + (void)HAL_LTDC_EnableColorKeying(&hlcd_ltdc, LayerIndex); + } + else + { + /* Configure and Enable the color Keying for LCD Layer */ + (void)HAL_LTDC_ConfigColorKeying_NoReload(&hlcd_ltdc, Color, LayerIndex); + (void)HAL_LTDC_EnableColorKeying_NoReload(&hlcd_ltdc, LayerIndex); + } + } + + return ret; +} + +/** + * @brief Disables the color keying. + * @param Instance LCD Instance + * @param LayerIndex Layer foreground or background + * @retval BSP status + */ +int32_t BSP_LCD_ResetColorKeying(uint32_t Instance, uint32_t LayerIndex) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Lcd_Ctx[Instance].ReloadEnable == 1U) + { + /* Disable the color Keying for LCD Layer */ + (void)HAL_LTDC_DisableColorKeying(&hlcd_ltdc, LayerIndex); + } + else + { + /* Disable the color Keying for LCD Layer */ + (void)HAL_LTDC_DisableColorKeying_NoReload(&hlcd_ltdc, LayerIndex); + } + } + + return ret; +} + +/** + * @brief Gets the LCD X size. + * @param Instance LCD Instance + * @param XSize LCD width + * @retval BSP status + */ +int32_t BSP_LCD_GetXSize(uint32_t Instance, uint32_t *XSize) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + *XSize = Lcd_Ctx[Instance].XSize; + } + + return ret; +} + +/** + * @brief Gets the LCD Y size. + * @param Instance LCD Instance + * @param YSize LCD Height + * @retval BSP status + */ +int32_t BSP_LCD_GetYSize(uint32_t Instance, uint32_t *YSize) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + *YSize = Lcd_Ctx[Instance].YSize; + } + + return ret; +} + +/** + * @brief Switch On the display. + * @param Instance LCD Instance + * @retval BSP status + */ +int32_t BSP_LCD_DisplayOn(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure = {0}; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + __HAL_LTDC_ENABLE(&hlcd_ltdc); + gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Pin = LCD_DISP_EN_PIN; + HAL_GPIO_Init(LCD_DISP_EN_GPIO_PORT, &gpio_init_structure); + + /* Assert LCD_DISP_EN pin */ + HAL_GPIO_WritePin(LCD_DISP_EN_GPIO_PORT, LCD_DISP_EN_PIN, GPIO_PIN_SET); + } + + return ret; +} + +/** + * @brief Switch Off the display. + * @param Instance LCD Instance + * @retval BSP status + */ +int32_t BSP_LCD_DisplayOff(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure = {0}; + + if (Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM; + gpio_init_structure.Pin = LCD_DISP_EN_PIN; + HAL_GPIO_Init(LCD_DISP_EN_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM; + gpio_init_structure.Pin = LCD_BL_CTRL_PIN; + HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure); + + /* Assert LCD_DISP_EN pin */ + HAL_GPIO_WritePin(LCD_DISP_EN_GPIO_PORT, LCD_DISP_EN_PIN, GPIO_PIN_RESET); + + __HAL_LTDC_DISABLE(&hlcd_ltdc); + + } + + return ret; +} + +/** + * @brief Set the brightness value + * @param Instance LCD Instance + * @param Brightness [00: Min (black), 100 Max] + * @retval BSP status + */ +int32_t BSP_LCD_SetBrightness(uint32_t Instance, uint32_t Brightness) +{ + int32_t ret = BSP_ERROR_NONE; + + if(Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + hlcd_lptim_config.Pulse = ((uint32_t) (LCD_LPTIMX_PERIOD_VALUE +1U) * Brightness / 100U) - 1U; + (void)HAL_LPTIM_OC_ConfigChannel(&hlcd_lptim, &hlcd_lptim_config, LPTIM_CHANNEL_2); + Lcd_Ctx[Instance].Brightness = Brightness; + } + + return ret; +} + +/** + * @brief Set the brightness value + * @param Instance LCD Instance + * @param Brightness [00: Min (black), 100 Max] + * @retval BSP status + */ +int32_t BSP_LCD_GetBrightness(uint32_t Instance, uint32_t *Brightness) +{ + int32_t ret = BSP_ERROR_NONE; + + if(Instance >= LCD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + *Brightness = Lcd_Ctx[Instance].Brightness; + } + + return ret; +} + +/** + * @brief Draws a bitmap picture loaded in the internal Flash in currently active layer. + * @param Instance LCD Instance + * @param Xpos Bmp X position in the LCD + * @param Ypos Bmp Y position in the LCD + * @param pBmp Pointer to Bmp picture address in the internal Flash. + * @retval BSP status + */ +int32_t BSP_LCD_DrawBitmap(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint8_t *pBmp) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t index, width, height, bit_pixel; + uint32_t Address; + uint32_t input_color_mode; + uint8_t *pbmp; + + /* Get bitmap data address offset */ + index = (uint32_t)pBmp[10] + ((uint32_t)pBmp[11] << 8) + ((uint32_t)pBmp[12] << 16) + ((uint32_t)pBmp[13] << 24); + + /* Read bitmap width */ + width = (uint32_t)pBmp[18] + ((uint32_t)pBmp[19] << 8) + ((uint32_t)pBmp[20] << 16) + ((uint32_t)pBmp[21] << 24); + + /* Read bitmap height */ + height = (uint32_t)pBmp[22] + ((uint32_t)pBmp[23] << 8) + ((uint32_t)pBmp[24] << 16) + ((uint32_t)pBmp[25] << 24); + + /* Read bit/pixel */ + bit_pixel = (uint32_t)pBmp[28] + ((uint32_t)pBmp[29] << 8); + + /* Set the address */ + Address = hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (((Lcd_Ctx[Instance].XSize*Ypos) + Xpos)*Lcd_Ctx[Instance].BppFactor); + + /* Get the layer pixel format */ + if ((bit_pixel/8U) == 4U) + { + input_color_mode = DMA2D_INPUT_ARGB8888; + } + else if ((bit_pixel/8U) == 2U) + { + input_color_mode = DMA2D_INPUT_RGB565; + } + else + { + input_color_mode = DMA2D_INPUT_RGB888; + } + + /* Bypass the bitmap header */ + pbmp = pBmp + (index + (width * (height - 1U) * (bit_pixel/8U))); + + /* Convert picture to ARGB8888 pixel format */ + for(index=0; index < height; index++) + { + /* Pixel format conversion */ + LL_ConvertLineToRGB(Instance, (uint32_t *)pbmp, (uint32_t *)Address, width, input_color_mode); + + /* Increment the source and destination buffers */ + Address+= (Lcd_Ctx[Instance].XSize * Lcd_Ctx[Instance].BppFactor); + pbmp -= width*(bit_pixel/8U); + } + + return ret; +} + +/** + * @brief Draw a horizontal line on LCD. + * @param Instance LCD Instance. + * @param Xpos X position. + * @param Ypos Y position. + * @param pData Pointer to RGB line data + * @param Width Rectangle width. + * @param Height Rectangle Height. + * @retval BSP status. + */ +int32_t BSP_LCD_FillRGBRect(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint8_t *pData, uint32_t Width, uint32_t Height) +{ + uint32_t i; + uint8_t *pdata = pData; + +#if (USE_DMA2D_TO_FILL_RGB_RECT == 1) + uint32_t Xaddress; + for(i = 0; i < Height; i++) + { + /* Get the line address */ + Xaddress = hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (Lcd_Ctx[Instance].BppFactor*((Lcd_Ctx[Instance].XSize*(Ypos + i)) + Xpos)); + +#if (USE_BSP_CPU_CACHE_MAINTENANCE == 1) + SCB_CleanDCache_by_Addr((uint32_t *)pdata, Lcd_Ctx[Instance].BppFactor*Lcd_Ctx[Instance].XSize); +#endif /* USE_BSP_CPU_CACHE_MAINTENANCE */ + + /* Write line */ + if (Lcd_Ctx[Instance].PixelFormat == LCD_PIXEL_FORMAT_RGB565) + { + LL_ConvertLineToRGB(Instance, (uint32_t *)pdata, (uint32_t *)Xaddress, Width, DMA2D_INPUT_RGB565); + } + else + { + LL_ConvertLineToRGB(Instance, (uint32_t *)pdata, (uint32_t *)Xaddress, Width, DMA2D_INPUT_ARGB8888); + } + pdata += Lcd_Ctx[Instance].BppFactor*Width; + } +#else + uint32_t color, j; + for(i = 0; i < Height; i++) + { + for(j = 0; j < Width; j++) + { + color = (uint32_t)((uint32_t)*pdata | ((uint32_t)(*(pdata + 1U)) << 8U) | ((uint32_t)(*(pdata + 2U)) << 16U) | ((uint32_t)(*(pdata + 3U)) << 24U)); + (void)BSP_LCD_WritePixel(Instance, Xpos + j, Ypos + i, color); + pdata += Lcd_Ctx[Instance].BppFactor; + } + } +#endif + + return BSP_ERROR_NONE; +} + +/** + * @brief Draws an horizontal line in currently active layer. + * @param Instance LCD Instance + * @param Xpos X position + * @param Ypos Y position + * @param Length Line length + * @param Color RGB color + * @retval BSP status + */ +int32_t BSP_LCD_DrawHLine(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color) +{ + uint32_t Xaddress; + + /* Get the line address */ + Xaddress = hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (Lcd_Ctx[Instance].BppFactor*((Lcd_Ctx[Instance].XSize*Ypos) + Xpos)); + + /* Write line */ + LL_FillBuffer(Instance, (uint32_t *)Xaddress, Length, 1, 0, Color); + + return BSP_ERROR_NONE; +} + +/** + * @brief Draws a vertical line in currently active layer. + * @param Instance LCD Instance + * @param Xpos X position + * @param Ypos Y position + * @param Length Line length + * @param Color RGB color + * @retval BSP status + */ +int32_t BSP_LCD_DrawVLine(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color) +{ + uint32_t Xaddress; + + /* Get the line address */ + Xaddress = (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress) + (Lcd_Ctx[Instance].BppFactor*((Lcd_Ctx[Instance].XSize*Ypos) + Xpos)); + + /* Write line */ + LL_FillBuffer(Instance, (uint32_t *)Xaddress, 1, Length, (Lcd_Ctx[Instance].XSize - 1U), Color); + + return BSP_ERROR_NONE; +} + +/** + * @brief Draws a full rectangle in currently active layer. + * @param Instance LCD Instance + * @param Xpos X position + * @param Ypos Y position + * @param Width Rectangle width + * @param Height Rectangle height + * @param Color RGB color + * @retval BSP status + */ +int32_t BSP_LCD_FillRect(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height, uint32_t Color) +{ + uint32_t Xaddress; + + /* Get the rectangle start address */ + Xaddress = (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress) + (Lcd_Ctx[Instance].BppFactor*((Lcd_Ctx[Instance].XSize*Ypos) + Xpos)); + + /* Fill the rectangle */ + LL_FillBuffer(Instance, (uint32_t *)Xaddress, Width, Height, (Lcd_Ctx[Instance].XSize - Width), Color); + + return BSP_ERROR_NONE; +} + +/** + * @brief Reads a LCD pixel. + * @param Instance LCD Instance + * @param Xpos X position + * @param Ypos Y position + * @param Color RGB pixel color + * @retval BSP status + */ +int32_t BSP_LCD_ReadPixel(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t *Color) +{ + if (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) + { + /* Read data value from RAM memory */ + *Color = *(__IO uint32_t*) (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (4U*((Ypos*Lcd_Ctx[Instance].XSize) + Xpos))); + } + else /* if ((hlcd_ltdc.LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) */ + { + /* Read data value from RAM memory */ + *Color = *(__IO uint16_t*) (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (2U*((Ypos*Lcd_Ctx[Instance].XSize) + Xpos))); + } + + return BSP_ERROR_NONE; +} + +/** + * @brief Draws a pixel on LCD. + * @param Instance LCD Instance + * @param Xpos X position + * @param Ypos Y position + * @param Color Pixel color + * @retval BSP status + */ +int32_t BSP_LCD_WritePixel(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Color) +{ + if (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) + { + /* Write data value to RAM memory */ + *(__IO uint32_t*) (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (4U*((Ypos*Lcd_Ctx[Instance].XSize) + Xpos))) = Color; + } + else + { + /* Write data value to RAM memory */ + *(__IO uint16_t*) (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (2U*((Ypos*Lcd_Ctx[Instance].XSize) + Xpos))) = (uint16_t)Color; + } + + return BSP_ERROR_NONE; +} + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LCD_Private_Functions STM32H7S78_DK LCD Private Functions + * @{ + */ +/** + * @brief Fills a buffer. + * @param Instance LCD Instance + * @param pDst Pointer to destination buffer + * @param xSize Buffer width + * @param ySize Buffer height + * @param OffLine Offset + * @param Color RGB color + */ +static void LL_FillBuffer(uint32_t Instance, uint32_t *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t Color) +{ + uint32_t output_color_mode, input_color = Color; + + switch(Lcd_Ctx[Instance].PixelFormat) + { + case LCD_PIXEL_FORMAT_RGB565: + output_color_mode = DMA2D_OUTPUT_RGB565; /* RGB565 */ + input_color = CONVERTRGB5652ARGB8888(Color); + break; + case LCD_PIXEL_FORMAT_RGB888: + default: + output_color_mode = DMA2D_OUTPUT_ARGB8888; /* ARGB8888 */ + break; + } + + /* Register to memory mode with ARGB8888 as color Mode */ + hlcd_dma2d.Init.Mode = DMA2D_R2M; + hlcd_dma2d.Init.ColorMode = output_color_mode; + hlcd_dma2d.Init.OutputOffset = OffLine; + + hlcd_dma2d.Instance = DMA2D; + + /* DMA2D Initialization */ + if (HAL_DMA2D_Init(&hlcd_dma2d) == HAL_OK) + { + if (HAL_DMA2D_Start(&hlcd_dma2d, input_color, (uint32_t)pDst, xSize, ySize) == HAL_OK) + { + /* Polling For DMA transfer */ + (void)HAL_DMA2D_PollForTransfer(&hlcd_dma2d, 50); + } + } +} + +/** + * @brief Converts a line to an RGB pixel format. + * @param Instance LCD Instance + * @param pSrc Pointer to source buffer + * @param pDst Output color + * @param xSize Buffer width + * @param ColorMode Input color mode + */ +static void LL_ConvertLineToRGB(uint32_t Instance, uint32_t *pSrc, uint32_t *pDst, uint32_t xSize, uint32_t ColorMode) +{ + uint32_t output_color_mode; + + switch(Lcd_Ctx[Instance].PixelFormat) + { + case LCD_PIXEL_FORMAT_RGB565: + output_color_mode = DMA2D_OUTPUT_RGB565; /* RGB565 */ + break; + case LCD_PIXEL_FORMAT_RGB888: + default: + output_color_mode = DMA2D_OUTPUT_ARGB8888; /* ARGB8888 */ + break; + } + + /* Configure the DMA2D Mode, Color Mode and output offset */ + hlcd_dma2d.Init.Mode = DMA2D_M2M_PFC; + hlcd_dma2d.Init.ColorMode = output_color_mode; + hlcd_dma2d.Init.OutputOffset = 0; + + /* Foreground Configuration */ + hlcd_dma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; + hlcd_dma2d.LayerCfg[1].InputAlpha = 0xFF; + hlcd_dma2d.LayerCfg[1].InputColorMode = ColorMode; + hlcd_dma2d.LayerCfg[1].InputOffset = 0; + hlcd_dma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; + + hlcd_dma2d.Instance = DMA2D; + + /* DMA2D Initialization */ + if (HAL_DMA2D_Init(&hlcd_dma2d) == HAL_OK) + { + if (HAL_DMA2D_ConfigLayer(&hlcd_dma2d, 1) == HAL_OK) + { + if (HAL_DMA2D_Start(&hlcd_dma2d, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK) + { + /* Polling For DMA transfer */ + (void)HAL_DMA2D_PollForTransfer(&hlcd_dma2d, 50); + } + } + } +} + +/** + * @brief Initialize the BSP LTDC Msp. + * @param hltdc LTDC handle + * @retval None + */ +static void LTDC_MspInit(LTDC_HandleTypeDef *hltdc) +{ + GPIO_InitTypeDef gpio_init_structure; + + if (hltdc->Instance == LTDC) + { + __HAL_RCC_LTDC_CLK_ENABLE(); + + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + + /* Data */ + gpio_init_structure.Pin = GPIO_PIN_13 |GPIO_PIN_15; + gpio_init_structure.Alternate = GPIO_AF10_LTDC; + HAL_GPIO_Init(GPIOB, &gpio_init_structure); + + /* Data */ + gpio_init_structure.Pin = GPIO_PIN_3 |GPIO_PIN_4 | GPIO_PIN_10| GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_14; + gpio_init_structure.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOB, &gpio_init_structure); + + + gpio_init_structure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_8|GPIO_PIN_11 |GPIO_PIN_12| GPIO_PIN_15; + gpio_init_structure.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOA, &gpio_init_structure); + + + gpio_init_structure.Pin = GPIO_PIN_6; + gpio_init_structure.Alternate = GPIO_AF12_LTDC; + HAL_GPIO_Init(GPIOA, &gpio_init_structure); + + gpio_init_structure.Pin = GPIO_PIN_9|GPIO_PIN_10; + gpio_init_structure.Alternate = GPIO_AF14_LTDC; + HAL_GPIO_Init(GPIOA, &gpio_init_structure); + + + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_13|GPIO_PIN_14; + gpio_init_structure.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOG, &gpio_init_structure); + + /* VSYNC */ + gpio_init_structure.Pin = GPIO_PIN_11; + gpio_init_structure.Alternate = GPIO_AF11_LTDC; + HAL_GPIO_Init(GPIOE, &gpio_init_structure); + + gpio_init_structure.Pin = GPIO_PIN_0 ; + gpio_init_structure.Alternate = GPIO_AF11_LTDC; + HAL_GPIO_Init(GPIOF, &gpio_init_structure); + + gpio_init_structure.Pin = GPIO_PIN_10|GPIO_PIN_11; + gpio_init_structure.Alternate = GPIO_AF14_LTDC; + HAL_GPIO_Init(GPIOF , &gpio_init_structure); + + gpio_init_structure.Pin = GPIO_PIN_9 | GPIO_PIN_7 | GPIO_PIN_15; + gpio_init_structure.Alternate = GPIO_AF13_LTDC; + HAL_GPIO_Init(GPIOF , &gpio_init_structure); + + gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM; + gpio_init_structure.Pin = LCD_DISP_EN_PIN; + HAL_GPIO_Init(LCD_DISP_EN_GPIO_PORT, &gpio_init_structure); + + /** Toggle Sw reset of LTDC IP */ + __HAL_RCC_LTDC_FORCE_RESET(); + __HAL_RCC_LTDC_RELEASE_RESET(); + } +} + +/** + * @brief De-Initializes the BSP LTDC Msp + * @param hltdc LTDC handle + * @retval None + */ +static void LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc) +{ + GPIO_InitTypeDef gpio_init_structure; + + if (hltdc->Instance == LTDC) + { + /* LTDC Pins deactivation */ + /* GPIOA deactivation */ + gpio_init_structure.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_8|GPIO_PIN_11 |GPIO_PIN_12| GPIO_PIN_15 | GPIO_PIN_6 | GPIO_PIN_9|GPIO_PIN_10; + HAL_GPIO_DeInit(GPIOA, gpio_init_structure.Pin); + + /* GPIOB deactivation */ + gpio_init_structure.Pin = GPIO_PIN_13 | GPIO_PIN_15 | GPIO_PIN_3 |GPIO_PIN_4 | GPIO_PIN_10| GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14; + HAL_GPIO_DeInit(GPIOB, gpio_init_structure.Pin); + + /* GPIOE deactivation */ + gpio_init_structure.Pin = GPIO_PIN_11 | GPIO_PIN_15; + HAL_GPIO_DeInit(GPIOE, gpio_init_structure.Pin); + + /* GPIOF deactivation */ + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_10|GPIO_PIN_11 | GPIO_PIN_9 | GPIO_PIN_7 | GPIO_PIN_15; + HAL_GPIO_DeInit(GPIOF, gpio_init_structure.Pin); + + /* GPIOG deactivation */ + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2 | GPIO_PIN_13|GPIO_PIN_14; + HAL_GPIO_DeInit(GPIOG, gpio_init_structure.Pin); + + /** Force and let in reset state LTDC */ + __HAL_RCC_LTDC_FORCE_RESET(); + + /** Disable the LTDC */ + __HAL_RCC_LTDC_CLK_DISABLE(); + } +} + +/** + * @brief Initialize the BSP DMA2D Msp. + * @param hdma2d DMA2D handle + * @retval None + */ +static void DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d) +{ + if (hdma2d->Instance == DMA2D) + { + /** Enable the DMA2D clock */ + __HAL_RCC_DMA2D_CLK_ENABLE(); + + /** Toggle Sw reset of DMA2D IP */ + __HAL_RCC_DMA2D_FORCE_RESET(); + __HAL_RCC_DMA2D_RELEASE_RESET(); + } +} + +/** + * @brief De-Initializes the BSP DMA2D Msp + * @param hdma2d DMA2D handle + * @retval None + */ +static void DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d) +{ + if (hdma2d->Instance == DMA2D) + { + /** Disable IRQ of DMA2D IP */ + HAL_NVIC_DisableIRQ(DMA2D_IRQn); + + /** Force and let in reset state DMA2D */ + __HAL_RCC_DMA2D_FORCE_RESET(); + + /** Disable the DMA2D */ + __HAL_RCC_DMA2D_CLK_DISABLE(); + } +} + +/** + * @brief Initializes TIM MSP. + * @param hlptim LPTIM handle + * @retval None + */ +static void LPTIMx_PWM_MspInit(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + GPIO_InitTypeDef gpio_init_structure; + + LCD_BL_CTRL_GPIO_CLK_ENABLE(); + + /* LPTIMx Peripheral clock enable */ + LCD_LPTIMx_CLK_ENABLE(); + + /* Timer channel configuration */ + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM; + gpio_init_structure.Alternate = LCD_LPTIMx_CHANNEL_AF; + gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* BL_CTRL */ + + HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure); +} + +/** + * @brief De-Initializes LPTIM MSP. + * @param hlptim LPTIM handle + * @retval None + */ +static void LPTIMx_PWM_MspDeInit(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + GPIO_InitTypeDef gpio_init_structure; + + /* LPTIMx Peripheral clock disable */ + LCD_BL_CTRL_GPIO_CLK_DISABLE(); + + /* LPTimer channel configuration */ + gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* BL_CTRL */ + HAL_GPIO_DeInit(LCD_BL_CTRL_GPIO_PORT, gpio_init_structure.Pin); +} + +/** + * @brief Initializes LPTIM in PWM mode + * @param hlptim LPTIM handle + * @retval None + */ +static void LPTIMx_PWM_Init(LPTIM_HandleTypeDef *hlptim) +{ + LPTIMx_PWM_MspInit(hlptim); + + hlptim->Instance = LCD_LPTIMx; + (void)HAL_LPTIM_DeInit(hlptim); + + hlptim->Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; + hlptim->Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; + hlptim->Init.Clock.Source = LCD_LPTIMX_CLOCK_SOURCE; + hlptim->Init.Clock.Prescaler = LCD_LPTIMX_PRESCALER_VALUE; + hlptim->Init.UltraLowPowerClock.SampleTime = LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION; + hlptim->Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE; + hlptim->Init.Trigger.ActiveEdge = LPTIM_ACTIVEEDGE_RISING; + hlptim->Init.Trigger.SampleTime = LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION; + hlptim->Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO; + hlptim->Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO; + hlptim->Init.Period = LCD_LPTIMX_PERIOD_VALUE; + hlptim->Init.RepetitionCounter = 0; + hlptim->Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING; + + (void)HAL_LPTIM_Init(hlptim); + + hlcd_lptim_config.Pulse = LCD_LPTIMX_PULSE_VALUE; + hlcd_lptim_config.OCPolarity = LPTIM_OCPOLARITY_LOW; + (void)HAL_LPTIM_OC_ConfigChannel(hlptim, &hlcd_lptim_config, LPTIM_CHANNEL_2); + Lcd_Ctx[0].Brightness = LCD_BRIGHTNESS_DEFAULT_VALUE; + (void)HAL_LPTIM_PWM_Start(hlptim, LPTIM_CHANNEL_2); +} + +/** + * @brief De-Initializes LPTIM + * @param hlptim LPTIM handle + * @retval None + */ +static void LPTIMx_PWM_DeInit(LPTIM_HandleTypeDef *hlptim) +{ + hlptim->Instance = LCD_LPTIMx; + + /* Timer de-intialization */ + (void)HAL_LPTIM_DeInit(hlptim); + + /* Timer Msp de-intialization */ + LPTIMx_PWM_MspDeInit(hlptim); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.h new file mode 100644 index 0000000..c83f2a4 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_lcd.h @@ -0,0 +1,299 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_lcd.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32h7s78_discovery_lcd.c driver. + ****************************************************************************** + * @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 STM32H7S78_DISCOVERY_LCD_H +#define STM32H7S78_DISCOVERY_LCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" + + +#ifndef USE_LCD_CTRL_RK050HR18 +#define USE_LCD_CTRL_RK050HR18 1U +#endif + +#if (USE_LCD_CTRL_RK050HR18 == 1) +/* Include RK050HR18 LCD Driver IC driver code */ +#include "../Components/rk050hr18/rk050hr18.h" +#endif +#include "../Components/Common/lcd.h" +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup STM32H7S78_DK_LCD + * @{ + */ + +/** @defgroup STM32H7S78_DK_LCD_Exported_Constants STM32H7S78_DK LCD Exported Constants + * @{ + */ +#define LCD_INSTANCES_NBR 1U + +#define LCD_ORIENTATION_LANDSCAPE 0x01U /* Landscape orientation choice of LCD screen */ + +#define LCD_DEFAULT_WIDTH 800 +#define LCD_DEFAULT_HEIGHT 480 + +#define BSP_LCD_RELOAD_NONE 0U /* No reload executed */ +#define BSP_LCD_RELOAD_IMMEDIATE LTDC_RELOAD_IMMEDIATE /* Immediate Reload */ +#define BSP_LCD_RELOAD_VERTICAL_BLANKING LTDC_RELOAD_VERTICAL_BLANKING /* Vertical Blanking Reload */ +/** + * @brief LCD special pins + */ +/* LCD display enable pin */ +#define LCD_DISP_EN_PIN GPIO_PIN_15 +#define LCD_DISP_EN_GPIO_PORT GPIOE +#define LCD_DISP_EN_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define LCD_DISP_EN_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() + +/* LCD BackLight control pin */ +#define LCD_BL_CTRL_PIN GPIO_PIN_15 +#define LCD_BL_CTRL_GPIO_PORT GPIOG +#define LCD_BL_CTRL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define LCD_BL_CTRL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE() + +/* LCD Brightness default value */ +#define LCD_BRIGHTNESS_DEFAULT_VALUE 50U + +/*LCD LPTimer brightness control parameters */ +#define LCD_LPTIMx LPTIM1 +#define LCD_LPTIMx_CLK_ENABLE() __HAL_RCC_LPTIM1_CLK_ENABLE() +#define LCD_LPTIMx_CLK_DISABLE() __HAL_RCC_LPTIM1_CLK_DISABLE() +#define LCD_LPTIMx_CHANNEL TIM_CHANNEL_2 +#define LCD_LPTIMx_CHANNEL_AF GPIO_AF1_LPTIM1 +#define LCD_LPTIMX_PERIOD_VALUE ((uint32_t)10000) /* Period Value */ +#define LCD_LPTIMX_PULSE_VALUE (((uint32_t)(LCD_LPTIMX_PERIOD_VALUE +1U)*LCD_BRIGHTNESS_DEFAULT_VALUE/100U)-1U) +#define LCD_LPTIMX_PRESCALER_VALUE LPTIM_PRESCALER_DIV1 /* Prescaler divider Value */ +#define LCD_LPTIMX_CLOCK_SOURCE LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC /* internal clock source */ + +/* RGB565 colors definitions */ +#define LCD_COLOR_RGB565_BLUE 0x001FU +#define LCD_COLOR_RGB565_GREEN 0x07E0U +#define LCD_COLOR_RGB565_RED 0xF800U +#define LCD_COLOR_RGB565_CYAN 0x07FFU +#define LCD_COLOR_RGB565_MAGENTA 0xF81FU +#define LCD_COLOR_RGB565_YELLOW 0xFFE0U +#define LCD_COLOR_RGB565_LIGHTBLUE 0x841FU +#define LCD_COLOR_RGB565_LIGHTGREEN 0x87F0U +#define LCD_COLOR_RGB565_LIGHTRED 0xFC10U +#define LCD_COLOR_RGB565_LIGHTCYAN 0x87FFU +#define LCD_COLOR_RGB565_LIGHTMAGENTA 0xFC1FU +#define LCD_COLOR_RGB565_LIGHTYELLOW 0xFFF0U +#define LCD_COLOR_RGB565_DARKBLUE 0x0010U +#define LCD_COLOR_RGB565_DARKGREEN 0x0400U +#define LCD_COLOR_RGB565_DARKRED 0x8000U +#define LCD_COLOR_RGB565_DARKCYAN 0x0410U +#define LCD_COLOR_RGB565_DARKMAGENTA 0x8010U +#define LCD_COLOR_RGB565_DARKYELLOW 0x8400U +#define LCD_COLOR_RGB565_WHITE 0xFFFFU +#define LCD_COLOR_RGB565_LIGHTGRAY 0xD69AU +#define LCD_COLOR_RGB565_GRAY 0x8410U +#define LCD_COLOR_RGB565_DARKGRAY 0x4208U +#define LCD_COLOR_RGB565_BLACK 0x0000U +#define LCD_COLOR_RGB565_BROWN 0xA145U +#define LCD_COLOR_RGB565_ORANGE 0xFD20U +/* Definition of Official ST COLOR */ +#define LCD_COLOR_RGB565_ST_BLUE_DARK 0x0001U +#define LCD_COLOR_RGB565_ST_BLUE 0x01EBU +#define LCD_COLOR_RGB565_ST_BLUE_LIGHT 0x06A7U +#define LCD_COLOR_RGB565_ST_GREEN_LIGHT 0x05ECU +#define LCD_COLOR_RGB565_ST_GREEN_DARK 0x001CU +#define LCD_COLOR_RGB565_ST_YELLOW 0x07F0U +#define LCD_COLOR_RGB565_ST_BROWN 0x02C8U +#define LCD_COLOR_RGB565_ST_PINK 0x0681U +#define LCD_COLOR_RGB565_ST_PURPLE 0x02CDU +#define LCD_COLOR_RGB565_ST_GRAY_DARK 0x0251U +#define LCD_COLOR_RGB565_ST_GRAY 0x04BAU +#define LCD_COLOR_RGB565_ST_GRAY_LIGHT 0x05E7U + +/* ARGB8888 colors definitions */ +#define LCD_COLOR_ARGB8888_BLUE 0xFF0000FFUL +#define LCD_COLOR_ARGB8888_GREEN 0xFF00FF00UL +#define LCD_COLOR_ARGB8888_RED 0xFFFF0000UL +#define LCD_COLOR_ARGB8888_CYAN 0xFF00FFFFUL +#define LCD_COLOR_ARGB8888_MAGENTA 0xFFFF00FFUL +#define LCD_COLOR_ARGB8888_YELLOW 0xFFFFFF00UL +#define LCD_COLOR_ARGB8888_LIGHTBLUE 0xFF8080FFUL +#define LCD_COLOR_ARGB8888_LIGHTGREEN 0xFF80FF80UL +#define LCD_COLOR_ARGB8888_LIGHTRED 0xFFFF8080UL +#define LCD_COLOR_ARGB8888_LIGHTCYAN 0xFF80FFFFUL +#define LCD_COLOR_ARGB8888_LIGHTMAGENTA 0xFFFF80FFUL +#define LCD_COLOR_ARGB8888_LIGHTYELLOW 0xFFFFFF80UL +#define LCD_COLOR_ARGB8888_DARKBLUE 0xFF000080UL +#define LCD_COLOR_ARGB8888_DARKGREEN 0xFF008000UL +#define LCD_COLOR_ARGB8888_DARKRED 0xFF800000UL +#define LCD_COLOR_ARGB8888_DARKCYAN 0xFF008080UL +#define LCD_COLOR_ARGB8888_DARKMAGENTA 0xFF800080UL +#define LCD_COLOR_ARGB8888_DARKYELLOW 0xFF808000UL +#define LCD_COLOR_ARGB8888_WHITE 0xFFFFFFFFUL +#define LCD_COLOR_ARGB8888_LIGHTGRAY 0xFFD3D3D3UL +#define LCD_COLOR_ARGB8888_GRAY 0xFF808080UL +#define LCD_COLOR_ARGB8888_DARKGRAY 0xFF404040UL +#define LCD_COLOR_ARGB8888_BLACK 0xFF000000UL +#define LCD_COLOR_ARGB8888_BROWN 0xFFA52A2AUL +#define LCD_COLOR_ARGB8888_ORANGE 0xFFFFA500UL +/* Definition of Official ST Colors */ +#define LCD_COLOR_ARGB8888_ST_BLUE_DARK 0xFF002052UL +#define LCD_COLOR_ARGB8888_ST_BLUE 0xFF39A9DCUL +#define LCD_COLOR_ARGB8888_ST_BLUE_LIGHT 0xFFD1E4F3UL +#define LCD_COLOR_ARGB8888_ST_GREEN_LIGHT 0xFFBBCC01UL +#define LCD_COLOR_ARGB8888_ST_GREEN_DARK 0xFF003D14UL +#define LCD_COLOR_ARGB8888_ST_YELLOW 0xFFFFD300UL +#define LCD_COLOR_ARGB8888_ST_BROWN 0xFF5C0915UL +#define LCD_COLOR_ARGB8888_ST_PINK 0xFFD4007AUL +#define LCD_COLOR_ARGB8888_ST_PURPLE 0xFF590D58UL +#define LCD_COLOR_ARGB8888_ST_GRAY_DARK 0xFF4F5251UL +#define LCD_COLOR_ARGB8888_ST_GRAY 0xFF90989EUL +#define LCD_COLOR_ARGB8888_ST_GRAY_LIGHT 0xFFB9C4CAUL +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_LCD_Exported_Types STM32H7S78_DK LCD Exported Types + * @{ + */ +typedef struct +{ + uint32_t XSize; + uint32_t YSize; + uint32_t ActiveLayer; + uint32_t PixelFormat; + uint32_t BppFactor; + uint32_t IsMspCallbacksValid; + uint32_t ReloadEnable; + uint32_t Brightness; +} BSP_LCD_Ctx_t; + +typedef struct +{ + uint32_t X0; + uint32_t X1; + uint32_t Y0; + uint32_t Y1; + uint32_t PixelFormat; + uint32_t Address; +} MX_LTDC_LayerConfig_t; + +#define BSP_LCD_LayerConfig_t MX_LTDC_LayerConfig_t + + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +typedef struct +{ + pLTDC_CallbackTypeDef pMspLtdcInitCb; + pLTDC_CallbackTypeDef pMspLtdcDeInitCb; +} BSP_LCD_Cb_t; +#endif /*(USE_HAL_LTDC_REGISTER_CALLBACKS == 1) */ +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_LCD_Exported_Variables + * @{ + */ +extern DMA2D_HandleTypeDef hlcd_dma2d; +extern LTDC_HandleTypeDef hlcd_ltdc; +extern BSP_LCD_Ctx_t Lcd_Ctx[LCD_INSTANCES_NBR]; +extern const LCD_UTILS_Drv_t LCD_Driver; +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_LCD_Exported_Functions + * @{ + */ +/* Initialization APIs */ +int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation); +int32_t BSP_LCD_InitEx(uint32_t Instance, uint32_t Orientation, uint32_t PixelFormat, uint32_t Width, uint32_t Height); +int32_t BSP_LCD_DeInit(uint32_t Instance); + +/* Register Callbacks APIs */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +int32_t BSP_LCD_RegisterDefaultMspCallbacks(uint32_t Instance); +int32_t BSP_LCD_RegisterMspCallbacks(uint32_t Instance, BSP_LCD_Cb_t *CallBacks); +#endif /*(USE_HAL_LTDC_REGISTER_CALLBACKS == 1) */ + +/* LCD specific APIs: Layer control & LCD HW reset */ +int32_t BSP_LCD_Reload(uint32_t Instance, uint32_t ReloadType); +int32_t BSP_LCD_ConfigLayer(uint32_t Instance, uint32_t LayerIndex, BSP_LCD_LayerConfig_t *Config); +int32_t BSP_LCD_SetLayerVisible(uint32_t Instance, uint32_t LayerIndex, FunctionalState State); +int32_t BSP_LCD_SetTransparency(uint32_t Instance, uint32_t LayerIndex, uint8_t Transparency); +int32_t BSP_LCD_SetLayerAddress(uint32_t Instance, uint32_t LayerIndex, uint32_t Address); +int32_t BSP_LCD_SetLayerWindow(uint32_t Instance, uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); +int32_t BSP_LCD_SetColorKeying(uint32_t Instance, uint32_t LayerIndex, uint32_t Color); +int32_t BSP_LCD_ResetColorKeying(uint32_t Instance, uint32_t LayerIndex); + +/* LCD generic APIs: Display control */ +int32_t BSP_LCD_DisplayOn(uint32_t Instance); +int32_t BSP_LCD_DisplayOff(uint32_t Instance); +int32_t BSP_LCD_SetBrightness(uint32_t Instance, uint32_t Brightness); +int32_t BSP_LCD_GetBrightness(uint32_t Instance, uint32_t *Brightness); +int32_t BSP_LCD_GetXSize(uint32_t Instance, uint32_t *XSize); +int32_t BSP_LCD_GetYSize(uint32_t Instance, uint32_t *YSize); + +/* LCD generic APIs: Draw operations. This list of APIs is required for + lcd gfx utilities */ +int32_t BSP_LCD_SetActiveLayer(uint32_t Instance, uint32_t LayerIndex); +int32_t BSP_LCD_GetPixelFormat(uint32_t Instance, uint32_t *PixelFormat); +int32_t BSP_LCD_DrawBitmap(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint8_t *pBmp); +int32_t BSP_LCD_DrawHLine(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color); +int32_t BSP_LCD_DrawVLine(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color); +int32_t BSP_LCD_FillRGBRect(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint8_t *pData, uint32_t Width, uint32_t Height); +int32_t BSP_LCD_FillRect(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height, uint32_t Color); +int32_t BSP_LCD_ReadPixel(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t *Color); +int32_t BSP_LCD_WritePixel(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Color); + +/* LCD MX APIs */ +HAL_StatusTypeDef MX_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, uint32_t LayerIndex, MX_LTDC_LayerConfig_t *Config); +HAL_StatusTypeDef MX_LTDC_ClockConfig(LTDC_HandleTypeDef *hltdc); +HAL_StatusTypeDef MX_LTDC_Init(LTDC_HandleTypeDef *hltdc, uint32_t Width, uint32_t Height); + +/** + * @} + */ + +/* Private constants --------------------------------------------------------*/ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_LCD_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.c new file mode 100644 index 0000000..012b873 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.c @@ -0,0 +1,925 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_sd.c + * @author MCD Application Team + * @brief This file includes the uSD card driver mounted on STM32H7S78_DK + * boards. + ****************************************************************************** + * @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 is used to drive the micro SD external card mounted on the + STM32H7S78_DK board. + - This driver does not need a specific component driver for the micro SD device + to be included with. + + Driver description: + ------------------ + + Initialization steps: + o Initialize the micro SD card using the BSP_SD_Init() function. This + function includes the MSP layer hardware resources initialization and the + SDIO interface configuration to interface with the external micro SD. It + also includes the micro SD initialization sequence for instance 0. + + o To check the SD card presence you can use the function BSP_SD_IsDetected() which + returns the detection status for instance 0. + + o If SD presence detection interrupt mode is desired, you must configure the + SD detection interrupt mode by calling the function BSP_SD_DetectITConfig(). + The interrupt is generated as an external interrupt whenever the micro SD card is + plugged/unplugged in/from the discovery board. + The SD detection interrupt is handled by calling the function BSP_SD_DetectIT() + which is called in the IRQ handler file, the user callback is implemented in + the function BSP_SD_DetectCallback(). + + o The function BSP_SD_GetCardInfo()are used to get the micro SD card information + which is stored in the structure "HAL_SD_CardInfoTypedef". + + + Micro SD card operations + o The micro SD card can be accessed with read/write block(s) operations once + it is ready for access. The access can be performed whether + using the polling mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks(), + using the interrupt mode by calling the functions BSP_SD_ReadBlocks_IT()/BSP_SD_WriteBlocks_IT(), + or by DMA transfer using the functions BSP_SD_ReadBlocks_DMA()/BSP_SD_WriteBlocks_DMA(). + The access can be performed to instance 0. + + o The DMA transfer complete is used with interrupt mode. Once the SD transfer + is complete, the SD interrupt is handled using the function BSP_SD_IRQHandler() + when instance 0 is used. + The DMA Tx/Rx transfer complete are handled using the functions + SD_SDMMC1_DMA_Tx_IRQHandler(), SD_SDMMC1_DMA_Rx_IRQHandler(). The corresponding + user callbacks are implemented by the user at application level. + + o The SD erase block(s) is performed using the functions BSP_SD_Erase() with specifying + the number of blocks to erase. + + o The SD runtime status is returned when calling the function BSP_SD_GetCardState(). + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_sd.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_SD SD + * @{ + */ + +/** @defgroup STM32H7S78_DK_SD_Private_TypesDefinitions SD Private TypesDefinitions + * @{ + */ +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) +/* Is Msp Callbacks registered */ +static uint32_t IsMspCallbacksValid[SD_INSTANCES_NBR] = {0}; +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +typedef void (*BSP_EXTI_SD_LineCallback)(void); +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_SD_Exported_Variables SD Exported Variables + * @{ + */ +SD_HandleTypeDef hsd_sdmmc[SD_INSTANCES_NBR]; +EXTI_HandleTypeDef hsd_exti[SD_INSTANCES_NBR]; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_SD_Private_Variables SD Private Variables + * @{ + */ +static uint32_t PinDetect[SD_INSTANCES_NBR] = {SD_DETECT_PIN}; +static GPIO_TypeDef *SD_GPIO_PORT[SD_INSTANCES_NBR] = {SD_DETECT_GPIO_PORT}; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_SD_Private_Functions_Prototypes SD Private Functions Prototypes + * @{ + */ +static void SD_MspInit(SD_HandleTypeDef *hsd); +static void SD_MspDeInit(SD_HandleTypeDef *hsd); +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) +static void SD_AbortCallback(SD_HandleTypeDef *hsd); +static void SD_TxCpltCallback(SD_HandleTypeDef *hsd); +static void SD_RxCpltCallback(SD_HandleTypeDef *hsd); +#endif /* (USE_HAL_SD_REGISTER_CALLBACKS > 0) */ +static void SD_EXTI_Callback(void); +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_SD_Exported_Functions SD Exported Functions + * @{ + */ + +/** + * @brief Initializes the SD card device. + * @param Instance SD Instance + * @retval BSP status + */ +int32_t BSP_SD_Init(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure = {0}; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* GPIO Detect pin configuration */ + SD_DETECT_GPIO_CLK_ENABLE(); + + /* Configure Interrupt mode for SD detection pin */ + gpio_init_structure.Pin = PinDetect[Instance]; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(SD_GPIO_PORT[Instance], &gpio_init_structure); + + /* Check if SD card is present */ + if ((uint32_t)BSP_SD_IsDetected(Instance) != SD_PRESENT) + { + ret = BSP_ERROR_SD_NOT_DETECTED; + } + else + { +#if (USE_HAL_SD_REGISTER_CALLBACKS == 0) + /* Msp SD initialization */ + SD_MspInit(&hsd_sdmmc[Instance]); +#else + /* Register the SD MSP Callbacks */ + if (IsMspCallbacksValid[Instance] == 0UL) + { + if (BSP_SD_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + if (ret == BSP_ERROR_NONE) + { +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + + /* HAL SD initialization and Enable wide operation */ + if (MX_SDMMC1_SD_Init(&hsd_sdmmc[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_SD_ConfigWideBusOperation(&hsd_sdmmc[Instance], SDMMC_BUS_WIDE_4B) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Try to switch to High Speed mode if the card supports this mode */ + (void)HAL_SD_ConfigSpeedBusOperation(&hsd_sdmmc[Instance], SDMMC_SPEED_MODE_HIGH); + +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) + /* Register SD TC, HT and Abort callbacks */ + if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_TX_CPLT_CB_ID, SD_TxCpltCallback) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_RX_CPLT_CB_ID, SD_RxCpltCallback) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_ABORT_CB_ID, SD_AbortCallback) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) + } +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } +} + +return ret; +} + +/** + * @brief DeInitializes the SD card device. + * @param Instance SD Instance + * @retval SD status + */ +int32_t BSP_SD_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (HAL_EXTI_ClearConfigLine(&hsd_exti[Instance]) != HAL_OK) + { + return BSP_ERROR_PERIPH_FAILURE; + } + + /* Configure Detect pins in input floating mode */ + gpio_init_structure.Pin = PinDetect[Instance]; + HAL_GPIO_DeInit(SD_GPIO_PORT[Instance], gpio_init_structure.Pin); + + /* HAL SD de-initialization */ + if (HAL_SD_DeInit(&hsd_sdmmc[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Msp SD de-initialization */ +#if (USE_HAL_SD_REGISTER_CALLBACKS == 0) + SD_MspDeInit(&hsd_sdmmc[Instance]); +#endif /* (USE_HAL_SD_REGISTER_CALLBACKS == 0) */ + } + } + return ret; +} + +/** + * @brief Initializes the SDMMC1 peripheral. + * @param hsd SD handle + * @retval HAL status + */ +__weak HAL_StatusTypeDef MX_SDMMC1_SD_Init(SD_HandleTypeDef *hsd) +{ + HAL_StatusTypeDef ret = HAL_OK; + /* uSD device interface configuration */ + hsd->Instance = SDMMC1; + hsd->Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + hsd->Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + hsd->Init.BusWide = SDMMC_BUS_WIDE_1B; + hsd->Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE; + hsd->Init.ClockDiv = SDMMC_NSpeed_CLK_DIV; + + /* HAL SD initialization */ + if (HAL_SD_Init(hsd) != HAL_OK) + { + ret = HAL_ERROR; + } + return ret; +} + +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) +/** + * @brief Default BSP SD Msp Callbacks + * @param Instance SD Instance + * @retval BSP status + */ +int32_t BSP_SD_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_MSP_INIT_CB_ID, SD_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_MSP_DEINIT_CB_ID, SD_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + IsMspCallbacksValid[Instance] = 1U; + } + } + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP SD Msp Callback registering + * @param Instance SD Instance + * @param CallBacks pointer to MspInit/MspDeInit callbacks functions + * @retval BSP status + */ +int32_t BSP_SD_RegisterMspCallbacks(uint32_t Instance, BSP_SD_Cb_t *CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_MSP_INIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_SD_RegisterCallback(&hsd_sdmmc[Instance], HAL_SD_MSP_DEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + IsMspCallbacksValid[Instance] = 1U; + } + } + /* Return BSP status */ + return ret; +} +#endif /* (USE_HAL_SD_REGISTER_CALLBACKS > 0) */ + +/** + * @brief Configures Interrupt mode for SD detection pin. + * @param Instance SD Instance + * @retval Returns 0 + */ +int32_t BSP_SD_DetectITConfig(uint32_t Instance) +{ + int32_t ret; + GPIO_InitTypeDef gpio_init_structure = {0}; + static BSP_EXTI_SD_LineCallback SdCallback[SD_INSTANCES_NBR] = {SD_EXTI_Callback}; + static IRQn_Type SD_EXTI_IRQn[SD_INSTANCES_NBR] = {SD_DETECT_EXTI_IRQn}; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + SD_DETECT_GPIO_CLK_ENABLE(); + + /* Configure Interrupt mode for SD detection pin */ + gpio_init_structure.Pin = PinDetect[Instance]; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_init_structure.Mode = GPIO_MODE_IT_RISING_FALLING; + HAL_GPIO_Init(SD_GPIO_PORT[Instance], &gpio_init_structure); + + if (HAL_EXTI_GetHandle(&hsd_exti[Instance], SD_DETECT_EXTI_LINE) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_EXTI_RegisterCallback(&hsd_exti[Instance], HAL_EXTI_COMMON_CB_ID, SdCallback[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Enable and set Button EXTI Interrupt to the lowest priority */ + HAL_NVIC_SetPriority(SD_EXTI_IRQn[Instance], BSP_SD_IT_PRIORITY, 0x00); + HAL_NVIC_EnableIRQ(SD_EXTI_IRQn[Instance]); + ret = BSP_ERROR_NONE; + } + } + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP SD Callback. + * @param Instance SD Instance + * @param Status Pin status + * @retval None. + */ +__weak void BSP_SD_DetectCallback(uint32_t Instance, uint32_t Status) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); + UNUSED(Status); + + /* This function should be implemented by the user application. + It is called into this driver when an event on JoyPin is triggered. */ +} + +/** + * @brief Detects if SD card is correctly plugged in the memory slot or not. + * @param Instance SD Instance + * @retval Returns if SD is detected or not + */ +int32_t BSP_SD_IsDetected(uint32_t Instance) +{ + uint32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + return BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check SD card detect pin */ + if (HAL_GPIO_ReadPin(SD_GPIO_PORT[Instance], (uint16_t)PinDetect[Instance]) == GPIO_PIN_SET) + { + ret = SD_NOT_PRESENT; + } + else + { + ret = SD_PRESENT; + } + } + + return (int32_t)ret; +} + +/** + * @brief Reads block(s) from a specified address in an SD card, in polling mode. + * @param Instance SD Instance + * @param pData Pointer to the buffer that will contain the data to transmit + * @param BlockIdx Block index from where data is to be read + * @param BlocksNbr Number of SD blocks to read + * @retval BSP status + */ +int32_t BSP_SD_ReadBlocks(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + uint32_t timeout = SD_READ_TIMEOUT * BlocksNbr; + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_ReadBlocks(&hsd_sdmmc[Instance], (uint8_t *)pData, BlockIdx, BlocksNbr, timeout) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes block(s) to a specified address in an SD card, in polling mode. + * @param Instance SD Instance + * @param pData Pointer to the buffer that will contain the data to transmit + * @param BlockIdx Block index from where data is to be written + * @param BlocksNbr Number of SD blocks to write + * @retval BSP status + */ +int32_t BSP_SD_WriteBlocks(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + uint32_t timeout = SD_READ_TIMEOUT * BlocksNbr; + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_WriteBlocks(&hsd_sdmmc[Instance], (uint8_t *)pData, BlockIdx, BlocksNbr, timeout) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads block(s) from a specified address in an SD card, in DMA mode. + * @param Instance SD Instance + * @param pData Pointer to the buffer that will contain the data to transmit + * @param BlockIdx Block index from where data is to be read + * @param BlocksNbr Number of SD blocks to read + * @retval BSP status + */ +int32_t BSP_SD_ReadBlocks_DMA(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_ReadBlocks_DMA(&hsd_sdmmc[Instance], (uint8_t *)pData, BlockIdx, BlocksNbr) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes block(s) to a specified address in an SD card, in DMA mode. + * @param Instance SD Instance + * @param pData Pointer to the buffer that will contain the data to transmit + * @param BlockIdx Block index from where data is to be written + * @param BlocksNbr Number of SD blocks to write + * @retval BSP status + */ +int32_t BSP_SD_WriteBlocks_DMA(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_WriteBlocks_DMA(&hsd_sdmmc[Instance], (uint8_t *)pData, BlockIdx, BlocksNbr) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads block(s) from a specified address in an SD card, in DMA mode. + * @param Instance SD Instance + * @param pData Pointer to the buffer that will contain the data to transmit + * @param BlockIdx Block index from where data is to be read + * @param BlocksNbr Number of SD blocks to read + * @retval SD status + */ +int32_t BSP_SD_ReadBlocks_IT(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_ReadBlocks_IT(&hsd_sdmmc[Instance], (uint8_t *)pData, BlockIdx, BlocksNbr) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes block(s) to a specified address in an SD card, in DMA mode. + * @param Instance SD Instance + * @param pData Pointer to the buffer that will contain the data to transmit + * @param BlockIdx Block index from where data is to be written + * @param BlocksNbr Number of SD blocks to write + * @retval SD status + */ +int32_t BSP_SD_WriteBlocks_IT(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_WriteBlocks_IT(&hsd_sdmmc[Instance], (uint8_t *)pData, BlockIdx, BlocksNbr) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + /* Return BSP status */ + return ret; +} + + +/** + * @brief Erases the specified memory area of the given SD card. + * @param Instance SD Instance + * @param BlockIdx Block index from where data is to be + * @param BlocksNbr Number of SD blocks to erase + * @retval SD status + */ +int32_t BSP_SD_Erase(uint32_t Instance, uint32_t BlockIdx, uint32_t BlocksNbr) +{ + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (HAL_SD_Erase(&hsd_sdmmc[Instance], BlockIdx, BlockIdx + BlocksNbr) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Gets the current SD card data status. + * @param Instance SD Instance + * @retval Data transfer state. + * This value can be one of the following values: + * @arg SD_TRANSFER_OK: No data transfer is acting + * @arg SD_TRANSFER_BUSY: Data transfer is acting + */ +int32_t BSP_SD_GetCardState(uint32_t Instance) +{ + return (int32_t)((HAL_SD_GetCardState(&hsd_sdmmc[Instance]) == HAL_SD_CARD_TRANSFER) ? SD_TRANSFER_OK + : SD_TRANSFER_BUSY); +} + +/** + * @brief Get SD information about specific SD card. + * @param Instance SD Instance + * @param CardInfo Pointer to HAL_SD_CardInfoTypedef structure + * @retval BSP status + */ +int32_t BSP_SD_GetCardInfo(uint32_t Instance, BSP_SD_CardInfo *CardInfo) +{ + int32_t ret; + + if (Instance >= SD_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + (void)HAL_SD_GetCardInfo(&hsd_sdmmc[Instance], CardInfo); + ret = BSP_ERROR_NONE; + } + + /* Return BSP status */ + return ret; +} + +#if (USE_HAL_SD_REGISTER_CALLBACKS == 0) || !defined(USE_HAL_SD_REGISTER_CALLBACKS) +/** + * @brief SD Abort callbacks + * @param hsd SD handle + * @retval None + */ +void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd) +{ + BSP_SD_AbortCallback((hsd == &hsd_sdmmc[0]) ? 0UL : 1UL); +} + +/** + * @brief Tx Transfer completed callbacks + * @param hsd SD handle + * @retval None + */ +void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd) +{ + BSP_SD_WriteCpltCallback((hsd == &hsd_sdmmc[0]) ? 0UL : 1UL); +} + +/** + * @brief Rx Transfer completed callbacks + * @param hsd SD handle + * @retval None + */ +void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd) +{ + BSP_SD_ReadCpltCallback((hsd == &hsd_sdmmc[0]) ? 0UL : 1UL); +} +#endif /* (USE_HAL_SD_REGISTER_CALLBACKS == 0) */ + +/** + * @brief This function handles EXTI_LINE_10 for SD1 interrupt request. + * @param Instance SD Instance + * @retval None + */ +void BSP_SD_DETECT_IRQHandler(uint32_t Instance) +{ + HAL_EXTI_IRQHandler(&hsd_exti[Instance]); +} + +/** + * @brief This function handles SDMMC interrupt requests. + * @param Instance SD Instance + * @retval None + */ +void BSP_SD_IRQHandler(uint32_t Instance) +{ + HAL_SD_IRQHandler(&hsd_sdmmc[Instance]); +} + +/** + * @brief BSP SD Abort callbacks + * @param Instance SD Instance + * @retval None + */ +__weak void BSP_SD_AbortCallback(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief BSP Tx Transfer completed callbacks + * @param Instance SD Instance + * @retval None + */ +__weak void BSP_SD_WriteCpltCallback(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @brief BSP Rx Transfer completed callbacks + * @param Instance SD Instance + * @retval None + */ +__weak void BSP_SD_ReadCpltCallback(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); +} + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_SD_Private_Functions SD Private Functions + * @{ + */ +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) +/** + * @brief SD Abort callbacks + * @param hsd SD handle + * @retval None + */ +static void SD_AbortCallback(SD_HandleTypeDef *hsd) +{ + BSP_SD_AbortCallback((hsd == &hsd_sdmmc[0]) ? 0UL : 1UL); +} + +/** + * @brief Tx Transfer completed callbacks + * @param hsd SD handle + * @retval None + */ +static void SD_TxCpltCallback(SD_HandleTypeDef *hsd) +{ + BSP_SD_WriteCpltCallback((hsd == &hsd_sdmmc[0]) ? 0UL : 1UL); +} + +/** + * @brief Rx Transfer completed callbacks + * @param hsd SD handle + * @retval None + */ +static void SD_RxCpltCallback(SD_HandleTypeDef *hsd) +{ + BSP_SD_ReadCpltCallback((hsd == &hsd_sdmmc[0]) ? 0UL : 1UL); +} + +#endif /* USE_HAL_SD_REGISTER_CALLBACKS > 0 */ + +/** + * @brief SD EXTI line detection callbacks. + * @retval None + */ +static void SD_EXTI_Callback(void) +{ + uint32_t sd_status; + + if (HAL_GPIO_ReadPin(SD_GPIO_PORT[0], (uint16_t)PinDetect[0]) == GPIO_PIN_SET) + { + sd_status = SD_NOT_PRESENT; + } + else + { + sd_status = SD_PRESENT; + } + BSP_SD_DetectCallback(0, sd_status); +} + +/** + * @brief Initializes the SD MSP. + * @param hsd SD handle + * @retval None + */ +static void SD_MspInit(SD_HandleTypeDef *hsd) +{ + GPIO_InitTypeDef gpioinitstruct = {0}; + + if (hsd == &hsd_sdmmc[0]) + { + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC12; + PeriphClkInitStruct.Sdmmc12ClockSelection = RCC_SDMMC12CLKSOURCE_PLL2S; + (void)HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Enable SDMMC1 clock */ + __HAL_RCC_SDMMC1_CLK_ENABLE(); + + /* Enable GPIOs clock */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /* Common GPIO configuration */ + gpioinitstruct.Mode = GPIO_MODE_AF_PP; + gpioinitstruct.Pull = GPIO_PULLUP; + gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + /* GPIOC configuration D2*/ + gpioinitstruct.Alternate = GPIO_AF12_SDMMC1; + gpioinitstruct.Pin = GPIO_PIN_10; + HAL_GPIO_Init(GPIOC, &gpioinitstruct); + + /* GPIOC configuration, D0, D1, D3, CK*/ + gpioinitstruct.Alternate = GPIO_AF11_SDMMC1; + gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12; + HAL_GPIO_Init(GPIOC, &gpioinitstruct); + + /* GPIOD configuration */ + gpioinitstruct.Pin = GPIO_PIN_2; + HAL_GPIO_Init(GPIOD, &gpioinitstruct); + + /* NVIC configuration for SDMMC1 interrupts */ + HAL_NVIC_SetPriority(SDMMC1_IRQn, BSP_SD_IT_PRIORITY, 0); + HAL_NVIC_EnableIRQ(SDMMC1_IRQn); + } +} + +/** + * @brief DeInitializes the SD MSP. + * @param hsd SD handle + * @retval None + */ +static void SD_MspDeInit(SD_HandleTypeDef *hsd) +{ + GPIO_InitTypeDef gpio_init_structure; + + if (hsd == &hsd_sdmmc[0]) + { + /* Disable NVIC for SDIO interrupts */ + HAL_NVIC_DisableIRQ(SDMMC1_IRQn); + + /* GPIOC configuration */ + gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; + HAL_GPIO_DeInit(GPIOC, gpio_init_structure.Pin); + + /* GPIOD configuration */ + gpio_init_structure.Pin = GPIO_PIN_2; + HAL_GPIO_DeInit(GPIOD, gpio_init_structure.Pin); + + /* Disable SDMMC1 clock */ + __HAL_RCC_SDMMC1_CLK_DISABLE(); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.h new file mode 100644 index 0000000..57f5d28 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_sd.h @@ -0,0 +1,162 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_sd.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32h7s78_discovery_sd.c 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 STM32H7S78_DK_SD_H +#define STM32H7S78_DK_SD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_SD SD + * @{ + */ + +/** @defgroup STM32H7S78_DK_SD_Exported_Types SD Exported Types + * @{ + */ + +/** + * @brief SD Card information structure + */ +#define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef + +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) +typedef struct +{ + void (*pMspInitCb)(SD_HandleTypeDef *); + void (*pMspDeInitCb)(SD_HandleTypeDef *); +} BSP_SD_Cb_t; +#endif /* (USE_HAL_SD_REGISTER_CALLBACKS > 0) */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_SD_Exported_Constants SD Exported Constants + * @{ + */ +#define SD_INSTANCES_NBR 1UL + +#ifndef SD_WRITE_TIMEOUT +#define SD_WRITE_TIMEOUT 100U +#endif /* SD_WRITE_TIMEOUT */ + +#ifndef SD_READ_TIMEOUT +#define SD_READ_TIMEOUT 100U +#endif /* SD_READ_TIMEOUT */ + +/** + * @brief SD transfer state definition + */ +#define SD_TRANSFER_OK 0U +#define SD_TRANSFER_BUSY 1U + +/** + * @brief SD-detect signal + */ +#define SD_PRESENT 1U +#define SD_NOT_PRESENT 0U + +#define SD_DETECT_PIN GPIO_PIN_14 +#define SD_DETECT_GPIO_PORT GPIOM +#define SD_DETECT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOM_CLK_ENABLE() +#define SD_DETECT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOM_CLK_DISABLE() +#define SD_DETECT_EXTI_IRQn EXTI14_IRQn +#define SD_DETECT_EXTI_LINE EXTI_LINE_14 +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_SD_Exported_Variables + * @{ + */ +extern SD_HandleTypeDef hsd_sdmmc[]; +extern EXTI_HandleTypeDef hsd_exti[]; + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_SD_Exported_Functions + * @{ + */ +int32_t BSP_SD_Init(uint32_t Instance); +int32_t BSP_SD_DeInit(uint32_t Instance); +#if (USE_HAL_SD_REGISTER_CALLBACKS > 0) +int32_t BSP_SD_RegisterMspCallbacks(uint32_t Instance, BSP_SD_Cb_t *CallBacks); +int32_t BSP_SD_RegisterDefaultMspCallbacks(uint32_t Instance); +#endif /* (USE_HAL_SD_REGISTER_CALLBACKS > 0) */ +int32_t BSP_SD_DetectITConfig(uint32_t Instance); +int32_t BSP_SD_ReadBlocks(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_WriteBlocks(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_ReadBlocks_DMA(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_WriteBlocks_DMA(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_ReadBlocks_IT(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_WriteBlocks_IT(uint32_t Instance, uint32_t *pData, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_Erase(uint32_t Instance, uint32_t BlockIdx, uint32_t NbrOfBlocks); +int32_t BSP_SD_GetCardState(uint32_t Instance); +int32_t BSP_SD_GetCardInfo(uint32_t Instance, BSP_SD_CardInfo *CardInfo); +int32_t BSP_SD_IsDetected(uint32_t Instance); + +void BSP_SD_DETECT_IRQHandler(uint32_t Instance); +void BSP_SD_IRQHandler(uint32_t Instance); + +/* These functions can be modified in case the current settings (e.g. DMA stream or IT) + need to be changed for specific application needs */ +void BSP_SD_AbortCallback(uint32_t Instance); +void BSP_SD_WriteCpltCallback(uint32_t Instance); +void BSP_SD_ReadCpltCallback(uint32_t Instance); +void BSP_SD_DetectCallback(uint32_t Instance, uint32_t Status); + +HAL_StatusTypeDef MX_SDMMC1_SD_Init(SD_HandleTypeDef *hsd); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DK_SD_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.c new file mode 100644 index 0000000..f7751a1 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.c @@ -0,0 +1,690 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_ts.c + * @author MCD Application Team + * @brief This file provides a set of firmware functions to communicate + * with external devices available on STM32H7S78-DK board (MB1736) from + * STMicroelectronics + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* File Info : ----------------------------------------------------------------- + User NOTES +1. How To use this driver: +-------------------------- + - This driver is used to drive the GT911 touch screen module + mounted over TFT-LCD on the STM32H7S78_DK board. + +2. Driver description: +--------------------- + + Initialization steps: + o Initialize the TS module using the BSP_TS_Init() function. This + function includes the MSP layer hardware resources initialization and the + communication layer configuration to start the TS use. The LCD size properties + (x and y) are passed as parameters. + o If TS interrupt mode is desired, you must configure the TS interrupt mode + by calling the function BSP_TS_ITConfig(). The TS interrupt mode is generated + as an external interrupt whenever a touch is detected. + The interrupt mode internally uses the IO functionalities driver driven by + the IO expander, to configure the IT line. + + + Touch screen use + o The touch screen state is captured whenever the function BSP_TS_GetState() is + used. This function returns information about the last LCD touch occurred + in the TS_State_t structure. + o The IT is handled using the corresponding external interrupt IRQ handler, + the user IT callback treatment is implemented on the same external interrupt + callback. + +------------------------------------------------------------------------------*/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_ts.h" +#include "stm32h7s78_discovery_bus.h" +#include "../Components/Common/ts.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_TS TS + * @{ + */ + +/** @defgroup STM32H7S78_DK_TS_Private_Types_Definitions Private Types Definitions + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Private_Defines Private Types Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Private_Macros Private Macros + * @{ + */ +#define TS_MIN(a,b) ((a > b) ? b : a) +/** + * @} + */ +/** @defgroup STM32H7S78_DK_TS_Private_Function_Prototypes Private Function Prototypes + * @{ + */ +static int32_t GT911_Probe(uint32_t Instance); +static void TS_EXTI_Callback(void); +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Privates_Variables Privates Variables + * @{ + */ +static TS_Drv_t *Ts_Drv = NULL; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Exported_Variables Exported Variables + * @{ + */ +EXTI_HandleTypeDef hts_exti[TS_INSTANCES_NBR] = {0}; +void *Ts_CompObj[TS_INSTANCES_NBR] = {0}; +TS_Ctx_t Ts_Ctx[TS_INSTANCES_NBR] = {0}; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes and configures the touch screen functionalities and + * configures all necessary hardware resources (GPIOs, I2C, clocks..). + * @param Instance TS instance. Could be only 0. + * @param TS_Init TS Init structure + * @retval BSP status + */ +int32_t BSP_TS_Init(uint32_t Instance, TS_Init_t *TS_Init) +{ + int32_t ret = BSP_ERROR_NONE; + + if ((Instance >= TS_INSTANCES_NBR) || (TS_Init->Width == 0U) || ( TS_Init->Width > TS_MAX_WIDTH) || \ + (TS_Init->Height == 0U) || ( TS_Init->Height > TS_MAX_HEIGHT) || \ + (TS_Init->Accuracy > TS_MIN((TS_Init->Width), (TS_Init->Height)))) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (GT911_Probe(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_NO_INIT; + } + else + { + TS_Capabilities_t Capabilities = {0}; + uint32_t i; + /* Store parameters on TS context */ + Ts_Ctx[Instance].Width = TS_Init->Width; + Ts_Ctx[Instance].Height = TS_Init->Height; + Ts_Ctx[Instance].Orientation = TS_Init->Orientation; + Ts_Ctx[Instance].Accuracy = TS_Init->Accuracy; + /* Get capabilities to retrieve maximum values of X and Y */ + if (Ts_Drv->GetCapabilities(Ts_CompObj[Instance], &Capabilities) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Store maximum X and Y on context */ + Ts_Ctx[Instance].MaxX = Capabilities.MaxXl; + Ts_Ctx[Instance].MaxY = Capabilities.MaxYl; + /* Initialize previous position in order to always detect first touch */ + for (i = 0; i < TS_TOUCH_NBR; i++) + { + Ts_Ctx[Instance].PreviousX[i] = TS_Init->Width + TS_Init->Accuracy + 1U; + Ts_Ctx[Instance].PreviousY[i] = TS_Init->Height + TS_Init->Accuracy + 1U; + } + } + } + } + + return ret; +} + +/** + * @brief De-Initializes the touch screen functionalities + * @param Instance TS instance. Could be only 0. + * @retval BSP status + */ +int32_t BSP_TS_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Ts_Drv->DeInit(Ts_CompObj[Instance]) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + return ret; +} + +/** + * @brief Get Touch Screen instance capabilities + * @param Instance Touch Screen instance + * @param Capabilities pointer to Touch Screen capabilities + * @retval BSP status + */ +int32_t BSP_TS_GetCapabilities(uint32_t Instance, TS_Capabilities_t *Capabilities) +{ + int32_t ret = BSP_ERROR_NONE; + + if ((Instance >= TS_INSTANCES_NBR) || (Capabilities == NULL)) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + (void)Ts_Drv->GetCapabilities(Ts_CompObj[Instance], Capabilities); + } + + return ret; +} + +/** + * @brief Configures and enables the touch screen interrupts. + * @param Instance TS instance. Could be only 0. + * @retval BSP status + */ +int32_t BSP_TS_EnableIT(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure = {0}; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Configure Interrupt mode for TS_INT pin falling edge : when a new touch is available */ + /* TS_INT pin is active on low level on new touch available */ + TS_INT_GPIO_CLK_ENABLE(); + gpio_init_structure.Pin = TS_INT_PIN; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Mode = GPIO_MODE_IT_RISING; + + HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure); + + if (Ts_Drv->EnableIT(Ts_CompObj[Instance]) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (HAL_EXTI_GetHandle(&hts_exti[Instance], TS_EXTI_LINE) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_EXTI_RegisterCallback(&hts_exti[Instance], HAL_EXTI_COMMON_CB_ID, TS_EXTI_Callback) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Enable and set the TS_INT EXTI Interrupt to an intermediate priority */ + HAL_NVIC_SetPriority((IRQn_Type)(TS_INT_EXTI_IRQn), BSP_TS_IT_PRIORITY, 0x00); + HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn)); + } + } + } + + return ret; +} + +/** + * @brief Disables the touch screen interrupts. + * @param Instance TS instance. Could be only 0. + * @retval BSP status + */ +int32_t BSP_TS_DisableIT(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GPIO_InitTypeDef gpio_init_structure; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* De-init TS_INT_PIN */ + gpio_init_structure.Pin = TS_INT_PIN; + HAL_GPIO_DeInit(TS_INT_GPIO_PORT, gpio_init_structure.Pin); + + /* Disable the TS in interrupt mode */ + /* In that case the INT output of GT911 when new touch is available */ + /* is active on low level and directed on EXTI */ + if (Ts_Drv->DisableIT(Ts_CompObj[Instance]) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + return ret; +} + +/** + * @brief This function handles TS interrupt request. + * @param Instance TS instance + * @retval None + */ +void BSP_TS_IRQHandler(uint32_t Instance) +{ + HAL_EXTI_IRQHandler(&hts_exti[Instance]); +} + +/** + * @brief BSP TS Callback. + * @param Instance : TS instance + * @retval None. + */ +__weak void BSP_TS_Callback(uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Instance); + + /* This function should be implemented by the user application. + It is called into this driver when an event on TS touch detection */ +} + +/** + * @brief Returns positions of a single touch screen. + * @param Instance TS instance. Could be only 0. + * @param TS_State Pointer to touch screen current state structure + * @retval BSP status + */ +int32_t BSP_TS_GetState(uint32_t Instance, TS_State_t *TS_State) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t x_oriented, y_oriented; + uint32_t x_diff, y_diff; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + GT911_State_t state = {0}; + + /* Get each touch coordinates */ + if (Ts_Drv->GetState(Ts_CompObj[Instance], &state) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Check and update the number of touches active detected */ + else if (state.TouchDetected != 0U) + { + x_oriented = state.TouchX; + y_oriented = state.TouchY; + + if ((Ts_Ctx[Instance].Orientation & TS_SWAP_XY) == TS_SWAP_XY) + { + x_oriented = state.TouchY; + y_oriented = state.TouchX; + } + + if ((Ts_Ctx[Instance].Orientation & TS_SWAP_X) == TS_SWAP_X) + { + x_oriented = Ts_Ctx[Instance].MaxX - state.TouchX - 1UL; + } + + if ((Ts_Ctx[Instance].Orientation & TS_SWAP_Y) == TS_SWAP_Y) + { + y_oriented = Ts_Ctx[Instance].MaxY - state.TouchY; + } + + /* Apply boundary */ + TS_State->TouchX = (x_oriented * Ts_Ctx[Instance].Width) / Ts_Ctx[Instance].MaxX; + TS_State->TouchY = (y_oriented * Ts_Ctx[Instance].Height) / Ts_Ctx[Instance].MaxY; + /* Store Current TS state */ + TS_State->TouchDetected = state.TouchDetected; + + /* Check accuracy */ + x_diff = (TS_State->TouchX > Ts_Ctx[Instance].PreviousX[0]) ? + (TS_State->TouchX - Ts_Ctx[Instance].PreviousX[0]) : + (Ts_Ctx[Instance].PreviousX[0] - TS_State->TouchX); + + y_diff = (TS_State->TouchY > Ts_Ctx[Instance].PreviousY[0]) ? + (TS_State->TouchY - Ts_Ctx[Instance].PreviousY[0]) : + (Ts_Ctx[Instance].PreviousY[0] - TS_State->TouchY); + + + if ((x_diff > Ts_Ctx[Instance].Accuracy) || (y_diff > Ts_Ctx[Instance].Accuracy)) + { + /* New touch detected */ + Ts_Ctx[Instance].PreviousX[0] = TS_State->TouchX; + Ts_Ctx[Instance].PreviousY[0] = TS_State->TouchY; + } + else + { + TS_State->TouchX = Ts_Ctx[Instance].PreviousX[0]; + TS_State->TouchY = Ts_Ctx[Instance].PreviousY[0]; + } + } + else + { + TS_State->TouchDetected = 0U; + TS_State->TouchX = Ts_Ctx[Instance].PreviousX[0]; + TS_State->TouchY = Ts_Ctx[Instance].PreviousY[0]; + } + } + + return ret; +} + +#if (USE_TS_MULTI_TOUCH > 0) +/** + * @brief Returns positions of multi touch screen. + * @param Instance TS instance. Could be only 0. + * @param TS_State Pointer to touch screen current state structure + * @retval BSP status + */ +int32_t BSP_TS_Get_MultiTouchState(uint32_t Instance, TS_MultiTouch_State_t *TS_State) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t index; + uint32_t x_oriented, y_oriented; + uint32_t x_diff, y_diff; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + GT911_MultiTouch_State_t state = {0}; + + /* Get each touch coordinates */ + if (Ts_Drv->GetMultiTouchState(Ts_CompObj[Instance], &state) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (state.TouchDetected != 0U) + { + /* Check and update the number of touches active detected */ + for (index = 0; index < state.TouchDetected; index++) + { + x_oriented = state.TouchX[index]; + y_oriented = state.TouchY[index]; + + if ((Ts_Ctx[Instance].Orientation & TS_SWAP_XY) == TS_SWAP_XY) + { + x_oriented = state.TouchY[index]; + y_oriented = state.TouchX[index]; + } + + if ((Ts_Ctx[Instance].Orientation & TS_SWAP_X) == TS_SWAP_X) + { + x_oriented = Ts_Ctx[Instance].MaxX - state.TouchX[index] - 1UL; + } + + if ((Ts_Ctx[Instance].Orientation & TS_SWAP_Y) == TS_SWAP_Y) + { + y_oriented = Ts_Ctx[Instance].MaxY - state.TouchY[index]; + } + + /* Apply boundary */ + TS_State->TouchX[index] = (x_oriented * Ts_Ctx[Instance].Width) / Ts_Ctx[Instance].MaxX; + TS_State->TouchY[index] = (y_oriented * Ts_Ctx[Instance].Height) / Ts_Ctx[Instance].MaxY; + /* Store Current TS state */ + TS_State->TouchDetected = state.TouchDetected; + + /* Check accuracy */ + x_diff = (TS_State->TouchX[index] > Ts_Ctx[Instance].PreviousX[index]) ? + (TS_State->TouchX[index] - Ts_Ctx[Instance].PreviousX[index]) : + (Ts_Ctx[Instance].PreviousX[index] - TS_State->TouchX[index]); + + y_diff = (TS_State->TouchY[index] > Ts_Ctx[Instance].PreviousY[index]) ? + (TS_State->TouchY[index] - Ts_Ctx[Instance].PreviousY[index]) : + (Ts_Ctx[Instance].PreviousY[index] - TS_State->TouchY[index]); + + if ((x_diff > Ts_Ctx[Instance].Accuracy) || (y_diff > Ts_Ctx[Instance].Accuracy)) + { + /* New touch detected */ + Ts_Ctx[Instance].PreviousX[index] = TS_State->TouchX[index]; + Ts_Ctx[Instance].PreviousY[index] = TS_State->TouchY[index]; + } + else + { + TS_State->TouchX[index] = Ts_Ctx[Instance].PreviousX[index]; + TS_State->TouchY[index] = Ts_Ctx[Instance].PreviousY[index]; + } + } + } + else + { + TS_State->TouchDetected = 0U; + for (index = 0; index < TS_TOUCH_NBR; index++) + { + TS_State->TouchX[index] = Ts_Ctx[Instance].PreviousX[index]; + TS_State->TouchY[index] = Ts_Ctx[Instance].PreviousY[index]; + } + } + } + + return ret; +} +#endif /* USE_TS_MULTI_TOUCH == 1 */ + +#if (USE_TS_GESTURE == 1) +/** + * @brief Update gesture Id following a touch detected. + * @param Instance TS instance. Could be only 0. + * @param GestureConfig Pointer to gesture configuration structure + * @retval BSP status + */ +int32_t BSP_TS_GestureConfig(uint32_t Instance, TS_Gesture_Config_t *GestureConfig) +{ + int32_t ret = BSP_ERROR_NONE; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (Ts_Drv->GestureConfig(Ts_CompObj[Instance], GestureConfig) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + return ret; +} + +/** + * @brief Update gesture Id following a touch detected. + * @param Instance TS instance. Could be only 0. + * @param GestureId Pointer to gesture ID + * @retval BSP status + */ +int32_t BSP_TS_GetGestureId(uint32_t Instance, uint32_t *GestureId) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t tmp = 0; + + if (Instance >= TS_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + }/* Get gesture Id */ + else if (Ts_Drv->GetGesture(Ts_CompObj[Instance], &tmp) < 0) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Remap gesture Id to a TS_Gesture_Id_t value */ + switch (tmp) + { + case GT911_GEST_ID_NO_GESTURE : + *GestureId = GESTURE_ID_NO_GESTURE; + break; + case GT911_GEST_ID_SWIPE_UP : + *GestureId = GESTURE_ID_SWIPE_UP; + break; + case GT911_GEST_ID_SWIPE_RIGHT : + *GestureId = GESTURE_ID_SWIPE_RIGHT; + break; + case GT911_GEST_ID_SWIPE_DOWN : + *GestureId = GESTURE_ID_SWIPE_DOWN; + break; + case GT911_GEST_ID_SWIPE_LEFT : + *GestureId = GESTURE_ID_SWIPE_LEFT; + break; + case GT911_GEST_ID_DOUBLE_TAP : + *GestureId = GESTURE_ID_DOUBLE_TAP; + break; + default : + *GestureId = GESTURE_ID_NO_GESTURE; + break; + } + } + + return ret; +} +#endif /* USE_TS_GESTURE == 1 */ + +/** + * @brief Set TS orientation + * @param Instance TS instance. Could be only 0. + * @param Orientation Orientation to be set + * @retval BSP status + */ +int32_t BSP_TS_Set_Orientation(uint32_t Instance, uint32_t Orientation) +{ + Ts_Ctx[Instance].Orientation = Orientation; + return BSP_ERROR_NONE; +} + +/** + * @brief Get TS orientation + * @param Instance TS instance. Could be only 0. + * @param Orientation Current Orientation to be returned + * @retval BSP status + */ +int32_t BSP_TS_Get_Orientation(uint32_t Instance, uint32_t *Orientation) +{ + *Orientation = Ts_Ctx[Instance].Orientation; + return BSP_ERROR_NONE; +} + +/** + * @} + */ +/** @defgroup STM32H7S78_DK_TS_Private_Functions Private Functions + * @{ + */ + +/** + * @brief Register Bus IOs if component ID is OK + * @param Instance TS instance. Could be only 0. + * @retval BSP status + */ +static int32_t GT911_Probe(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + GT911_IO_t IOCtx; + static GT911_Object_t GT911Obj; + uint32_t gt911_id = 0; + + /* Configure the touch screen driver */ + IOCtx.Address = TS_I2C_ADDRESS; + IOCtx.Init = BSP_I2C1_Init; + IOCtx.DeInit = BSP_I2C1_DeInit; + IOCtx.ReadReg = BSP_I2C1_ReadReg16; + IOCtx.WriteReg = BSP_I2C1_WriteReg16; + IOCtx.GetTick = BSP_GetTick; + + if (GT911_RegisterBusIO (>911Obj, &IOCtx) != GT911_OK) + { + ret = BSP_ERROR_BUS_FAILURE; + } + else if (GT911_ReadID(>911Obj, >911_id) != GT911_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (gt911_id != GT911_ID) + { + ret = BSP_ERROR_UNKNOWN_COMPONENT; + } + else + { + Ts_CompObj[Instance] = >911Obj; + Ts_Drv = (TS_Drv_t *) >911_TS_Driver; + + if (Ts_Drv->Init(Ts_CompObj[Instance]) != GT911_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + return ret; +} + +/** + * @brief TS EXTI touch detection callbacks. + * @retval None + */ +static void TS_EXTI_Callback(void) +{ + BSP_TS_Callback(0); + + /* Clear interrupt on TS driver */ + (void)Ts_Drv->ClearIT(Ts_CompObj[0]); +} + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.h new file mode 100644 index 0000000..64e3f01 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_ts.h @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_ts.h + * @author MCD Application Team + * @brief This file is the header of stm32h7s78_discovery_bus.c 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7S78_DK_TS_H +#define STM32H7S78_DK_TS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" +#include "../Components/gt911/gt911.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup STM32H7S78_DK_TS + * @{ + */ + +/** @defgroup STM32H7S78_DK_TS_Exported_Constants Exported Constants + * @{ + */ +#ifndef USE_TS_MULTI_TOUCH +#define USE_TS_MULTI_TOUCH 1U +#endif +#ifndef USE_TS_GESTURE +#define USE_TS_GESTURE 1U +#endif + +#ifndef TS_TOUCH_NBR +#define TS_TOUCH_NBR 5U +#endif + +#define TS_INSTANCES_NBR 1U + +/* Maximum border values of the touchscreen pad */ +#define TS_MAX_WIDTH GT911_MAX_X_LENGTH /* Touchscreen pad max width */ +#define TS_MAX_HEIGHT GT911_MAX_Y_LENGTH /* Touchscreen pad max height */ + +#define TS_SWAP_NONE 0x01U +#define TS_SWAP_X 0x02U +#define TS_SWAP_Y 0x04U +#define TS_SWAP_XY 0x08U + +/** + * @brief TouchScreen Slave I2C address 1 + */ +#define TS_I2C_ADDRESS 0xBAU + +/** + * @brief Touch screen interrupt signal + */ +#define TS_INT_PIN GPIO_PIN_3 +#define TS_INT_GPIO_PORT GPIOE +#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE() +#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE() +#define TS_INT_EXTI_IRQn EXTI3_IRQn +#define TS_EXTI_LINE EXTI_LINE_3 + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Exported_Types Exported Types + * @{ + */ +typedef struct +{ + uint32_t Width; /* Screen Width */ + uint32_t Height; /* Screen Height */ + uint32_t Orientation; /* Touch Screen orientation from the upper left position */ + uint32_t Accuracy; /* Expressed in pixel and means the x or y difference vs old + position to consider the new values valid */ +} TS_Init_t; + +typedef struct +{ + uint32_t Width; + uint32_t Height; + uint32_t Orientation; + uint32_t Accuracy; + uint32_t MaxX; + uint32_t MaxY; + uint32_t PreviousX[TS_TOUCH_NBR]; + uint32_t PreviousY[TS_TOUCH_NBR]; +} TS_Ctx_t; + +typedef struct +{ + uint8_t MultiTouch; /* Multi-touch supported : 0 means no, 1 means yes */ + uint8_t Gesture; /* Gesture supported : 0 means no, 1 means yes */ + uint8_t MaxTouch; /* Maximum number of touches detected if multi-touch supported */ + uint32_t MaxXl; /* Maximum value of x coordinate */ + uint32_t MaxYl; /* Maximum value of y coordinate */ +} TS_Capabilities_t; + +typedef struct +{ + uint32_t TouchDetected; /* Touch detected : 0 means no, 1 means yes */ + uint32_t TouchX; /* x coordinate */ + uint32_t TouchY; /* y coordinate */ +} TS_State_t; + +typedef struct +{ + uint32_t TouchDetected; /* Number of touch detected (from 0 to maximum of touches) */ + uint32_t TouchX[TS_TOUCH_NBR]; /* x coordinates */ + uint32_t TouchY[TS_TOUCH_NBR]; /* y coordinates */ +} TS_MultiTouch_State_t; + +#if (USE_TS_GESTURE > 0) +/** + * @brief TS_Gesture_Id_t + * Define Possible managed gesture identification values returned by touch screen + * driver. + */ +#define GESTURE_ID_NO_GESTURE 0x00U /*!< Gesture not defined / recognized */ +#define GESTURE_ID_SWIPE_UP 0x01U /*!< Gesture Swipe Up */ +#define GESTURE_ID_SWIPE_RIGHT 0x02U /*!< Gesture Swipe Right */ +#define GESTURE_ID_SWIPE_DOWN 0x03U /*!< Gesture Swipe Down */ +#define GESTURE_ID_SWIPE_LEFT 0x04U /*!< Gesture Swipe Left */ +#define GESTURE_ID_DOUBLE_TAP 0x05U /*!< Gesture Double Tap */ +#define GESTURE_ID_NB_MAX 0x06U /*!< max number of gesture id */ + +typedef struct +{ + uint32_t DistanceLeftRight; /* Maximum distance while moving left and moving right gesture. + Value from 0 to TS_LENGTH/16 (default value is TS_LENGTH/8). */ + uint32_t DistanceUpDown; /* Maximum distance while moving up and moving down gesture. + Value from 0 to TS_LENGTH/16 (default value is TS_LENGTH/8). */ + uint8_t RefreshRate; /* Report Rate in Gesture Mode. */ + uint8_t GestureThreshold; /* Touch Threshold in Gesture Mode. */ + uint8_t Gain; /* Gesture PGA gain. */ +} TS_Gesture_Config_t; + +#endif /* (USE_TS_GESTURE > 0) */ + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_TS_Exported_Variables + * @{ + */ +extern void *Ts_CompObj[TS_INSTANCES_NBR]; +extern EXTI_HandleTypeDef hts_exti[TS_INSTANCES_NBR]; +extern TS_Ctx_t Ts_Ctx[TS_INSTANCES_NBR]; +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_TS_Exported_FunctionsPrototypes Exported Functions Prototypes + * @{ + */ +int32_t BSP_TS_Init(uint32_t Instance, TS_Init_t *TS_Init); +int32_t BSP_TS_DeInit(uint32_t Instance); +int32_t BSP_TS_EnableIT(uint32_t Instance); +int32_t BSP_TS_DisableIT(uint32_t Instance); +int32_t BSP_TS_GetState(uint32_t Instance, TS_State_t *TS_State); +#if (USE_TS_MULTI_TOUCH == 1) +int32_t BSP_TS_Get_MultiTouchState(uint32_t Instance, TS_MultiTouch_State_t *TS_State); +#endif /* USE_TS_MULTI_TOUCH == 1 */ +#if (USE_TS_GESTURE == 1) +int32_t BSP_TS_GestureConfig(uint32_t Instance, TS_Gesture_Config_t *GestureConfig); +int32_t BSP_TS_GetGestureId(uint32_t Instance, uint32_t *GestureId); +#endif /* (USE_TS_GESTURE == 1) */ +int32_t BSP_TS_Set_Orientation(uint32_t Instance, uint32_t Orientation); +int32_t BSP_TS_Get_Orientation(uint32_t Instance, uint32_t *Orientation); +int32_t BSP_TS_GetCapabilities(uint32_t Instance, TS_Capabilities_t *Capabilities); +void BSP_TS_Callback(uint32_t Instance); +void BSP_TS_IRQHandler(uint32_t Instance); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DK_TS_H */ diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.c new file mode 100644 index 0000000..89f7789 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.c @@ -0,0 +1,1870 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_usbpd_pwr.c + * @author MCD Application Team + * @brief This file provides a set of firmware functions to manage USB-PD Power: + * - VBUS control + * - VBUS voltage/current measurement + * - VCONN control + * - VBUS presence detection + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_usbpd_pwr.h" +#include "stm32h7s78_discovery_bus.h" + +#if defined(_TRACE) +#include "usbpd_core.h" +#include "usbpd_trace.h" +#include "string.h" +#ifndef _STDIO +#include "stdio.h" +#endif /* _STDIO */ +#endif /* _TRACE */ + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup USBPD_PWR + * @{ + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Exported_Variables Exported Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Private_Typedef Private Typedef + * @{ + */ +/** + * @brief Port HW configuration description + */ +typedef struct +{ + uint8_t Type; /*!< HW component associated to Port */ + uint8_t Address; /*!< I2C address (if any) associated to Port */ +} USBPD_PWR_PortConfig_t; + +/** + * @brief Port BSP Power status + */ +typedef struct +{ + uint8_t IsInitialized; /*!< Port Context Initialization status */ + uint8_t IsItEnabled; /*!< Port IT enabled status */ + USBPD_PWR_PowerRoleTypeDef PwrRole; /*!< Port current power role (SRC or SNK) */ + USBPD_PWR_PowerModeTypeDef PwrSavingMode; /*!< Port current power saving mode */ + uint32_t LastFaultTick; /*!< Current Tick on last detected fault */ + USBPD_PWR_VBUSDetectCallbackFunc *VBUSDetectCallback;/*!< Port callback for VBUS detection event */ +} USBPD_PWR_PortStatus_t; + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Private_Constants Private Constants + * @{ + */ + +/* Maximum digital value of the ADC output (12 Bits resolution) + To convert ADC measurement to an absolute voltage value: + VCHANNELx = ADCx_DATA x (VDD/ADC_FULL_SCALE) + */ +#define ADC_FULL_SCALE (0x0FFFU) + +/* Delay between ADC end of calibration and ADC enable. */ +/* Delay estimation in CPU cycles: Case of ADC enable done */ +/* immediately after ADC calibration, ADC clock setting slow */ +/* (LL_ADC_CLOCK_ASYNC_DIV32). Use a higher delay if ratio */ +/* (CPU clock / ADC clock) is above 32. */ + +#define ADC_DELAY_CALIB_ENABLE_CPU_CYCLES (LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES * 32U) + +#define VDDA_APPLI (3300U) + +#define ABS(__VAL__) (((int32_t)(__VAL__)) < 0 ? - ((int32_t)(__VAL__)) : ((int32_t)(__VAL__))) + +#define IS_PWR_TCPP0203_NOT_ZERO(__VALUE__) ((__VALUE__) != 0U) + +/* Minimum time between 2 detected faults allowing to consider that + fault could be due to a false detection (could be recovered). + => if 2 faults occurred in less than that duration, no recovery will be executed */ +#define USBPD_PWR_FAULT_MIN_TIME_RECOVERY (1000U) /* 1s */ + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Private_Macros Private Macros + * @{ + */ +#ifdef _TRACE +#define BSP_USBPD_PWR_TRACE(_PORT_,_MSG_) USBPD_TRACE_Add(USBPD_TRACE_DEBUG, (uint8_t)_PORT_, 0U , (uint8_t *)_MSG_, \ + strlen(_MSG_)); +#else +#define BSP_USBPD_PWR_TRACE(_PORT_,_MSG_) +#endif /* _TRACE */ + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Private_Functions Private Functions + * @{ + */ +static void PWR_TCPP0203_Configure_ADC(void); +static void PWR_TCPP0203_GPIOConfigInit(uint32_t PortNum); +static void PWR_TCPP0203_ITConfigInit(uint32_t PortNum); +static int32_t PWR_TCPP0203_BUSConfigInit(uint32_t PortNum, uint16_t Address); +static int32_t PWR_TCPP0203_ConfigDeInit(uint32_t PortNum); +static void PWR_TCPP0203_EventCallback(uint32_t PortNum); + +static uint32_t PWR_TCPP0203_ConvertADCDataToVoltage(uint32_t ADCData, uint32_t Ra, uint32_t Rb); +static int32_t PWR_TCPP0203_ConvertADCDataToCurrent(uint32_t ADCData, uint32_t Ga, uint32_t Rs); + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Private_Variables Private Variables + * @{ + */ + +static USBPD_PWR_PortConfig_t USBPD_PWR_Port_Configs[USBPD_PWR_INSTANCES_NBR] = +{ + { + USBPD_PWR_HW_CONFIG_TYPE_TCPP03, /* Port 0 : TCPP Type - default, will be read */ + TCPP0203_I2C_ADDRESS_X68, /* TCPP0x on shield (Address 0x34) */ + }, +}; + +static USBPD_PWR_PortStatus_t USBPD_PWR_Port_Status[USBPD_PWR_INSTANCES_NBR] = +{ + {0U, 0U, POWER_ROLE_SINK, USBPD_PWR_MODE_OFF, 0U, NULL}, +}; + +static TCPP0203_Object_t USBPD_PWR_PortCompObj[USBPD_PWR_INSTANCES_NBR] = { 0U }; +static TCPP0203_Drv_t *USBPD_PWR_PortCompDrv[USBPD_PWR_INSTANCES_NBR] = { NULL }; + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_USBPD_PWR_Exported_Functions + * @{ + */ + +/** + * @brief Global initialization of PWR resource used by USB-PD + * @param PortNum Type-C port identifier + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_Init(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_Init --"); + + if (USBPD_PWR_Port_Status[PortNum].IsInitialized == 0U) + { + /* Initialisation according to HW configuration type of port */ + switch (USBPD_PWR_Port_Configs[PortNum].Type) + { + case USBPD_PWR_HW_CONFIG_TYPE_TCPP02: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP03: + /* Set default Role to SNK */ + USBPD_PWR_Port_Status[PortNum].PwrRole = POWER_ROLE_SINK; + + /* Set default Power Mode to Hibernate */ + USBPD_PWR_Port_Status[PortNum].PwrSavingMode = USBPD_PWR_MODE_HIBERNATE; + + /* Reset port callback for VBUS detection event */ + USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback = NULL; + + /* Reset last detected fault Tick */ + USBPD_PWR_Port_Status[PortNum].LastFaultTick = 0U; + + /* Initialize required GPIOs */ + PWR_TCPP0203_GPIOConfigInit(PortNum); + + /* Initialize EXTI for FLGn signal */ + PWR_TCPP0203_ITConfigInit(PortNum); + + /* Enable component */ + TCPP0203_PORT0_ENABLE_GPIO_SET(); + + /* Initialize required BUS for communication */ + ret = PWR_TCPP0203_BUSConfigInit(PortNum, USBPD_PWR_Port_Configs[PortNum].Address); + break; + + case USBPD_PWR_HW_CONFIG_TYPE_DEFAULT: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP01: + default: + ret = BSP_ERROR_WRONG_PARAM; + break; + } + + if (ret == BSP_ERROR_NONE) + { + /* Set Initialisation flag */ + USBPD_PWR_Port_Status[PortNum].IsInitialized = 1U; + } + } + } + return ret; +} + +/** + * @brief Global de-initialization of PWR resource used by USB-PD + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_Deinit(uint32_t PortNum) +{ + int32_t ret; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_DeInit --"); + + /* Deinitialize Power config for port */ + switch (USBPD_PWR_Port_Configs[PortNum].Type) + { + case USBPD_PWR_HW_CONFIG_TYPE_TCPP02: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP03: + /* Perform any treatments required for de-initialization for GPIO, BUS communication, Interrupts */ + ret = PWR_TCPP0203_ConfigDeInit(PortNum); + break; + + case USBPD_PWR_HW_CONFIG_TYPE_DEFAULT: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP01: + default: + ret = BSP_ERROR_WRONG_PARAM; + break; + } + + /* Reset Initialisation flag */ + USBPD_PWR_Port_Status[PortNum].IsInitialized = 0U; + } + + return ret; +} + +/** + * @brief Assign Power role for current Port (Source or Sink) + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param Role Type-C port role + * This parameter can take one of the following values: + * @arg @ref POWER_ROLE_SOURCE + * @arg @ref POWER_ROLE_SINK + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_SetRole(uint32_t PortNum, USBPD_PWR_PowerRoleTypeDef Role) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + switch (Role) + { + case POWER_ROLE_SOURCE: + /* Port Role is now SRC */ + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_SetRole : SRC --"); + /* Set port power Role */ + USBPD_PWR_Port_Status[PortNum].PwrRole = Role; + + /* Ensure that TCPP0203 mode is not set to Hibernate */ + if (USBPD_PWR_Port_Status[PortNum].PwrSavingMode == USBPD_PWR_MODE_HIBERNATE) + { + if (USBPD_PWR_PortCompDrv[PortNum]->SetPowerMode(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_POWER_MODE_LOWPOWER) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + USBPD_PWR_Port_Status[PortNum].PwrSavingMode = USBPD_PWR_MODE_LOWPOWER; + } + } + break; + + case POWER_ROLE_SINK: + /* Port Role is now SNK */ + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_SetRole : SNK --"); + /* Set port power Role */ + USBPD_PWR_Port_Status[PortNum].PwrRole = Role; + break; + + default: + ret = BSP_ERROR_WRONG_PARAM; + break; + } + } + + return ret; +} + + +/** + * @brief Set operating mode of Port regarding power saving constraints + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param PwrMode Type-C port power saving mode + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_MODE_OFF + * @arg @ref USBPD_PWR_MODE_HIBERNATE + * @arg @ref USBPD_PWR_MODE_LOWPOWER + * @arg @ref USBPD_PWR_MODE_NORMAL + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_SetPowerMode(uint32_t PortNum, USBPD_PWR_PowerModeTypeDef PwrMode) +{ + uint8_t flg_reg = 0U; + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_SetPowerMode --"); + + /* Evaluate requested Power config for port */ + switch (PwrMode) + { + case USBPD_PWR_MODE_OFF: + /* Port should enter OFF mode : Reset TCPP0203 Reg0 */ + if (USBPD_PWR_PortCompDrv[PortNum]->Reset(&USBPD_PWR_PortCompObj[PortNum]) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + break; + + case USBPD_PWR_MODE_HIBERNATE: + /* Port Mode is Hibernate : (Default state at startup) suitable for SNK role + - Dead Batteries Enabled, + - Gate Driver Consumer controlled by I2C, Gate Driver Provider OFF + - waiting for VBUS_OK in FLGn (interrupt) + */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Hibernate --"); + if (USBPD_PWR_PortCompDrv[PortNum]->SetPowerMode(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_POWER_MODE_HIBERNATE) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Check if VBUS is present (in case of SNK VBUS powered device) */ + /* Read Flags register (FLGn) */ + if (USBPD_PWR_PortCompDrv[PortNum]->ReadFlagRegister(&USBPD_PWR_PortCompObj[PortNum], &flg_reg) == TCPP0203_OK) + { + /* If FLGn has been set to 0 in LOW POWER or HIBERNATE mode, + it is expected that a VBUS_OK condition is detected. + In this case, if any, vBus Detection callback could be called */ + if ((flg_reg & TCPP0203_FLAG_VBUS_OK_SET) == TCPP0203_FLAG_VBUS_OK_SET) + { + if (USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback != NULL) + { + /* In case of TCPP03 in Hibernate Mode (SNK config), + Mode is set to Low power to enable TCPP03 behavior on CC lines */ + /* Switch to Low Power mode */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Low Power --"); + if (USBPD_PWR_PortCompDrv[PortNum]->SetPowerMode(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_POWER_MODE_LOWPOWER) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback(PortNum, VBUS_CONNECTED); + } + } + else + { + /* VBUS indication not present in FLGn flags : nothing more to be done */ + } + } + break; + + case USBPD_PWR_MODE_LOWPOWER: + /* Port Mode is Low Power : suitable while toggling SNK/SRC is case of DRP + - Dead Batteries Disabled, + - Gate Driver Consumer or Provider controlled by I2C + - waiting for VBUS_OK in FLGn (interrupt) + */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Low Power --"); + if (USBPD_PWR_PortCompDrv[PortNum]->SetPowerMode(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_POWER_MODE_LOWPOWER) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + break; + + case USBPD_PWR_MODE_NORMAL: + /* Port Mode is Normal : No power saving measure (Explicit contract in place) */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Normal --"); + if (USBPD_PWR_PortCompDrv[PortNum]->SetPowerMode(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_POWER_MODE_NORMAL) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + break; + + default: + ret = BSP_ERROR_WRONG_PARAM; + break; + } + + /* Set port low power operating mode */ + USBPD_PWR_Port_Status[PortNum].PwrSavingMode = PwrMode; + } + + return ret; +} + +/** + * @brief Get operating mode of Port regarding power saving constraints + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param PwrMode Pointer on current Type-C port power saving mode value + * Following values are available : + * @arg @ref USBPD_PWR_MODE_OFF + * @arg @ref USBPD_PWR_MODE_HIBERNATE + * @arg @ref USBPD_PWR_MODE_LOWPOWER + * @arg @ref USBPD_PWR_MODE_NORMAL + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_GetPowerMode(uint32_t PortNum, USBPD_PWR_PowerModeTypeDef *PwrMode) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_GetPowerMode --"); + + /* Get port low power operating mode */ + *PwrMode = USBPD_PWR_Port_Status[PortNum].PwrSavingMode; + } + + return ret; +} + +/** + * @brief Initialize the hardware resources used by the Type-C power delivery (PD) + * controller. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSInit(uint32_t PortNum) +{ + int32_t ret; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VBUSInit --"); + + /* Initialize required HW for VBUS management */ + switch (USBPD_PWR_Port_Configs[PortNum].Type) + { + case USBPD_PWR_HW_CONFIG_TYPE_TCPP02: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP03: + /* Switch to Normal mode */ + ret = BSP_USBPD_PWR_SetPowerMode(PortNum, USBPD_PWR_MODE_NORMAL); + + PWR_TCPP0203_Configure_ADC(); + break; + + case USBPD_PWR_HW_CONFIG_TYPE_DEFAULT: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP01: + default: + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + break; + } + } + return ret; +} + +/** + * @brief Release the hardware resources used by the Type-C power delivery (PD) + * controller. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSDeInit(uint32_t PortNum) +{ + int32_t ret; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VBUSDeInit --"); + + /* Only for TCPP03 */ + if (USBPD_PWR_HW_CONFIG_TYPE_TCPP03 == USBPD_PWR_Port_Configs[PortNum].Type) + { + /* Close Gate Driver Consumer, only for TCPP03 */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetGateDriverConsumer(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_CONSUMER_SWITCH_CLOSED) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + return ret; + } + } + + /* Common for TCPP02 / TCPP03 */ + if ((USBPD_PWR_HW_CONFIG_TYPE_TCPP02 == USBPD_PWR_Port_Configs[PortNum].Type) || + (USBPD_PWR_HW_CONFIG_TYPE_TCPP03 == USBPD_PWR_Port_Configs[PortNum].Type)) + { + /* Restore default gates configuration for Low power mode */ + BSP_USBPD_PWR_TRACE(PortNum, "-- GDP/GDC setting : default --"); + + if (USBPD_PWR_Port_Status[PortNum].PwrRole == POWER_ROLE_SOURCE) + { + /* Switch to Low Power mode */ + ret = BSP_USBPD_PWR_SetPowerMode(PortNum, USBPD_PWR_MODE_LOWPOWER); + } + else + { + /* Switch to Hibernate mode */ + ret = BSP_USBPD_PWR_SetPowerMode(PortNum, USBPD_PWR_MODE_HIBERNATE); + } + } + else + { + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + } + return ret; +} + +/** + * @brief Enable power supply over VBUS. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSOn(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VBUSOn --"); + + /* Port Role is now SRC : Close Gate Driver Provider */ + if (USBPD_PWR_Port_Status[PortNum].PwrRole == POWER_ROLE_SOURCE) + { + /* Only for TCPP03 */ + if (USBPD_PWR_HW_CONFIG_TYPE_TCPP03 == USBPD_PWR_Port_Configs[PortNum].Type) + { + /* Open Gate Driver Consumer, only for TCPP03 */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetGateDriverConsumer(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_CONSUMER_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + return ret; + } + } + + /* Common for TCPP02 / TCPP03 */ + if ((USBPD_PWR_HW_CONFIG_TYPE_TCPP02 == USBPD_PWR_Port_Configs[PortNum].Type) || + (USBPD_PWR_HW_CONFIG_TYPE_TCPP03 == USBPD_PWR_Port_Configs[PortNum].Type)) + { + HAL_Delay(2); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetGateDriverProvider(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_PROVIDER_SWITCH_CLOSED) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + BSP_USBPD_PWR_TRACE(PortNum, "-- GDP/GDC setting : SRC --"); + } + else + { + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + } + else + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + return ret; +} + +/** + * @brief Disable power supply over VBUS. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSOff(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t vbus; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Open Gate driver provider */ + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VBUSOff --"); + if (USBPD_PWR_PortCompDrv[PortNum]->SetGateDriverProvider(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_PROVIDER_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Set Discharge On */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetVBusDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VBUS_DISCHARGE_ON) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Wait VBUS level becomes lower than USBPD_PWR_LOW_VBUS_THRESHOLD */ + uint8_t counter = 0U; + + (void)BSP_USBPD_PWR_VBUSGetVoltage(PortNum, &vbus); + + while ((vbus >= (USBPD_PWR_LOW_VBUS_THRESHOLD - 200U)) && (counter < 20U)) + { + counter++; + HAL_Delay(20); + (void)BSP_USBPD_PWR_VBUSGetVoltage(PortNum, &vbus); + } + + /* Set Discharge Off */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetVBusDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VBUS_DISCHARGE_OFF) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + HAL_Delay(30); + + /* Only for TCPP03 */ + if (USBPD_PWR_HW_CONFIG_TYPE_TCPP03 == USBPD_PWR_Port_Configs[PortNum].Type) + { + /* Close Gate Driver Consumer, only for TCPP03 */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetGateDriverConsumer(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_CONSUMER_SWITCH_CLOSED) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + } + } + return ret; +} + +/** + * @brief Get actual VBUS status. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param pState VBUS status (1: On, 0: Off) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSIsOn(uint32_t PortNum, uint8_t *pState) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t val = 0U; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (USBPD_PWR_PortCompDrv[PortNum]->GetGateDriverProviderAck(&USBPD_PWR_PortCompObj[PortNum], + &val) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (val == TCPP0203_GD_PROVIDER_SWITCH_ACK_OPEN) + { + *pState = 0U; + } + else + { + *pState = 1U; + } + } + } + return ret; +} + +/** + * @brief Set a fixed PDO and manage the power control. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param VbusTargetInmv the vbus Target (in mV) + * @param OperatingCurrent the Operating Current (in mA) + * @param MaxOperatingCurrent the Max Operating Current (in mA) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSSetVoltage_Fixed(uint32_t PortNum, + uint32_t VbusTargetInmv, + uint32_t OperatingCurrent, + uint32_t MaxOperatingCurrent) +{ + int32_t ret = BSP_ERROR_NONE; + UNUSED(MaxOperatingCurrent); + UNUSED(OperatingCurrent); + UNUSED(VbusTargetInmv); + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + return ret; +} + +/** + * @brief Set a variable PDO and manage the power control. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param VbusTargetMinInmv the vbus Target min (in mV) + * @param VbusTargetMaxInmv the vbus Target max (in mV) + * @param OperatingCurrent the Operating Current (in mA) + * @param MaxOperatingCurrent the Max Operating Current (in mA) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSSetVoltage_Variable(uint32_t PortNum, + uint32_t VbusTargetMinInmv, + uint32_t VbusTargetMaxInmv, + uint32_t OperatingCurrent, + uint32_t MaxOperatingCurrent) +{ + int32_t ret; + UNUSED(MaxOperatingCurrent); + UNUSED(OperatingCurrent); + UNUSED(VbusTargetMaxInmv); + UNUSED(VbusTargetMinInmv); + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + return ret; +} + +/** + * @brief Set a Battery PDO and manage the power control. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param VbusTargetMin the vbus Target min (in mV) + * @param VbusTargetMax the vbus Target max (in mV) + * @param OperatingPower the Operating Power (in mW) + * @param MaxOperatingPower the Max Operating Power (in mW) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSSetVoltage_Battery(uint32_t PortNum, + uint32_t VbusTargetMin, + uint32_t VbusTargetMax, + uint32_t OperatingPower, + uint32_t MaxOperatingPower) +{ + int32_t ret; + UNUSED(OperatingPower); + UNUSED(VbusTargetMax); + UNUSED(VbusTargetMin); + UNUSED(MaxOperatingPower); + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Set the power, the precision must be at 5% */ + /* Set the current limitation */ + /* not implemented */ + + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + return ret; +} + +/** + * @brief Set a APDO and manage the power control. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param VbusTargetInmv the vbus Target (in mV) + * @param OperatingCurrent the Operating current (in mA) + * @param Delta Delta between with previous APDO (in mV), 0 means APDO start + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSSetVoltage_APDO(uint32_t PortNum, + uint32_t VbusTargetInmv, + uint32_t OperatingCurrent, + int32_t Delta) +{ + int32_t ret; + UNUSED(Delta); + UNUSED(OperatingCurrent); + UNUSED(VbusTargetInmv); + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + return ret; +} + +/** + * @brief Set the VBUS disconnection voltage threshold. + * @note Callback function invoked when VBUS falls below programmed threshold. + * @note By default VBUS disconnection threshold is set to 3.3V + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param VoltageThreshold VBUS disconnection voltage threshold (in mV) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_SetVBUSDisconnectionThreshold(uint32_t PortNum, + uint32_t VoltageThreshold) +{ + UNUSED(VoltageThreshold); + int32_t ret; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + ret = BSP_ERROR_FEATURE_NOT_SUPPORTED; + } + return ret; +} + +/** + * @brief Register USB Type-C Current callback function. + * @note Callback function invoked when VBUS rises above 4V (VBUS present) or + * when VBUS falls below programmed threshold (VBUS absent). + * @note Callback function is un-registered when callback function pointer + * argument is NULL. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param pfnVBUSDetectCallback callback function pointer + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_RegisterVBUSDetectCallback(uint32_t PortNum, + USBPD_PWR_VBUSDetectCallbackFunc *pfnVBUSDetectCallback) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if ((PortNum >= USBPD_PWR_INSTANCES_NBR) || (NULL == pfnVBUSDetectCallback)) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Set port callback for VBUS detection event */ + USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback = pfnVBUSDetectCallback; + } + return ret; +} + +/** + * @brief Get actual voltage level measured on the VBUS line. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param pVoltage Pointer on measured voltage level (in mV) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSGetVoltage(uint32_t PortNum, uint32_t *pVoltage) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if ((PortNum >= USBPD_PWR_INSTANCES_NBR) || (NULL == pVoltage)) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + uint32_t voltage; + static __IO uint16_t adc_value; + adc_value = LL_ADC_REG_ReadConversionData12(TCPP0203_PORT0_VBUSC_ADC_INSTANCE); + voltage = PWR_TCPP0203_ConvertADCDataToVoltage(adc_value, TCPP0203_PORT0_VBUSC_RA, TCPP0203_PORT0_VBUSC_RB); + + *pVoltage = voltage; + } + return ret; +} + +/** + * @brief Get actual current level measured on the VBUS line. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param pCurrent Pointer on measured current level (in mA) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSGetCurrent(uint32_t PortNum, int32_t *pCurrent) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if ((PortNum >= USBPD_PWR_INSTANCES_NBR) || (NULL == pCurrent)) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + int32_t current; + uint16_t adc_value; + adc_value = 0U; /* Not implemented */ + current = PWR_TCPP0203_ConvertADCDataToCurrent(adc_value, + TCPP0203_PORT0_IANA_ISENSE_GA, TCPP0203_PORT0_IANA_ISENSE_RS); + + *pCurrent = current; + } + return ret; +} + +/** + * @brief Activate discharge on VBUS. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSDischargeOn(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VBUSDischargeOn --"); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetGateDriverProvider(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_PROVIDER_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (USBPD_PWR_PortCompDrv[PortNum]->SetVBusDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VBUS_DISCHARGE_ON) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + return ret; +} + +/** + * @brief Deactivate discharge on VBUS. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VBUSDischargeOff(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VBUSDischargeOff --"); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetVBusDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VBUS_DISCHARGE_OFF) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + return ret; +} + +/** + * @brief Initialize VCONN sourcing. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param CCPinId Type-C CC pin identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_CC1 + * @arg @ref USBPD_PWR_TYPE_C_CC2 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNInit(uint32_t PortNum, + uint32_t CCPinId) +{ + UNUSED(CCPinId); + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* No specific treatment required for initialising VCONN management from TCPP03 */ + /* Initialise VCONN management from TCPP03 : + Ensure VCONN switch to Open/Open + Ensure VCONN Discharge OFF + */ + + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VCONNInit --"); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnSwitch(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_DISCHARGE_OFF) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + return ret; +} + +/** + * @brief De-initialize VCONN sourcing. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param CCPinId Type-C CC pin identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_CC1 + * @arg @ref USBPD_PWR_TYPE_C_CC2 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNDeInit(uint32_t PortNum, + uint32_t CCPinId) +{ + UNUSED(CCPinId); + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* De-initialise VCONN management from TCPP03 : + Force VCONN switch to Open/Open + Force VCONN Discharge OFF + */ + + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VCONNDeInit --"); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnSwitch(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_DISCHARGE_OFF) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + return ret; +} + +/** + * @brief Enable VCONN sourcing. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param CCPinId Type-C CC pin identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_CC1 + * @arg @ref USBPD_PWR_TYPE_C_CC2 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNOn(uint32_t PortNum, + uint32_t CCPinId) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if parameters are valid */ + if ((PortNum >= USBPD_PWR_INSTANCES_NBR) + || ((CCPinId != USBPD_PWR_TYPE_C_CC1) && (CCPinId != USBPD_PWR_TYPE_C_CC2)) + ) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Set TCPP0203 VCONN Switch according to CC pin used for VCONN */ + if (CCPinId == USBPD_PWR_TYPE_C_CC1) + { + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnSwitch(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_SWITCH_CC1) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + else + { + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnSwitch(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_SWITCH_CC2) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + return ret; +} + +/** + * @brief Disable VCONN sourcing. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param CCPinId CC pin identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_CC1 + * @arg @ref USBPD_PWR_TYPE_C_CC2 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNOff(uint32_t PortNum, + uint32_t CCPinId) +{ + UNUSED(CCPinId); + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Switch off VCONN : restore VCONN switch to Open/open position */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnSwitch(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Discharge VCONN path */ + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_DISCHARGE_ON) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Wait DISCHARGE is completed then disable VCONN Discharge */ + HAL_Delay(10U); + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_DISCHARGE_OFF) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + } + return ret; +} + +/** + * @brief Get actual VCONN status. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @param CCPinId Type-C CC pin identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_CC1 + * @arg @ref USBPD_PWR_TYPE_C_CC2 + * @param pState VCONN status (1: On, 0: Off) + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNIsOn(uint32_t PortNum, + uint32_t CCPinId, uint8_t *pState) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t vconnSwitch = 0U; + + /* Check if parameters are valid */ + if ((PortNum >= USBPD_PWR_INSTANCES_NBR) || (NULL == pState) + || ((CCPinId != USBPD_PWR_TYPE_C_CC1) && (CCPinId != USBPD_PWR_TYPE_C_CC2)) + ) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + *pState = 0U; + + /* Get TCPP0203 VCONN Switch position */ + if (USBPD_PWR_PortCompDrv[PortNum]->GetVConnSwitchAck(&USBPD_PWR_PortCompObj[PortNum], + &vconnSwitch) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (((CCPinId == USBPD_PWR_TYPE_C_CC1) && (vconnSwitch == TCPP0203_VCONN_SWITCH_CC1)) + || ((CCPinId == USBPD_PWR_TYPE_C_CC2) && (vconnSwitch == TCPP0203_VCONN_SWITCH_CC2)) + ) + { + *pState = 1U; + } + } + } + return ret; +} + +/** + * @brief Activate discharge on VCONN. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNDischargeOn(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VCONNDischargeOn --"); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnSwitch(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_SWITCH_OPEN) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_DISCHARGE_ON) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + return ret; +} + +/** + * @brief Deactivate discharge on VCONN. + * @param PortNum Type-C port identifier + * This parameter can take one of the following values: + * @arg @ref USBPD_PWR_TYPE_C_PORT_1 + * @retval BSP status + */ +int32_t BSP_USBPD_PWR_VCONNDischargeOff(uint32_t PortNum) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if instance is valid */ + if (PortNum >= USBPD_PWR_INSTANCES_NBR) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_VCONNDischargeOff --"); + + if (USBPD_PWR_PortCompDrv[PortNum]->SetVConnDischarge(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_VCONN_DISCHARGE_OFF) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + return ret; +} + +/** + * @brief USBPD PWR callback used to notify a asynchronous PWR event. + * (This callback caould be called fromp an IT routine, associated to + * any PWR related event detection mechanism) + * @param PortNum Type-C port identifier + * @retval None + */ +void BSP_USBPD_PWR_EventCallback(uint32_t PortNum) +{ + BSP_USBPD_PWR_TRACE(PortNum, "-- BSP_USBPD_PWR_EventCallback --"); + + /* Handle USBPD PWR event */ + switch (USBPD_PWR_Port_Configs[PortNum].Type) + { + case USBPD_PWR_HW_CONFIG_TYPE_TCPP02: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP03: + /* In case of TCPP0203, this callback could be called when an event is detected + on FLGn line */ + PWR_TCPP0203_EventCallback(PortNum); + break; + + case USBPD_PWR_HW_CONFIG_TYPE_DEFAULT: + case USBPD_PWR_HW_CONFIG_TYPE_TCPP01: + default: + break; + } +} + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_USBPD_PWR_Private_Functions + * @{ + */ + + +/** + * @brief Configure TCPP0203 used GPIO. + * @note GPIO used for TCPP0203 operation includes VBUS measurement, ENABLE pin driving + * @param PortNum Port number + * @retval None + */ +static void PWR_TCPP0203_GPIOConfigInit(uint32_t PortNum) +{ + UNUSED(PortNum); + + /* Configure ENABLE GPIO */ + TCPP0203_PORT0_ENABLE_GPIO_CLK_ENABLE(); + /* Configure IO in output push-pull mode to drive ENABLE */ + LL_GPIO_SetPinMode(TCPP0203_PORT0_ENABLE_GPIO_PORT, TCPP0203_PORT0_ENABLE_GPIO_PIN, TCPP0203_PORT0_ENABLE_GPIO_MODE); + LL_GPIO_SetPinOutputType(TCPP0203_PORT0_ENABLE_GPIO_PORT, TCPP0203_PORT0_ENABLE_GPIO_PIN, + TCPP0203_PORT0_ENABLE_GPIO_OUTPUT); + LL_GPIO_SetPinSpeed(TCPP0203_PORT0_ENABLE_GPIO_PORT, TCPP0203_PORT0_ENABLE_GPIO_PIN, LL_GPIO_SPEED_FREQ_LOW); + LL_GPIO_SetPinPull(TCPP0203_PORT0_ENABLE_GPIO_PORT, TCPP0203_PORT0_ENABLE_GPIO_PIN, TCPP0203_PORT0_ENABLE_GPIO_PUPD); + + /* Set ENABLE to default state */ + TCPP0203_PORT0_ENABLE_GPIO_DEFVALUE(); + + /* Configure IANA GPIO */ + TCPP0203_PORT0_IANA_GPIO_CLK_ENABLE(); + /* Configure GPIO in Analog mode */ + LL_GPIO_SetPinMode(TCPP0203_PORT0_IANA_GPIO_PORT, TCPP0203_PORT0_IANA_GPIO_PIN, TCPP0203_PORT0_IANA_GPIO_MODE); + + /* Configure VBUS Connector sensing GPIO */ + TCPP0203_PORT0_VBUSC_GPIO_CLK_ENABLE(); + /* Configure GPIO in Analog mode */ + LL_GPIO_SetPinMode(TCPP0203_PORT0_VBUSC_GPIO_PORT, TCPP0203_PORT0_VBUSC_GPIO_PIN, TCPP0203_PORT0_VBUSC_GPIO_MODE); +} + +/** + * @brief Configure ADC (ADC instance for Vsense and Isense: TCPP0203_PORT0_VBUSC_ADC_INSTANCE) and GPIO used by ADC channels. + * @retval None + */ +static void PWR_TCPP0203_Configure_ADC(void) +{ + static ADC_HandleTypeDef hadc; + + /* USER CODE BEGIN ADC_Init 0 */ + TCPP0203_PORT0_VBUSC_ADC_CLK_ENABLE(); + + /* Configure the GPIO as analog */ + TCPP0203_PORT0_VBUSC_GPIO_CLK_ENABLE(); + LL_GPIO_SetPinMode(TCPP0203_PORT0_VBUSC_GPIO_PORT, TCPP0203_PORT0_VBUSC_GPIO_PIN, TCPP0203_PORT0_VBUSC_GPIO_MODE); + + /* USER CODE END ADC1_Init 0 */ + + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInitStructure; + RCC_PeriphClkInitStructure.PeriphClockSelection = RCC_PERIPHCLK_ADC; + RCC_PeriphClkInitStructure.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP; + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInitStructure) != HAL_OK) + { + } + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC_Init 1 */ + + /* USER CODE END ADC_Init 1 */ + /* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ + hadc.Instance = TCPP0203_PORT0_VBUSC_ADC_INSTANCE; + hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; + hadc.Init.Resolution = ADC_RESOLUTION_12B; + hadc.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + hadc.Init.LowPowerAutoWait = DISABLE; + hadc.Init.ContinuousConvMode = ENABLE; + hadc.Init.NbrOfConversion = 1; + hadc.Init.DiscontinuousConvMode = DISABLE; + hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; + hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; + hadc.Init.OversamplingMode = DISABLE; + if (HAL_ADC_Init(&hadc) != HAL_OK) + { + } + + /* Configure Regular Channel */ + sConfig.Channel = TCPP0203_PORT0_VBUSC_ADC_CHANNEL; + sConfig.Rank = TCPP0203_PORT0_VBUSC_ADC_RANK; + sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; + sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */ + sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */ + sConfig.Offset = 0U; /* Parameter discarded because offset correction is disabled */ + sConfig.OffsetSaturation = DISABLE; + sConfig.OffsetSign = ADC_OFFSET_SIGN_POSITIVE; + + if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) + { + } + + /* USER CODE BEGIN ADC_Init 2 */ + if (HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK) + { + } + + if (HAL_ADC_Start(&hadc) != HAL_OK) + { + } + /* USER CODE END ADC_Init 2 */ +} + +/** + * @brief Configure TCPP0203 low level interrupt. + * @note Corresponds to EXTI mapped onto FLGn pin of TCPP0203 + * @param PortNum Port number + * @retval None + */ +static void PWR_TCPP0203_ITConfigInit(uint32_t PortNum) +{ + if (USBPD_PWR_Port_Status[PortNum].IsItEnabled == 0U) + { + USBPD_PWR_Port_Status[PortNum].IsItEnabled = 1U; + + /* Enable the GPIO EXTI clock */ + TCPP0203_PORT0_FLG_GPIO_CLK_ENABLE(); + /* Configure IO */ + LL_GPIO_SetPinMode(TCPP0203_PORT0_FLG_GPIO_PORT, TCPP0203_PORT0_FLG_GPIO_PIN, TCPP0203_PORT0_FLG_GPIO_MODE); + LL_GPIO_SetPinPull(TCPP0203_PORT0_FLG_GPIO_PORT, TCPP0203_PORT0_FLG_GPIO_PIN, TCPP0203_PORT0_FLG_GPIO_PUPD); + + /* Connect External Line to the GPIO*/ + TCPP0203_PORT0_FLG_SET_EXTI(); + + /* Enable a falling trigger EXTI line x Interrupt */ + TCPP0203_PORT0_FLG_EXTI_ENABLE(); + TCPP0203_PORT0_FLG_TRIG_ENABLE(); + + /* Configure NVIC for EXTIx_IRQn */ + NVIC_SetPriority(TCPP0203_PORT0_FLG_EXTI_IRQN, TCPP0203_PORT0_FLG_IT_PRIORITY); + NVIC_EnableIRQ(TCPP0203_PORT0_FLG_EXTI_IRQN); + } +} + +/** + * @brief I2C BUS registration for TCPP0203 communication + * @param PortNum Port number + * @param Address I2C Address + * @retval BSP status + */ +static int32_t PWR_TCPP0203_BUSConfigInit(uint32_t PortNum, uint16_t Address) +{ + int32_t ret = BSP_ERROR_NONE; + TCPP0203_IO_t TCPP0203IOCtx; + uint8_t tcpp_type = 0U; + + /* Configure the TCPP0203 I2C driver */ + TCPP0203IOCtx.Address = Address; + TCPP0203IOCtx.Init = BSP_I2C1_Init; + TCPP0203IOCtx.DeInit = BSP_I2C1_DeInit; + TCPP0203IOCtx.ReadReg = BSP_I2C1_ReadReg; + TCPP0203IOCtx.WriteReg = BSP_I2C1_WriteReg; + TCPP0203IOCtx.GetTick = BSP_GetTick; + + /* Register the component on BUS IO */ + if (TCPP0203_RegisterBusIO(&USBPD_PWR_PortCompObj[PortNum], &TCPP0203IOCtx) != TCPP0203_OK) + { + ret = BSP_ERROR_BUS_FAILURE; + } + else + { + /* Initialisation step */ + USBPD_PWR_PortCompDrv[PortNum] = &TCPP0203_Driver; + if (USBPD_PWR_PortCompDrv[PortNum]->Init(&USBPD_PWR_PortCompObj[PortNum]) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Read the component type */ + if (USBPD_PWR_PortCompDrv[PortNum]->ReadTCPPType(&USBPD_PWR_PortCompObj[PortNum], &tcpp_type) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Check the component type and update config accordingly */ + switch (tcpp_type) + { + case TCPP0203_DEVICE_TYPE_02: + USBPD_PWR_Port_Configs[PortNum].Type = USBPD_PWR_HW_CONFIG_TYPE_TCPP02; + BSP_USBPD_PWR_TRACE(PortNum, "-- TCPP02 detected"); + break; + + case TCPP0203_DEVICE_TYPE_03: + USBPD_PWR_Port_Configs[PortNum].Type = USBPD_PWR_HW_CONFIG_TYPE_TCPP03; + BSP_USBPD_PWR_TRACE(PortNum, "-- TCPP03 detected"); + break; + + default: + USBPD_PWR_Port_Configs[PortNum].Type = USBPD_PWR_HW_CONFIG_TYPE_DEFAULT; + BSP_USBPD_PWR_TRACE(PortNum, "-- Unknown TCPP type"); + ret = BSP_ERROR_UNKNOWN_COMPONENT; + break; + } + + if (ret == BSP_ERROR_NONE) + { + /* Reset TCPP0203 Reg0 register */ + if (USBPD_PWR_PortCompDrv[PortNum]->Reset(&USBPD_PWR_PortCompObj[PortNum]) != TCPP0203_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Registration completed */ + } + } + return ret; +} + +/** + * @brief De-Initialize TCPP0203 HW resources associated to Type-C port + * @param PortNum Port number + * @retval BSP Status + */ +static int32_t PWR_TCPP0203_ConfigDeInit(uint32_t PortNum) +{ + UNUSED(PortNum); + return (BSP_ERROR_NONE); +} + +/** + * @brief Handle Event callback + * @param PortNum Port number + * @retval None + */ +static void PWR_TCPP0203_EventCallback(uint32_t PortNum) +{ + uint8_t flg_reg = 0U; + + /* In case of TCPP0203, this callback could be called when an event is detected + on FLGn line */ + if (USBPD_PWR_Port_Status[PortNum].IsInitialized == 1U) + { + /* Read Flags register (FLGn) */ + if (USBPD_PWR_PortCompDrv[PortNum]->ReadFlagRegister(&USBPD_PWR_PortCompObj[PortNum], &flg_reg) == TCPP0203_OK) + { +#ifdef _TRACE + char _str[13U]; + (void)sprintf(_str, "Reg2_0x%02x", flg_reg); + BSP_USBPD_PWR_TRACE(PortNum, _str); +#endif /* _TRACE */ + + /* If FLGn has been set to 0 in LOW POWER or HIBERNATE mode, + it is expected that a VBUS_OK condition is detected. + In this case, if any, vBus Detection callback could be called */ + switch (USBPD_PWR_Port_Status[PortNum].PwrSavingMode) + { + case USBPD_PWR_MODE_HIBERNATE: + { + if ((flg_reg & TCPP0203_FLAG_VBUS_OK_SET) == TCPP0203_FLAG_VBUS_OK_SET) + { + if (USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback != NULL) + { + /* In case of TCPP03 in Hibernate Mode (SNK config), + Mode is set to Low power to enable TCPP03 behavior on CC lines */ + /* Switch to Low Power mode */ + (void)BSP_USBPD_PWR_SetPowerMode(PortNum, USBPD_PWR_MODE_LOWPOWER); + + USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback(PortNum, VBUS_CONNECTED); + } + } + else + { + /* In all other cases (NORMAL mode), FLGn signals fault detection events. */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Wrong detection --"); + } + break; + } + + case USBPD_PWR_MODE_LOWPOWER: + { + if ((flg_reg & TCPP0203_FLAG_VBUS_OK_SET) == TCPP0203_FLAG_VBUS_OK_SET) + { + if (USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback != NULL) + { + USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback(PortNum, VBUS_CONNECTED); + } + } + else + { + /* In all other cases (NORMAL mode), FLGn signals fault detection events. */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Wrong detection --"); + } + break; + } + + case USBPD_PWR_MODE_NORMAL: + { + uint32_t tickfault = HAL_GetTick(); + uint8_t recoveryword; + + /* In all other cases (NORMAL mode), FLGn signals fault detection events. */ + /* Check type of error raised in FLGn */ + if ((flg_reg & TCPP0203_FLAG_OCP_VCONN_SET) == TCPP0203_FLAG_OCP_VCONN_SET) + { + BSP_USBPD_PWR_TRACE(PortNum, "-- OCP VCONN detected --"); + } + if ((flg_reg & TCPP0203_FLAG_OCP_VBUS_SET) == TCPP0203_FLAG_OCP_VBUS_SET) + { + BSP_USBPD_PWR_TRACE(PortNum, "-- OCP VBUS detected --"); + + /* Check if detected fault could be recovered */ + /* In case of OCP fault, allow to restart and check if a 2nd OCP fault occurs in a limited time */ + if ((tickfault > USBPD_PWR_Port_Status[PortNum].LastFaultTick) + && ((tickfault - USBPD_PWR_Port_Status[PortNum].LastFaultTick) > USBPD_PWR_FAULT_MIN_TIME_RECOVERY)) + { + /* Send Recovery word to TCPP0203 : + GDC and GDP open (TCPP0203_GD_PROVIDER_SWITCH_OPEN is 0) */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Send Recovery Word --"); + recoveryword = TCPP0203_GD_CONSUMER_SWITCH_OPEN | TCPP0203_POWER_MODE_NORMAL; + (void)TCPP0203_WriteCtrlRegister(&USBPD_PWR_PortCompObj[PortNum], &recoveryword); + + /* In case PWR Role is SRC, try to restore VBUS as soon as possible */ + if (USBPD_PWR_Port_Status[PortNum].PwrRole == POWER_ROLE_SOURCE) + { + (void)TCPP0203_SetPowerMode(&USBPD_PWR_PortCompObj[PortNum], TCPP0203_POWER_MODE_NORMAL); + (void)TCPP0203_SetGateDriverProvider(&USBPD_PWR_PortCompObj[PortNum], + TCPP0203_GD_PROVIDER_SWITCH_CLOSED); + BSP_USBPD_PWR_TRACE(PortNum, "-- GDP/GDC setting : SRC (Restored) --"); + } + else + { + if (USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback != NULL) + { + /* Notify Error thanks to callback */ + USBPD_PWR_Port_Status[PortNum].VBUSDetectCallback(PortNum, VBUS_NOT_CONNECTED); + } + } + } + USBPD_PWR_Port_Status[PortNum].LastFaultTick = tickfault; + } + if ((flg_reg & TCPP0203_FLAG_OVP_VBUS_SET) == TCPP0203_FLAG_OVP_VBUS_SET) + { + BSP_USBPD_PWR_TRACE(PortNum, "-- OVP VBUS detected --"); + } + if ((flg_reg & TCPP0203_FLAG_OTP_SET) == TCPP0203_FLAG_OTP_SET) + { + BSP_USBPD_PWR_TRACE(PortNum, "-- Over Temp detected --"); + } + if ((flg_reg & TCPP0203_FLAG_OVP_CC_SET) == TCPP0203_FLAG_OVP_CC_SET) + { + BSP_USBPD_PWR_TRACE(PortNum, "-- OVP CC detected --"); + } + break; + } + + default: + { + /* Unexpected port state */ + BSP_USBPD_PWR_TRACE(PortNum, "-- Unexpected State for FLGn event --"); + break; + } + } + } + } +} + +/** + * @brief Calculate the VBUS voltage level corresponding to ADC raw converted data. + * @note Voltage level is measured though a voltage divider + * Example : + * Voltage -- Ra ----.- ^ + * | | + * Rb | vadc = VBUS * Rb /(Ra + Rb) + * | | + * GND | + * vadc = raw_data * (ADC_FULL_SCALE / VDD) + * @param ADCData ADC raw converted data (resolution 12 bits) + * @param Ra value of Ra resistance + * @param Rb value of Rb resistance + * @retval analog voltage (unit: mV) + */ +static uint32_t PWR_TCPP0203_ConvertADCDataToVoltage(uint32_t ADCData, uint32_t Ra, uint32_t Rb) +{ + uint32_t voltage; + uint32_t vadc; + + voltage = 0U; + + /* Avoid dividing by zero */ + if (IS_PWR_TCPP0203_NOT_ZERO(Rb)) + { + vadc = (ADCData * VDD_VALUE) / ADC_FULL_SCALE; + voltage = vadc * (Ra + Rb) / Rb; + } + + return voltage; +} + +/** + * @brief Calculate the VBUS current level corresponding to ADC raw converted data. + * @note ADC measurement provides measurement on IANA pin. + * @param ADCData ADC raw converted data (resolution 12 bits) + * @param Ga value of TCPP0X Iana gain in V/V + * @param Rs value of shunt resistor in milliohm + * @retval VBUS analog current (unit: mA) + */ +static int32_t PWR_TCPP0203_ConvertADCDataToCurrent(uint32_t ADCData, uint32_t Ga, uint32_t Rs) +{ + int32_t current; + uint32_t vadc; + + current = 0; + + /* Avoid dividing by zero */ + if (IS_PWR_TCPP0203_NOT_ZERO(Ga * Rs)) + { + vadc = (ADCData * VDD_VALUE) / ADC_FULL_SCALE; + current = ((int32_t)vadc * 1000) / ((int32_t)Ga * (int32_t)Rs); + } + + return current; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.h new file mode 100644 index 0000000..c21a388 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_usbpd_pwr.h @@ -0,0 +1,337 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_usbpd_pwr.h + * @author MCD Application Team + * @brief Header file for stm32h7s78_discovery_usbpd_pwr.c 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7S78_DISCOVERY_USBPD_PWR_H +#define STM32H7S78_DISCOVERY_USBPD_PWR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" +#include "stm32h7rsxx_hal_adc.h" +#include "stm32h7rsxx_ll_bus.h" +#include "stm32h7rsxx_ll_gpio.h" +#include "stm32h7rsxx_ll_exti.h" +#include "stm32h7rsxx_ll_system.h" +#include "../Components/tcpp0203/tcpp0203.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup USBPD_PWR USBPD_PWR + * @{ + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Exported_Types Exported Types + * @{ + */ + +#if !defined(USBPD_PWR_USER_H_) + +/** + * @brief Power role + */ +typedef enum +{ + POWER_ROLE_SOURCE = 0, + POWER_ROLE_SINK, + POWER_ROLE_DUAL +} USBPD_PWR_PowerRoleTypeDef; + +/** + * @brief Low Power Mode of TypeC ports + */ +typedef enum +{ + USBPD_PWR_MODE_OFF = 0, + USBPD_PWR_MODE_HIBERNATE, + USBPD_PWR_MODE_LOWPOWER, + USBPD_PWR_MODE_NORMAL +} USBPD_PWR_PowerModeTypeDef; + +/** + * @brief VBUS connection status + */ +typedef enum +{ + VBUS_CONNECTED = 0, + VBUS_NOT_CONNECTED +} USBPD_PWR_VBUSConnectionStatusTypeDef; + +/** + * @brief ADC buffer identifiers + */ +typedef enum +{ + ADCBUF_VSENSE = 0, + ADCBUF_ISENSE +} USBPD_PWR_ADCBufIDTypeDef; + +/** + * @brief VBUS Detection Callback + */ +typedef void USBPD_PWR_VBUSDetectCallbackFunc(uint32_t PortNum, + USBPD_PWR_VBUSConnectionStatusTypeDef VBUSConnectionStatus); + +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Exported_Constants Exported Constants + * @{ + */ +/** + * @brief HW configuration type of TypeC ports + */ +#define USBPD_PWR_HW_CONFIG_TYPE_DEFAULT (0U) /*!< Default configuration : + Port available natively on board, no protection */ +#define USBPD_PWR_HW_CONFIG_TYPE_TCPP01 (1U) /*!< TypeC Port protection available + thanks to a TCPP01 component */ +#define USBPD_PWR_HW_CONFIG_TYPE_TCPP02 (2U) /*!< TypeC Port protection available + thanks to a TCPP02 component */ +#define USBPD_PWR_HW_CONFIG_TYPE_TCPP03 (3U) /*!< TypeC Port protection available + thanks to a TCPP03 component */ + + +/** + * @brief Number of TypeC ports + */ +#define USBPD_PWR_INSTANCES_NBR (1U) + +/** + * @brief Type-C port identifier + */ +#define USBPD_PWR_TYPE_C_PORT_1 (0U) +#define USBPD_PWR_TYPE_C_PORT_2 (1U) +#define USBPD_PWR_TYPE_C_PORT_3 (2U) + +/** + * @brief CC pin identifier + */ +#define USBPD_PWR_TYPE_C_CC1 (1U) +#define USBPD_PWR_TYPE_C_CC2 (2U) + +/** + * @brief VBUS disconnection threshold values (in mV) + */ +#define USBPD_PWR_HIGH_VBUS_THRESHOLD (2800U) +#define USBPD_PWR_LOW_VBUS_THRESHOLD (750U) +#define USBPD_PWR_VBUS_THRESHOLD_5V (3900U) +#define USBPD_PWR_VBUS_THRESHOLD_9V (7000U) +#define USBPD_PWR_VBUS_THRESHOLD_15V (12500U) +#define USBPD_PWR_VBUS_THRESHOLD_20V (17000U) +#define USBPD_PWR_VBUS_THRESHOLD_APDO (2150U) + +/** + * @brief VBUS discharge parameters + */ +#define USBPD_PWR_DISCHARGE_MARGIN (500U) +#define USBPD_PWR_DISCHARGE_TIME (6U) + +/** + * @brief Standard VBUS voltage levels + */ +#define USBPD_PWR_VBUS_5V 5000U +#define USBPD_PWR_VBUS_9V 9000U +#define USBPD_PWR_VBUS_15V 15000U + +/** + * @brief power timeout + */ +#define USBPD_PWR_TIMEOUT_PDO 250U /* Timeout for PDO to PDO or PDO to APDO at 250ms */ +#define USBPD_PWR_TIMEOUT_APDO 25U /* Timeout for APDO to APDO at 25ms */ + +/** + * @brief Invalid value set during issue with voltage setting + */ +#define USBPD_PWR_INVALID_VALUE 0xFFFFFFFFU + +#endif /* !USBPD_PWR_USER_H_ */ + +/** + * @brief TCPP0203_FLGn pin + * To be defined for each Port, protected by a TCPP0203 component + */ +#define TCPP0203_PORT0_FLG_GPIO_CLK_ENABLE() __HAL_RCC_GPIOM_CLK_ENABLE() +#define TCPP0203_PORT0_FLG_GPIO_CLK_DISABLE() __HAL_RCC_GPIOM_CLK_DISABLE() +#define TCPP0203_PORT0_FLG_GPIO_PORT GPIOM +#define TCPP0203_PORT0_FLG_GPIO_PIN LL_GPIO_PIN_8 +#define TCPP0203_PORT0_FLG_GPIO_MODE LL_GPIO_MODE_INPUT +#define TCPP0203_PORT0_FLG_GPIO_PUPD LL_GPIO_PULL_UP +#define TCPP0203_PORT0_FLG_SET_EXTI() \ + do \ + { \ + __HAL_RCC_SBS_CLK_ENABLE(); \ + LL_SBS_SetEXTISource(LL_SBS_EXTI_PORTM, LL_SBS_EXTI_LINE8); \ + } while(0); +#define TCPP0203_PORT0_FLG_EXTI_LINE LL_EXTI_LINE_8 +#define TCPP0203_PORT0_FLG_EXTI_ENABLE() \ + do \ + { \ + LL_EXTI_DisableEvent_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); \ + LL_EXTI_EnableIT_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); \ + } while(0); +#define TCPP0203_PORT0_FLG_EXTI_DISABLE() LL_EXTI_DisableIT_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); +#define TCPP0203_PORT0_FLG_TRIG_ENABLE() \ + do \ + { \ + LL_EXTI_DisableRisingTrig_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); \ + LL_EXTI_EnableFallingTrig_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); \ + } while(0); +#define TCPP0203_PORT0_FLG_TRIG_DISABLE() LL_EXTI_DisableFallingTrig_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); +#define TCPP0203_PORT0_FLG_EXTI_IS_ACTIVE_FLAG() LL_EXTI_IsActiveFlag_0_31(TCPP0203_PORT0_FLG_EXTI_LINE) +#define TCPP0203_PORT0_FLG_EXTI_CLEAR_FLAG() LL_EXTI_ClearFlag_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); +#define TCPP0203_PORT0_FLG_EXTI_IRQN EXTI8_IRQn +#define TCPP0203_PORT0_FLG_EXTI_IRQHANDLER EXTI8_IRQHandler + +#define TCPP0203_PORT0_FLG_IT_PRIORITY (12U) +#define TCPP0203_PORT0_FLG_GENERATE_IT() LL_EXTI_GenerateSWI_0_31(TCPP0203_PORT0_FLG_EXTI_LINE); + +/** + * @brief TCPP0203_PWRENn pin + */ +#define TCPP0203_PORT0_ENABLE_GPIO_CLK_ENABLE() __HAL_RCC_GPIOM_CLK_ENABLE() +#define TCPP0203_PORT0_ENABLE_GPIO_CLK_DISABLE() __HAL_RCC_GPIOM_CLK_DISABLE() +#define TCPP0203_PORT0_ENABLE_GPIO_PORT GPIOM +#define TCPP0203_PORT0_ENABLE_GPIO_PIN LL_GPIO_PIN_9 +#define TCPP0203_PORT0_ENABLE_GPIO_MODE LL_GPIO_MODE_OUTPUT +#define TCPP0203_PORT0_ENABLE_GPIO_OUTPUT LL_GPIO_OUTPUT_PUSHPULL +#define TCPP0203_PORT0_ENABLE_GPIO_PUPD LL_GPIO_PULL_NO +#define TCPP0203_PORT0_ENABLE_GPIO_DEFVALUE() LL_GPIO_ResetOutputPin(TCPP0203_PORT0_ENABLE_GPIO_PORT,\ + TCPP0203_PORT0_ENABLE_GPIO_PIN); +#define TCPP0203_PORT0_ENABLE_GPIO_SET() LL_GPIO_SetOutputPin(TCPP0203_PORT0_ENABLE_GPIO_PORT,\ + TCPP0203_PORT0_ENABLE_GPIO_PIN); +#define TCPP0203_PORT0_ENABLE_GPIO_RESET() LL_GPIO_ResetOutputPin(TCPP0203_PORT0_ENABLE_GPIO_PORT,\ + TCPP0203_PORT0_ENABLE_GPIO_PIN); + +#define TCPP0203_PORT0_IANA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define TCPP0203_PORT0_IANA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOF_CLK_DISABLE() +#define TCPP0203_PORT0_IANA_GPIO_PORT GPIOF +#define TCPP0203_PORT0_IANA_GPIO_PIN LL_GPIO_PIN_12 +#define TCPP0203_PORT0_IANA_GPIO_MODE LL_GPIO_MODE_ANALOG + +#define TCPP0203_PORT0_VBUSC_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define TCPP0203_PORT0_VBUSC_GPIO_CLK_DISABLE() __HAL_RCC_GPIOF_CLK_DISABLE() +#define TCPP0203_PORT0_VBUSC_GPIO_PORT GPIOF +#define TCPP0203_PORT0_VBUSC_GPIO_PIN LL_GPIO_PIN_14 +#define TCPP0203_PORT0_VBUSC_GPIO_MODE LL_GPIO_MODE_ANALOG +#define TCPP0203_PORT0_VBUSC_ADC_INSTANCE ADC2 +#define TCPP0203_PORT0_VBUSC_ADC_COMMON ADC12_COMMON +#define TCPP0203_PORT0_VBUSC_ADC_RANK LL_ADC_REG_RANK_1 +#define TCPP0203_PORT0_VBUSC_ADC_CHANNEL LL_ADC_CHANNEL_6 +#define TCPP0203_PORT0_VBUSC_ADC_CLK_ENABLE() __HAL_RCC_ADC12_CLK_ENABLE() + +#define TCPP0203_PORT0_VBUSC_RA 3300u /* VBUS voltage divider RA */ +#define TCPP0203_PORT0_VBUSC_RB 499u /* VBUS voltage divider RB */ + +#define TCPP0203_PORT0_IANA_ISENSE_GA 42u /* Current measure gain In V/V */ +#define TCPP0203_PORT0_IANA_ISENSE_RS 22u /* Current measure shunt resistor in milliohm */ + +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_USBPD_PWR_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32H7S78_DK_USBPD_PWR_Exported_Functions Exported Functions + * @{ + */ +/* Common functions */ +int32_t BSP_USBPD_PWR_Init(uint32_t PortNum); +int32_t BSP_USBPD_PWR_Deinit(uint32_t PortNum); + +int32_t BSP_USBPD_PWR_SetRole(uint32_t PortNum, USBPD_PWR_PowerRoleTypeDef Role); +int32_t BSP_USBPD_PWR_SetPowerMode(uint32_t PortNum, USBPD_PWR_PowerModeTypeDef PwrMode); +int32_t BSP_USBPD_PWR_GetPowerMode(uint32_t PortNum, USBPD_PWR_PowerModeTypeDef *PwrMode); + +int32_t BSP_USBPD_PWR_VBUSInit(uint32_t PortNum); +int32_t BSP_USBPD_PWR_VBUSDeInit(uint32_t PortNum); + +int32_t BSP_USBPD_PWR_VBUSOn(uint32_t PortNum); +int32_t BSP_USBPD_PWR_VBUSOff(uint32_t PortNum); +int32_t BSP_USBPD_PWR_VBUSIsOn(uint32_t PortNum, uint8_t *pState); + +int32_t BSP_USBPD_PWR_VBUSSetVoltage_Fixed(uint32_t PortNum, uint32_t VbusTargetInmv, uint32_t OperatingCurrent, + uint32_t MaxOperatingCurrent); +int32_t BSP_USBPD_PWR_VBUSSetVoltage_Variable(uint32_t PortNum, uint32_t VbusTargetMaxInmv, + uint32_t VbusTargetMinInmv, uint32_t OperatingCurrent, + uint32_t MaxOperatingCurrent); +int32_t BSP_USBPD_PWR_VBUSSetVoltage_Battery(uint32_t PortNum, uint32_t VbusTargetMin, uint32_t VbusTargetMax, + uint32_t OperatingPower, uint32_t MaxOperatingPower); +int32_t BSP_USBPD_PWR_VBUSSetVoltage_APDO(uint32_t PortNum, uint32_t VbusTargetInmv, uint32_t OperatingCurrent, + int32_t Delta); + +int32_t BSP_USBPD_PWR_SetVBUSDisconnectionThreshold(uint32_t PortNum, uint32_t VoltageThreshold); + +int32_t BSP_USBPD_PWR_RegisterVBUSDetectCallback(uint32_t PortNum, + USBPD_PWR_VBUSDetectCallbackFunc *pfnVBUSDetectCallback); + +int32_t BSP_USBPD_PWR_VBUSGetVoltage(uint32_t PortNum, uint32_t *pVoltage); +int32_t BSP_USBPD_PWR_VBUSGetCurrent(uint32_t PortNum, int32_t *pCurrent); + +int32_t BSP_USBPD_PWR_VBUSDischargeOn(uint32_t PortNum); +int32_t BSP_USBPD_PWR_VBUSDischargeOff(uint32_t PortNum); + +int32_t BSP_USBPD_PWR_VCONNInit(uint32_t PortNum, uint32_t CCPinId); +int32_t BSP_USBPD_PWR_VCONNDeInit(uint32_t PortNum, uint32_t CCPinId); + +int32_t BSP_USBPD_PWR_VCONNOn(uint32_t PortNum, uint32_t CCPinId); +int32_t BSP_USBPD_PWR_VCONNOff(uint32_t PortNum, uint32_t CCPinId); +int32_t BSP_USBPD_PWR_VCONNIsOn(uint32_t PortNum, uint32_t CCPinId, uint8_t *pState); + +int32_t BSP_USBPD_PWR_VCONNDischargeOn(uint32_t PortNum); +int32_t BSP_USBPD_PWR_VCONNDischargeOff(uint32_t PortNum); + +void BSP_USBPD_PWR_EventCallback(uint32_t PortNum); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_USBPD_PWR_H */ + diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.c b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.c new file mode 100644 index 0000000..1237778 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.c @@ -0,0 +1,2482 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_xspi.c + * @author MCD Application Team + * @brief This file includes a standard driver for the MX66UW1G45G and the APS256XX + * XSPI memories mounted on the STM32H7S78-DK board. + ****************************************************************************** + * @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 used to drive the MX66UW1G45G Octal NOR and the APS256XX Octal PSRAM + external memories mounted on STM32H7S78-DK board. + + (#) This driver need specific component driver (MX66UW1G45G and APS256XX) to be included with. + + (#) MX66UW1G45G Initialization steps: + (++) Initialize the XSPI external memory using the BSP_XSPI_NOR_Init() function. This + function includes the MSP layer hardware resources initialization and the + XSPI interface with the external memory. + + (#) MX66UW1G45G Octal NOR memory operations + (++) XSPI memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_XSPI_NOR_Read()/BSP_XSPI_NOR_Write(). + (++) The function BSP_XSPI_NOR_GetInfo() returns the configuration of the XSPI memory. + (see the XSPI memory data sheet) + (++) Perform erase block operation using the function BSP_XSPI_NOR_Erase_Block() and by + specifying the block address. You can perform an erase operation of the whole + chip by calling the function BSP_XSPI_NOR_Erase_Chip(). + (++) The function BSP_XSPI_NOR_GetStatus() returns the current status of the XSPI memory. + (see the XSPI memory data sheet) + (++) The memory access can be configured in memory-mapped mode with the call of + function BSP_XSPI_NOR_EnableMemoryMapped(). To go back in indirect mode, the + function BSP_XSPI_NOR_DisableMemoryMapped() should be used. + (++) The erase operation can be suspend and resume with using functions + BSP_XSPI_NOR_SuspendErase() and BSP_XSPI_NOR_ResumeErase() + (++) It is possible to put the memory in deep power-down mode to reduce its consumption. + For this, the function BSP_XSPI_NOR_EnterDeepPowerDown() should be called. To leave + the deep power-down mode, the function BSP_XSPI_NOR_LeaveDeepPowerDown() should be called. + (++) The function BSP_XSPI_NOR_ReadID() returns the identifier of the memory + (see the XSPI memory data sheet) + (++) The configuration of the interface between peripheral and memory is done by + the function BSP_XSPI_NOR_ConfigFlash(), three modes are possible : + - SPI : instruction, address and data on one line + - STR OPI : instruction, address and data on eight lines with sampling on one edge of clock + - DTR OPI : instruction, address and data on eight lines with sampling on both edgaes of clock + + (#) APS256XX Octal PSRAM memory Initialization steps: + (++) Initialize the Octal PSRAM external memory using the BSP_XSPI_RAM_Init() function. This + function includes the MSP layer hardware resources initialization and the + XSPI interface with the external memory. + + (#) APS256XXL Octal PSRAM memory operations + (++) Octal PSRAM memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_XSPI_RAM_Read()/BSP_XSPI_RAM_Write(). + (++) The memory access can be configured in memory-mapped mode with the call of + function BSP_XSPI_RAM_EnableMemoryMapped(). To go back in indirect mode, the + function BSP_XSPI_RAM_DisableMemoryMapped() should be used. + (++) The function BSP_XSPI_RAM_ReadID() returns the identifier of the memory + (see the XSPI memory data sheet) + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_xspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @defgroup STM32H7S78_DK_XSPI XSPI + * @{ + */ + +/* Exported variables --------------------------------------------------------*/ +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @addtogroup STM32H7S78_DK_XSPI_NOR_Exported_Variables + * @{ + */ +XSPI_HandleTypeDef hxspi_nor[XSPI_NOR_INSTANCES_NUMBER] = {0}; +XSPI_NOR_Ctx_t XSPI_Nor_Ctx[XSPI_NOR_INSTANCES_NUMBER] = {{ + XSPI_ACCESS_NONE, + MX66UW1G45G_SPI_MODE, + MX66UW1G45G_STR_TRANSFER + } +}; +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +/* Exported variables --------------------------------------------------------*/ +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @addtogroup STM32H7S78_DK_XSPI_RAM_Exported_Variables + * @{ + */ +XSPI_HandleTypeDef hxspi_ram[XSPI_RAM_INSTANCES_NUMBER] = {0}; +XSPI_RAM_Ctx_t XSPI_Ram_Ctx[XSPI_RAM_INSTANCES_NUMBER] = {{ + XSPI_ACCESS_NONE, + BSP_XSPI_RAM_VARIABLE_LATENCY, + DEFAULT_READ_LATENCY_CODE, + DEFAULT_WRITE_LATENCY_CODE, + BSP_XSPI_RAM_IO_X8_MODE + } +}; + +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +/* Private constants --------------------------------------------------------*/ +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Private_Constants XSPI_NOR Private Constants + * @{ + */ +#if (DUMMY_CYCLES_READ_OCTAL == 20U) +#define XSPI_NOR_MAX_FREQ 200000000U /* Fmax of memory is 200 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 18U) +#define XSPI_NOR_MAX_FREQ 173000000U /* Fmax of memory is 173 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 16U) +#define XSPI_NOR_MAX_FREQ 166000000U /* Fmax of memory is 166 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 14U) +#define XSPI_NOR_MAX_FREQ 155000000U /* Fmax of memory is 155 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 12U) +#define XSPI_NOR_MAX_FREQ 133000000U /* Fmax of memory is 133 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 10U) +#define XSPI_NOR_MAX_FREQ 104000000U /* Fmax of memory is 104 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 8U) +#define XSPI_NOR_MAX_FREQ 84000000U /* Fmax of memory is 84 MHz */ +#elif (DUMMY_CYCLES_READ_OCTAL == 6U) +#define XSPI_NOR_MAX_FREQ 66000000U /* Fmax of memory is 66 MHz */ +#endif /* DUMMY_CYCLES_READ_OCTAL */ +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +/* Private variables ---------------------------------------------------------*/ +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Private_Variables XSPI_NOR Private Variables + * @{ + */ +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +static uint32_t XSPINor_IsMspCbValid[XSPI_NOR_INSTANCES_NUMBER] = {0}; +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ +static const uint8_t XSPINor_DummyCyclesArray[] = {MX66UW1G45G_CR2_DC_6_CYCLES, + MX66UW1G45G_CR2_DC_8_CYCLES, + MX66UW1G45G_CR2_DC_10_CYCLES, + MX66UW1G45G_CR2_DC_12_CYCLES, + MX66UW1G45G_CR2_DC_14_CYCLES, + MX66UW1G45G_CR2_DC_16_CYCLES, + MX66UW1G45G_CR2_DC_18_CYCLES, + MX66UW1G45G_CR2_DC_20_CYCLES + }; +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @defgroup STM32H7S78_DK_XSPI_RAM_Private_Variables XSPI_RAM Private Variables + * @{ + */ +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +static uint32_t XSPIRam_IsMspCbValid[XSPI_RAM_INSTANCES_NUMBER] = {0}; +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +/* Private functions ---------------------------------------------------------*/ +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Private_Functions XSPI_NOR Private Functions + * @{ + */ +static void XSPI_NOR_MspInit(XSPI_HandleTypeDef *hxspi); +static void XSPI_NOR_MspDeInit(XSPI_HandleTypeDef *hxspi); +static int32_t XSPI_NOR_ResetMemory(uint32_t Instance); +static int32_t XSPI_NOR_EnterDOPIMode(uint32_t Instance); +static int32_t XSPI_NOR_EnterSOPIMode(uint32_t Instance); +static int32_t XSPI_NOR_ExitOPIMode(uint32_t Instance); +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @defgroup STM32H7S78_DK_XSPI_RAM_Private_Functions XSPI_RAM Private Functions + * @{ + */ +static void XSPI_RAM_MspInit(XSPI_HandleTypeDef *hxspi); +static void XSPI_RAM_MspDeInit(XSPI_HandleTypeDef *hxspi); +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +/* Exported functions ---------------------------------------------------------*/ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @addtogroup STM32H7S78_DK_XSPI_NOR_Exported_Functions + * @{ + */ + +/** + * @brief Initializes the XSPI interface. + * @param Instance XSPI Instance + * @param Init XSPI Init structure + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_Init(uint32_t Instance, BSP_XSPI_NOR_Init_t *Init) +{ + int32_t ret; + BSP_XSPI_NOR_Info_t pInfo = {0}; + MX_XSPI_InitTypeDef xspi_init; + uint32_t xspi_clk; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if the instance is already initialized */ + if (XSPI_Nor_Ctx[Instance].IsInitialized == XSPI_ACCESS_NONE) + { +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 0) + /* Msp XSPI initialization */ + XSPI_NOR_MspInit(&hxspi_nor[Instance]); +#else + /* Register the XSPI MSP Callbacks */ + if (XSPINor_IsMspCbValid[Instance] == 0UL) + { + if (BSP_XSPI_NOR_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + return BSP_ERROR_PERIPH_FAILURE; + } + } +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + + /* Get Flash information of one memory */ + (void)MX66UW1G45G_GetFlashInfo(&pInfo); + + /* Fill config structure */ + xspi_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI2); + xspi_init.ClockPrescaler = (xspi_clk / XSPI_NOR_MAX_FREQ); + if ((xspi_clk % XSPI_NOR_MAX_FREQ) == 0U) + { + xspi_init.ClockPrescaler = xspi_init.ClockPrescaler - 1U; + } + xspi_init.MemorySize = (uint32_t)POSITION_VAL((uint32_t)pInfo.FlashSize); + xspi_init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE; + xspi_init.TransferRate = (uint32_t)Init->TransferRate; + + /* STM32 XSPI interface initialization */ + if (MX_XSPI_NOR_Init(&hxspi_nor[Instance], &xspi_init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* XSPI memory reset */ + else if (XSPI_NOR_ResetMemory(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Check if memory is ready */ + else if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Configure the memory */ + else if (BSP_XSPI_NOR_ConfigFlash(Instance, Init->InterfaceMode, Init->TransferRate) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + else + { + ret = BSP_ERROR_NONE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief De-Initializes the XSPI interface. + * @param Instance XSPI Instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if the instance is already initialized */ + if (XSPI_Nor_Ctx[Instance].IsInitialized != XSPI_ACCESS_NONE) + { + /* Disable Memory mapped mode */ + if (XSPI_Nor_Ctx[Instance].IsInitialized == XSPI_ACCESS_MMP) + { + if (BSP_XSPI_NOR_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + } + + /* Set default XSPI_Nor_Ctx values */ + XSPI_Nor_Ctx[Instance].IsInitialized = XSPI_ACCESS_NONE; + XSPI_Nor_Ctx[Instance].InterfaceMode = BSP_XSPI_NOR_SPI_MODE; + XSPI_Nor_Ctx[Instance].TransferRate = BSP_XSPI_NOR_STR_TRANSFER; + +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 0) + XSPI_NOR_MspDeInit(&hxspi_nor[Instance]); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 0) */ + + /* Call the DeInit function to reset the driver */ + if (HAL_XSPI_DeInit(&hxspi_nor[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_XSPI_Exported_Init_Functions + * @{ + */ +/** + * @brief Initializes the XSPI interface. + * @param hxspi XSPI handle + * @param Init XSPI config structure + * @retval BSP status + */ +__weak HAL_StatusTypeDef MX_XSPI_NOR_Init(XSPI_HandleTypeDef *hxspi, MX_XSPI_InitTypeDef *Init) +{ + /* XSPI initialization */ + hxspi->Instance = XSPI2; + + hxspi->Init.FifoThresholdByte = 1; + hxspi->Init.MemorySize = Init->MemorySize; /* 1 GBits */ + hxspi->Init.ChipSelectHighTimeCycle = 2; + hxspi->Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE; + hxspi->Init.ClockMode = HAL_XSPI_CLOCK_MODE_0; + hxspi->Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE; + hxspi->Init.ClockPrescaler = Init->ClockPrescaler; + hxspi->Init.SampleShifting = Init->SampleShifting; + hxspi->Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE; + hxspi->Init.MemoryMode = HAL_XSPI_SINGLE_MEM; + hxspi->Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED; + + if (Init->TransferRate == (uint32_t) BSP_XSPI_NOR_DTR_TRANSFER) + { + hxspi->Init.MemoryType = HAL_XSPI_MEMTYPE_MACRONIX; + hxspi->Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE; + } + else + { + hxspi->Init.MemoryType = HAL_XSPI_MEMTYPE_MACRONIX; + hxspi->Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE; + } + return HAL_XSPI_Init(hxspi); +} +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_XSPI_NOR_Exported_Functions + * @{ + */ +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +/** + * @brief Default BSP XSPI Msp Callbacks + * @param Instance XSPI Instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_XSPI_RegisterCallback(&hxspi_nor[Instance], HAL_XSPI_MSP_INIT_CB_ID, XSPI_NOR_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_XSPI_RegisterCallback(&hxspi_nor[Instance], HAL_XSPI_MSP_DEINIT_CB_ID, XSPI_NOR_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + XSPINor_IsMspCbValid[Instance] = 1U; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP XSPI Msp Callback registering + * @param Instance XSPI Instance + * @param CallBacks pointer to MspInit/MspDeInit callbacks functions + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_RegisterMspCallbacks(uint32_t Instance, BSP_XSPI_Cb_t *CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_XSPI_RegisterCallback(&hxspi_nor[Instance], HAL_XSPI_MSP_INIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_XSPI_RegisterCallback(&hxspi_nor[Instance], + HAL_XSPI_MSP_DEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + XSPINor_IsMspCbValid[Instance] = 1U; + } + } + + /* Return BSP status */ + return ret; +} +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Reads an amount of data from the XSPI memory. + * @param Instance XSPI instance + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (XSPI_Nor_Ctx[Instance].TransferRate == BSP_XSPI_NOR_STR_TRANSFER) + { + if (MX66UW1G45G_ReadSTR(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + MX66UW1G45G_4BYTES_SIZE, pData, ReadAddr, Size) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + else + { + if (MX66UW1G45G_ReadDTR(&hxspi_nor[Instance], pData, ReadAddr, Size) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes an amount of data to the XSPI memory. + * @param Instance XSPI instance + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_Write(uint32_t Instance, const uint8_t *pData, uint32_t WriteAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t end_addr; + uint32_t current_size; + uint32_t current_addr; + uint32_t data_addr; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Calculation of the size between the write address and the end of the page */ + current_size = MX66UW1G45G_PAGE_SIZE - (WriteAddr % MX66UW1G45G_PAGE_SIZE); + + /* Check if the size of the data is less than the remaining place in the page */ + if (current_size > Size) + { + current_size = Size; + } + + /* Initialize the address variables */ + current_addr = WriteAddr; + end_addr = WriteAddr + Size; + data_addr = (uint32_t)pData; + + /* Perform the write page by page */ + do + { + /* Check if Flash busy ? */ + if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Enable write operations */ + else if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + if (XSPI_Nor_Ctx[Instance].TransferRate == BSP_XSPI_NOR_STR_TRANSFER) + { + /* Issue page program command */ + if (MX66UW1G45G_PageProgram(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + MX66UW1G45G_4BYTES_SIZE, (uint8_t *)data_addr, current_addr, + current_size) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + else + { + /* Issue page program command */ + if (MX66UW1G45G_PageProgramDTR(&hxspi_nor[Instance], (uint8_t *)data_addr, current_addr, + current_size) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + if (ret == BSP_ERROR_NONE) + { + /* Configure automatic polling mode to wait for end of program */ + if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update the address and size variables for next page programming */ + current_addr += current_size; + data_addr += current_size; + current_size = ((current_addr + MX66UW1G45G_PAGE_SIZE) > end_addr) + ? (end_addr - current_addr) + : MX66UW1G45G_PAGE_SIZE; + } + } + } + } while ((current_addr < end_addr) && (ret == BSP_ERROR_NONE)); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the specified block of the XSPI memory. + * @param Instance XSPI instance + * @param BlockAddress Block address to erase + * @param BlockSize Erase Block size + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_Erase_Block(uint32_t Instance, uint32_t BlockAddress, BSP_XSPI_NOR_Erase_t BlockSize) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Enable write operations */ + else if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Issue Block Erase command */ + else if (MX66UW1G45G_BlockErase(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, MX66UW1G45G_4BYTES_SIZE, + BlockAddress, BlockSize) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the entire XSPI memory. + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_Erase_Chip(uint32_t Instance) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Enable write operations */ + else if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Issue Chip erase command */ + else if (MX66UW1G45G_ChipErase(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads current status of the XSPI memory. + * @param Instance XSPI instance + * @retval XSPI memory status: whether busy or not + */ +int32_t BSP_XSPI_NOR_GetStatus(uint32_t Instance) +{ + static uint8_t reg[2]; + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (MX66UW1G45G_ReadSecurityRegister(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, reg) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Check the value of the register */ + else if ((reg[0] & (MX66UW1G45G_SECR_P_FAIL | MX66UW1G45G_SECR_E_FAIL)) != 0U) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if ((reg[0] & (MX66UW1G45G_SECR_PSB | MX66UW1G45G_SECR_ESB)) != 0U) + { + ret = BSP_ERROR_XSPI_SUSPENDED; + } + else if (MX66UW1G45G_ReadStatusRegister(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, reg) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Check the value of the register */ + else if ((reg[0] & MX66UW1G45G_SR_WIP) != 0U) + { + ret = BSP_ERROR_BUSY; + } + else + { + ret = BSP_ERROR_NONE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Return the configuration of the XSPI memory. + * @param Instance XSPI instance + * @param pInfo pointer on the configuration structure + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_GetInfo(uint32_t Instance, BSP_XSPI_NOR_Info_t *pInfo) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + (void)MX66UW1G45G_GetFlashInfo(pInfo); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Configure the XSPI in memory-mapped mode + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_EnableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (XSPI_Nor_Ctx[Instance].TransferRate == BSP_XSPI_NOR_STR_TRANSFER) + { + if (MX66UW1G45G_EnableMemoryMappedModeSTR(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + MX66UW1G45G_4BYTES_SIZE) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update XSPI context if all operations are well done */ + { + XSPI_Nor_Ctx[Instance].IsInitialized = XSPI_ACCESS_MMP; + } + } + else + { + if (MX66UW1G45G_EnableMemoryMappedModeDTR(&hxspi_nor[Instance], + XSPI_Nor_Ctx[Instance].InterfaceMode) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update XSPI context if all operations are well done */ + { + XSPI_Nor_Ctx[Instance].IsInitialized = XSPI_ACCESS_MMP; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Exit form memory-mapped mode + * Only 1 Instance can running MMP mode. And it will lock system at this mode. + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_DisableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (XSPI_Nor_Ctx[Instance].IsInitialized != XSPI_ACCESS_MMP) + { + ret = BSP_ERROR_XSPI_MMP_UNLOCK_FAILURE; + }/* Abort MMP back to indirect mode */ + else if (HAL_XSPI_Abort(&hxspi_nor[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else /* Update XSPI NOR context if all operations are well done */ + { + XSPI_Nor_Ctx[Instance].IsInitialized = XSPI_ACCESS_INDIRECT; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Get flash ID 3 Bytes: + * Manufacturer ID, Memory type, Memory density + * @param Instance XSPI instance + * @param Id Pointer to flash ID bytes + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_ReadID(uint32_t Instance, uint8_t *Id) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (MX66UW1G45G_ReadID(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, Id) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Set Flash to desired Interface mode. And this instance becomes current instance. + * If current instance running at MMP mode then this function doesn't work. + * Indirect -> Indirect + * @param Instance XSPI instance + * @param Mode XSPI mode + * @param Rate XSPI transfer rate + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_ConfigFlash(uint32_t Instance, BSP_XSPI_NOR_Interface_t Mode, BSP_XSPI_NOR_Transfer_t Rate) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if MMP mode locked ************************************************/ + if (XSPI_Nor_Ctx[Instance].IsInitialized == XSPI_ACCESS_MMP) + { + ret = BSP_ERROR_XSPI_MMP_LOCK_FAILURE; + } + else + { + /* Setup Flash interface ***************************************************/ + switch (XSPI_Nor_Ctx[Instance].InterfaceMode) + { + case BSP_XSPI_NOR_OPI_MODE : /* 8-8-8 commands */ + if ((Mode != BSP_XSPI_NOR_OPI_MODE) || (Rate != XSPI_Nor_Ctx[Instance].TransferRate)) + { + /* Exit OPI mode */ + ret = XSPI_NOR_ExitOPIMode(Instance); + + if ((ret == BSP_ERROR_NONE) && (Mode == BSP_XSPI_NOR_OPI_MODE)) + { + + if (XSPI_Nor_Ctx[Instance].TransferRate == BSP_XSPI_NOR_STR_TRANSFER) + { + /* Enter DTR OPI mode */ + ret = XSPI_NOR_EnterDOPIMode(Instance); + } + else + { + /* Enter STR OPI mode */ + ret = XSPI_NOR_EnterSOPIMode(Instance); + } + } + } + break; + + case BSP_XSPI_NOR_SPI_MODE : /* 1-1-1 commands, Power on H/W default setting */ + default : + if (Mode == BSP_XSPI_NOR_OPI_MODE) + { + if (Rate == BSP_XSPI_NOR_STR_TRANSFER) + { + /* Enter STR OPI mode */ + ret = XSPI_NOR_EnterSOPIMode(Instance); + } + else + { + /* Enter DTR OPI mode */ + ret = XSPI_NOR_EnterDOPIMode(Instance); + } + } + break; + } + + /* Update XSPI context if all operations are well done */ + if (ret == BSP_ERROR_NONE) + { + /* Update current status parameter *****************************************/ + XSPI_Nor_Ctx[Instance].IsInitialized = XSPI_ACCESS_INDIRECT; + XSPI_Nor_Ctx[Instance].InterfaceMode = Mode; + XSPI_Nor_Ctx[Instance].TransferRate = Rate; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function suspends an ongoing erase command. + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_SuspendErase(uint32_t Instance) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + /* Check whether the device is busy (erase operation is in progress). */ + else if (BSP_XSPI_NOR_GetStatus(Instance) != BSP_ERROR_BUSY) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_Suspend(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (BSP_XSPI_NOR_GetStatus(Instance) != BSP_ERROR_XSPI_SUSPENDED) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function resumes a paused erase command. + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_ResumeErase(uint32_t Instance) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + /* Check whether the device is busy (erase operation is in progress). */ + else if (BSP_XSPI_NOR_GetStatus(Instance) != BSP_ERROR_XSPI_SUSPENDED) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_Resume(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* + When this command is executed, the status register write in progress bit is set to 1, and + the flag status register program erase controller bit is set to 0. This command is ignored + if the device is not in a suspended state. + */ + else if (BSP_XSPI_NOR_GetStatus(Instance) != BSP_ERROR_BUSY) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function enter the XSPI memory in deep power down mode. + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_EnterDeepPowerDown(uint32_t Instance) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (MX66UW1G45G_EnterPowerDown(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* --- Memory takes 10us max to enter deep power down --- */ + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function leave the XSPI memory from deep power down mode. + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_NOR_LeaveDeepPowerDown(uint32_t Instance) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_NOR_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (MX66UW1G45G_ReleasePowerDown(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */ + /* --- Memory takes 30us min to leave deep power down --- */ + + /* Return BSP status */ + return ret; +} +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @addtogroup STM32H7S78_DK_XSPI_RAM_Exported_Functions + * @{ + */ + +/** + * @brief Initializes the XSPI interface. + * @param Instance XSPI Instance + * @param Init XSPI Init structure + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_Init(uint32_t Instance, BSP_XSPI_RAM_Cfg_t *Init) +{ + MX_XSPI_InitTypeDef xspi_init; + int32_t ret = BSP_ERROR_NONE; + uint32_t xspi_clk, xspi_max_freq; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if the instance is already initialized */ + if (XSPI_Ram_Ctx[Instance].IsInitialized == XSPI_ACCESS_NONE) + { +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 0) + /* Msp XSPI initialization */ + XSPI_RAM_MspInit(&hxspi_ram[Instance]); +#else + /* Register the XSPI MSP Callbacks */ + if (XSPIRam_IsMspCbValid[Instance] == 0UL) + { + if (BSP_XSPI_RAM_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + return BSP_ERROR_PERIPH_FAILURE; + } + } +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + + /* Fill config structure */ + if ((Init->ReadLatencyCode == BSP_XSPI_RAM_READ_LATENCY_3) || + (Init->WriteLatencyCode == BSP_XSPI_RAM_WRITE_LATENCY_3)) + { + /* In case of latency 3, Fmax of memory is 66 MHz */ + xspi_max_freq = 66000000U; + } + else if ((Init->ReadLatencyCode == BSP_XSPI_RAM_READ_LATENCY_4) || + (Init->WriteLatencyCode == BSP_XSPI_RAM_WRITE_LATENCY_4)) + { + /* In case of latency 4, Fmax of memory is 109 MHz */ + xspi_max_freq = 109000000U; + } + else if ((Init->ReadLatencyCode == BSP_XSPI_RAM_READ_LATENCY_5) || + (Init->WriteLatencyCode == BSP_XSPI_RAM_WRITE_LATENCY_5)) + { + /* In case of latency 5, Fmax of memory is 133 MHz */ + xspi_max_freq = 133000000U; + } + else if ((Init->ReadLatencyCode == BSP_XSPI_RAM_READ_LATENCY_6) || + (Init->WriteLatencyCode == BSP_XSPI_RAM_WRITE_LATENCY_6)) + { + /* In case of latency 6, Fmax of memory is 166 MHz */ + xspi_max_freq = 166000000U; + } + else + { + /* In case of latency 7, Fmax of memory is 200 MHz */ + xspi_max_freq = 200000000U; + } + xspi_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI1); + xspi_init.ClockPrescaler = (xspi_clk / xspi_max_freq); + if ((xspi_clk % xspi_max_freq) == 0U) + { + xspi_init.ClockPrescaler = xspi_init.ClockPrescaler - 1U; + } + xspi_init.MemorySize = HAL_XSPI_SIZE_256MB; + xspi_init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE; + + /* STM32 XSPI interface initialization */ + if (MX_XSPI_RAM_Init(&hxspi_ram[Instance], &xspi_init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Reset the memory */ + else if (APS256XX_Reset(&hxspi_ram[Instance]) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Configure the memory */ + else if (BSP_XSPI_RAM_Config16BitsOctalRAM(Instance, Init) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update current status parameter */ + XSPI_Ram_Ctx[Instance].IsInitialized = XSPI_ACCESS_INDIRECT; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief De-Initializes the XSPI interface. + * @param Instance XSPI Instance + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if the instance is already initialized */ + if (XSPI_Ram_Ctx[Instance].IsInitialized != XSPI_ACCESS_NONE) + { + /* Disable Memory mapped mode */ + if (XSPI_Ram_Ctx[Instance].IsInitialized == XSPI_ACCESS_MMP) + { + if (BSP_XSPI_RAM_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + } + /* Set default XSPI_Ram_Ctx values */ + XSPI_Ram_Ctx[Instance].IsInitialized = XSPI_ACCESS_NONE; + XSPI_Ram_Ctx[Instance].LatencyType = BSP_XSPI_RAM_VARIABLE_LATENCY; + XSPI_Ram_Ctx[Instance].ReadLatencyCode = DEFAULT_READ_LATENCY_CODE; + XSPI_Ram_Ctx[Instance].WriteLatencyCode = DEFAULT_WRITE_LATENCY_CODE; + XSPI_Ram_Ctx[Instance].IOMode = BSP_XSPI_RAM_IO_X8_MODE; + +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 0) + XSPI_RAM_MspDeInit(&hxspi_ram[Instance]); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 0) */ + + /* Call the DeInit function to reset the driver */ + if (HAL_XSPI_DeInit(&hxspi_ram[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_XSPI_Exported_Init_Functions + * @{ + */ + +/** + * @brief Initializes the XSPI interface. + * @param hxspi XSPI handle + * @param Init XSPI config structure + * @retval BSP status + */ +__weak HAL_StatusTypeDef MX_XSPI_RAM_Init(XSPI_HandleTypeDef *hxspi, MX_XSPI_InitTypeDef *Init) +{ + uint32_t hspi_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_XSPI1); + + /* XSPI initialization */ + hxspi->Instance = XSPI1; + + hxspi->Init.FifoThresholdByte = 4U; + hxspi->Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM_16BITS; + hxspi->Init.MemoryMode = HAL_XSPI_SINGLE_MEM; + hxspi->Init.MemorySize = Init->MemorySize; + hxspi->Init.MemorySelect = HAL_XSPI_CSSEL_NCS1; + hxspi->Init.ChipSelectHighTimeCycle = 5U; /* tCPH = 24 ns min */ + hxspi->Init.ClockMode = HAL_XSPI_CLOCK_MODE_0; + hxspi->Init.ClockPrescaler = Init->ClockPrescaler; + hxspi->Init.SampleShifting = Init->SampleShifting; + hxspi->Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE; + hxspi->Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_16KB; + hxspi->Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE; + /* tCEM = 2 us max => REFRESH+4 clock cycles for read */ + hxspi->Init.Refresh = ((2U * (hspi_clk / (hxspi->Init.ClockPrescaler + 1U)) / 1000000U) - 4U); + hxspi->Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED; + hxspi->Init.MaxTran = 0U; + + return HAL_XSPI_Init(hxspi); +} +/** + * @} + */ + +/** @addtogroup STM32H7S78_DK_XSPI_RAM_Exported_Functions + * @{ + */ +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +/** + * @brief Default BSP XSPI Msp Callbacks + * @param Instance XSPI Instance + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_XSPI_RegisterCallback(&hxspi_ram[Instance], HAL_XSPI_MSP_INIT_CB_ID, + XSPI_RAM_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_XSPI_RegisterCallback(&hxspi_ram[Instance], HAL_XSPI_MSP_DEINIT_CB_ID, + XSPI_RAM_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + XSPIRam_IsMspCbValid[Instance] = 1U; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP XSPI Msp Callback registering + * @param Instance XSPI Instance + * @param CallBacks pointer to MspInit/MspDeInit callbacks functions + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_RegisterMspCallbacks(uint32_t Instance, BSP_XSPI_Cb_t *CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_XSPI_RegisterCallback(&hxspi_ram[Instance], HAL_XSPI_MSP_INIT_CB_ID, + CallBacks->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_XSPI_RegisterCallback(&hxspi_ram[Instance], HAL_XSPI_MSP_DEINIT_CB_ID, + CallBacks->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + XSPIRam_IsMspCbValid[Instance] = 1U; + } + } + + /* Return BSP status */ + return ret; +} +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Reads an amount of data from the XSPI memory. + * @param Instance XSPI instance + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (APS256XX_Read(&hxspi_ram[Instance], pData, ReadAddr, Size, + (uint32_t)APS256XX_READ_LATENCY((uint32_t)(XSPI_Ram_Ctx[Instance].ReadLatencyCode), + (uint32_t)(XSPI_Ram_Ctx[Instance].LatencyType)), + (uint32_t)(XSPI_Ram_Ctx[Instance].IOMode), 0U) != APS256XX_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads an amount of data from the 16-bits Octal RAM memory in DMA mode. + * @param Instance XSPI instance + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_Read_DMA(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (APS256XX_Read_DMA(&hxspi_ram[Instance], pData, ReadAddr, Size, + (uint32_t)APS256XX_READ_LATENCY((uint32_t)(XSPI_Ram_Ctx[Instance].ReadLatencyCode), + (uint32_t)(XSPI_Ram_Ctx[Instance].LatencyType)), + (uint32_t)(XSPI_Ram_Ctx[Instance].IOMode), 0U) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes an amount of data to the XSPI memory. + * @param Instance XSPI instance + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_Write(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (APS256XX_Write(&hxspi_ram[Instance], pData, WriteAddr, Size, + (uint32_t)APS256XX_WRITE_LATENCY((uint32_t)(XSPI_Ram_Ctx[Instance].WriteLatencyCode)), + (uint32_t)(XSPI_Ram_Ctx[Instance].IOMode), 0U) != APS256XX_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes an amount of data to the 16-bits Octal RAM memory in DMA mode. + * @param Instance XSPI instance + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_Write_DMA(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (APS256XX_Write_DMA(&hxspi_ram[Instance], pData, WriteAddr, Size, + (uint32_t)APS256XX_WRITE_LATENCY((uint32_t)(XSPI_Ram_Ctx[Instance].WriteLatencyCode)), + (uint32_t)(XSPI_Ram_Ctx[Instance].IOMode), 0U) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Configure the XSPI in memory-mapped mode + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_EnableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (APS256XX_EnableMemoryMappedMode(&hxspi_ram[Instance], + (uint32_t)APS256XX_READ_LATENCY(\ + (uint32_t)(XSPI_Ram_Ctx[Instance].ReadLatencyCode), + (uint32_t)(XSPI_Ram_Ctx[Instance].LatencyType)), + (uint32_t)APS256XX_WRITE_LATENCY(\ + (uint32_t)(XSPI_Ram_Ctx[Instance].WriteLatencyCode)), + (uint32_t)(XSPI_Ram_Ctx[Instance].IOMode), 0U) != APS256XX_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Exit the memory-mapped mode + * @param Instance XSPI instance + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_DisableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (XSPI_Ram_Ctx[Instance].IsInitialized != XSPI_ACCESS_MMP) + { + ret = BSP_ERROR_XSPI_MMP_UNLOCK_FAILURE; + } + /* Abort MMP back to indirect mode */ + else if (HAL_XSPI_Abort(&hxspi_ram[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Update XSPI HyperRAM context if all operations are well done */ + else + { + XSPI_Ram_Ctx[Instance].IsInitialized = XSPI_ACCESS_INDIRECT; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Get RAM ID 3 Bytes: + * Vendor ID, Device ID, Device Density + * @param Instance XSPI instance + * @param Id Pointer to RAM ID bytes + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_ReadID(uint32_t Instance, uint8_t *Id) +{ + int32_t ret; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else if (APS256XX_ReadID(&hxspi_ram[0], Id, (uint32_t)APS256XX_READ_REG_LATENCY(\ + (uint32_t)(XSPI_Ram_Ctx[Instance].ReadLatencyCode))) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Set 16-bits Octal RAM to desired configuration. And this instance becomes current instance. + * If current instance running at MMP mode then this function doesn't work. + * Indirect -> Indirect + * @param Instance XSPI instance + * @param Cfg pointer to the RAM config + * @retval BSP status + */ +int32_t BSP_XSPI_RAM_Config16BitsOctalRAM(uint32_t Instance, BSP_XSPI_RAM_Cfg_t *Cfg) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t reg[2] = {0}; + + /* Check if the instance is supported */ + if (Instance >= XSPI_RAM_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if MMP mode locked ***********************************************/ + if (XSPI_Ram_Ctx[Instance].IsInitialized == XSPI_ACCESS_MMP) + { + ret = BSP_ERROR_XSPI_MMP_LOCK_FAILURE; + } + else + { + if ((XSPI_Ram_Ctx[Instance].IsInitialized == XSPI_ACCESS_NONE) || + (XSPI_Ram_Ctx[Instance].LatencyType != Cfg->LatencyType) || + (XSPI_Ram_Ctx[Instance].ReadLatencyCode != Cfg->ReadLatencyCode)) + { + /* Reading the configuration of Mode Register 0 ***********************/ + if (APS256XX_ReadReg(&hxspi_ram[Instance], APS256XX_MR0_ADDRESS, reg, + (uint32_t)APS256XX_READ_REG_LATENCY((uint32_t) \ + (XSPI_Ram_Ctx[Instance].ReadLatencyCode))) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Configure the 16-bits Octal RAM memory ***************************/ + MODIFY_REG(reg[0], ((uint8_t)APS256XX_MR0_LATENCY_TYPE | + (uint8_t)APS256XX_MR0_READ_LATENCY_CODE | + (uint8_t)APS256XX_MR0_DRIVE_STRENGTH), + ((uint8_t)(Cfg->LatencyType) | + (uint8_t)(Cfg->ReadLatencyCode) | + (uint8_t)CONF_HSPI_DS)); + + if (APS256XX_WriteReg(&hxspi_ram[Instance], APS256XX_MR0_ADDRESS, reg[0]) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + if (ret == BSP_ERROR_NONE) + { + if ((XSPI_Ram_Ctx[Instance].IsInitialized == XSPI_ACCESS_NONE) || + (XSPI_Ram_Ctx[Instance].WriteLatencyCode != Cfg->WriteLatencyCode)) + { + /* Reading the configuration of Mode Register 4 ***********************/ + if (APS256XX_ReadReg(&hxspi_ram[Instance], APS256XX_MR4_ADDRESS, reg, + (uint32_t)APS256XX_READ_REG_LATENCY((uint32_t) \ + (XSPI_Ram_Ctx[Instance].ReadLatencyCode))) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Configure the 16-bits Octal RAM memory ***************************/ + WRITE_REG(reg[0], ((uint8_t)Cfg->WriteLatencyCode | + (uint8_t)CONF_HSPI_RF | + (uint8_t)CONF_HSPI_PASR)); + + if (APS256XX_WriteReg(&hxspi_ram[Instance], APS256XX_MR4_ADDRESS, reg[0]) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + } + + if (ret == BSP_ERROR_NONE) + { + if ((XSPI_Ram_Ctx[Instance].IsInitialized == XSPI_ACCESS_NONE) || + (XSPI_Ram_Ctx[Instance].IOMode != Cfg->IOMode)) + { + /* Reading the configuration of Mode Register 8 ***********************/ + if (APS256XX_ReadReg(&hxspi_ram[Instance], APS256XX_MR8_ADDRESS, reg, + (uint32_t)APS256XX_READ_REG_LATENCY((uint32_t) \ + (XSPI_Ram_Ctx[Instance].ReadLatencyCode))) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Configure the 16-bits Octal RAM memory ***************************/ + MODIFY_REG(reg[0], (uint8_t)APS256XX_MR8_X8_X16, (uint8_t)(Cfg->IOMode)); + + if (APS256XX_WriteReg(&hxspi_ram[Instance], APS256XX_MR8_ADDRESS, reg[0]) != APS256XX_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + } + + /* Update XSPI context if all operations are well done */ + if (ret == BSP_ERROR_NONE) + { + /* Update current status parameter *****************************************/ + XSPI_Ram_Ctx[Instance].IsInitialized = XSPI_ACCESS_INDIRECT; + XSPI_Ram_Ctx[Instance].LatencyType = Cfg->LatencyType; + XSPI_Ram_Ctx[Instance].ReadLatencyCode = Cfg->ReadLatencyCode; + XSPI_Ram_Ctx[Instance].WriteLatencyCode = Cfg->WriteLatencyCode; + XSPI_Ram_Ctx[Instance].IOMode = Cfg->IOMode; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Handles XSPI 16-bits Octal RAM DMA transfer interrupt request. + * @param Instance XSPI instance + * @retval None + */ +void BSP_XSPI_RAM_DMA_RX_IRQHandler(uint32_t Instance) +{ + HAL_DMA_IRQHandler(hxspi_ram[Instance].hdmarx); +} + +/** + * @brief Handles XSPI 16-bits Octal RAM DMA transfer interrupt request. + * @param Instance XSPI instance + * @retval None + */ +void BSP_XSPI_RAM_DMA_TX_IRQHandler(uint32_t Instance) +{ + HAL_DMA_IRQHandler(hxspi_ram[Instance].hdmatx); +} + +/** + * @brief Handles XSPI 16-bits Octal RAM interrupt request. + * @param Instance XSPI instance + * @retval None + */ +void BSP_XSPI_RAM_IRQHandler(uint32_t Instance) +{ + HAL_XSPI_IRQHandler(&hxspi_ram[Instance]); +} +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @addtogroup STM32H7S78_DK_XSPI_NOR_Private_Functions + * @{ + */ + +/** + * @brief Initializes the XSPI MSP. + * @param hxspi XSPI handle + * @retval None + */ +static void XSPI_NOR_MspInit(XSPI_HandleTypeDef *hxspi) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* hxspi unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* Enable the SBS Clock */ + __HAL_RCC_SBS_CLK_ENABLE(); + + /* Enable the power of XSPI */ + XSPI_NOR_PWR_ENABLE(); + + /* Enable the XSPI memory interface clock */ + XSPI_NOR_CLK_ENABLE(); + + /* Reset the XSPI memory interface */ + XSPI_NOR_FORCE_RESET(); + XSPI_NOR_RELEASE_RESET(); + + /* Enable GPIO clocks */ + XSPI_NOR_CLK_GPIO_CLK_ENABLE(); + XSPI_NOR_DQS_GPIO_CLK_ENABLE(); + XSPI_NOR_CS_GPIO_CLK_ENABLE(); + XSPI_NOR_D0_GPIO_CLK_ENABLE(); + XSPI_NOR_D1_GPIO_CLK_ENABLE(); + XSPI_NOR_D2_GPIO_CLK_ENABLE(); + XSPI_NOR_D3_GPIO_CLK_ENABLE(); + XSPI_NOR_D4_GPIO_CLK_ENABLE(); + XSPI_NOR_D5_GPIO_CLK_ENABLE(); + XSPI_NOR_D6_GPIO_CLK_ENABLE(); + XSPI_NOR_D7_GPIO_CLK_ENABLE(); + + /* SBS: Enable HSLV on XSPI2 */ + HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI2_HSLV); + + /* XSPI CS GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_CS_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = XSPI_NOR_CS_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_CS_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI DQS GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_DQS_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_DQS_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_DQS_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI CLK GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_CLK_PIN; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = XSPI_NOR_CLK_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_CLK_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D0 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D0_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D0_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D0_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D1 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D1_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D1_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D1_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D2 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D2_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D2_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D2_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D3 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D3_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D3_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D3_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D4 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D4_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D4_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D4_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D5 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D5_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D5_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D5_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D6 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D6_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D6_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D6_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D7 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_NOR_D7_PIN; + GPIO_InitStruct.Alternate = XSPI_NOR_D7_PIN_AF; + HAL_GPIO_Init(XSPI_NOR_D7_GPIO_PORT, &GPIO_InitStruct); +} + +/** + * @brief De-Initializes the XSPI MSP. + * @param hxspi XSPI handle + * @retval None + */ +static void XSPI_NOR_MspDeInit(XSPI_HandleTypeDef *hxspi) +{ + /* hxspi unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* XSPI GPIO pins de-configuration */ + HAL_GPIO_DeInit(XSPI_NOR_CLK_GPIO_PORT, XSPI_NOR_CLK_PIN); + HAL_GPIO_DeInit(XSPI_NOR_DQS_GPIO_PORT, XSPI_NOR_DQS_PIN); + HAL_GPIO_DeInit(XSPI_NOR_CS_GPIO_PORT, XSPI_NOR_CS_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D0_GPIO_PORT, XSPI_NOR_D0_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D1_GPIO_PORT, XSPI_NOR_D1_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D2_GPIO_PORT, XSPI_NOR_D2_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D3_GPIO_PORT, XSPI_NOR_D3_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D4_GPIO_PORT, XSPI_NOR_D4_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D5_GPIO_PORT, XSPI_NOR_D5_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D6_GPIO_PORT, XSPI_NOR_D6_PIN); + HAL_GPIO_DeInit(XSPI_NOR_D7_GPIO_PORT, XSPI_NOR_D7_PIN); + + /* Reset the XSPI memory interface */ + XSPI_NOR_FORCE_RESET(); + XSPI_NOR_RELEASE_RESET(); + + /* Disable the XSPI memory interface clock */ + XSPI_NOR_CLK_DISABLE(); +} + +/** + * @brief This function reset the XSPI memory. + * @param Instance XSPI instance + * @retval BSP status + */ +static int32_t XSPI_NOR_ResetMemory(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + if (MX66UW1G45G_ResetEnable(&hxspi_nor[Instance], BSP_XSPI_NOR_SPI_MODE, + BSP_XSPI_NOR_STR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_ResetMemory(&hxspi_nor[Instance], BSP_XSPI_NOR_SPI_MODE, + BSP_XSPI_NOR_STR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_ResetEnable(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, + BSP_XSPI_NOR_STR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_ResetMemory(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, + BSP_XSPI_NOR_STR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_ResetEnable(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, + BSP_XSPI_NOR_DTR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (MX66UW1G45G_ResetMemory(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, + BSP_XSPI_NOR_DTR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + XSPI_Nor_Ctx[Instance].IsInitialized = XSPI_ACCESS_INDIRECT; /* After reset S/W setting to indirect access */ + XSPI_Nor_Ctx[Instance].InterfaceMode = BSP_XSPI_NOR_SPI_MODE; /* After reset H/W back to SPI mode by default */ + XSPI_Nor_Ctx[Instance].TransferRate = BSP_XSPI_NOR_STR_TRANSFER; /* After reset S/W setting to STR mode */ + + /* After SWreset CMD, wait in case SWReset occurred during erase operation */ + HAL_Delay(MX66UW1G45G_RESET_MAX_TIME); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function enables the octal DTR mode of the memory. + * @param Instance XSPI instance + * @retval BSP status + */ +static int32_t XSPI_NOR_EnterDOPIMode(uint32_t Instance) +{ + int32_t ret; + uint8_t reg[2] = {0}; + uint8_t dummy_cycles = XSPINor_DummyCyclesArray[((DUMMY_CYCLES_READ_OCTAL / 2U) - 3U)]; + + /* Enable write operations */ + if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Write Configuration register 2 (with new dummy cycles) */ + else if (MX66UW1G45G_WriteCfg2Register(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, MX66UW1G45G_CR2_REG3_ADDR, + dummy_cycles) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Enable write operations */ + else if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Write Configuration register 2 (with Octal I/O SPI protocol) */ + else if (MX66UW1G45G_WriteCfg2Register(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, MX66UW1G45G_CR2_REG1_ADDR, + MX66UW1G45G_CR2_DOPI) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Wait that the configuration is effective and check that memory is ready */ + HAL_Delay(MX66UW1G45G_WRITE_REG_MAX_TIME); + + /* Reconfigure the memory type of the peripheral */ + hxspi_nor[Instance].Init.MemoryType = HAL_XSPI_MEMTYPE_MACRONIX; + hxspi_nor[Instance].Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE; + if (HAL_XSPI_Init(&hxspi_nor[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Check Flash busy ? */ + else if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, + BSP_XSPI_NOR_DTR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Check the configuration has been correctly done */ + else if (MX66UW1G45G_ReadCfg2Register(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, BSP_XSPI_NOR_DTR_TRANSFER, + MX66UW1G45G_CR2_REG1_ADDR, reg) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (reg[0] != MX66UW1G45G_CR2_DOPI) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function enables the octal STR mode of the memory. + * @param Instance XSPI instance + * @retval BSP status + */ +static int32_t XSPI_NOR_EnterSOPIMode(uint32_t Instance) +{ + int32_t ret; + uint8_t reg[2] = {0}; + uint8_t dummy_cycles = XSPINor_DummyCyclesArray[((DUMMY_CYCLES_READ_OCTAL / 2U) - 3U)]; + + /* Enable write operations */ + if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Write Configuration register 2 (with new dummy cycles) */ + else if (MX66UW1G45G_WriteCfg2Register(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, MX66UW1G45G_CR2_REG3_ADDR, + dummy_cycles) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Enable write operations */ + else if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Write Configuration register 2 (with Octal I/O SPI protocol) */ + else if (MX66UW1G45G_WriteCfg2Register(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, MX66UW1G45G_CR2_REG1_ADDR, + MX66UW1G45G_CR2_SOPI) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Wait that the configuration is effective and check that memory is ready */ + HAL_Delay(MX66UW1G45G_WRITE_REG_MAX_TIME); + + /* Check Flash busy ? */ + if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, + BSP_XSPI_NOR_STR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Check the configuration has been correctly done */ + else if (MX66UW1G45G_ReadCfg2Register(&hxspi_nor[Instance], BSP_XSPI_NOR_OPI_MODE, BSP_XSPI_NOR_STR_TRANSFER, + MX66UW1G45G_CR2_REG1_ADDR, reg) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (reg[0] != MX66UW1G45G_CR2_SOPI) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + ret = BSP_ERROR_NONE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function disables the octal DTR or STR mode of the memory. + * @param Instance XSPI instance + * @retval BSP status + */ +static int32_t XSPI_NOR_ExitOPIMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t reg[2]; + + /* Enable write operations */ + if (MX66UW1G45G_WriteEnable(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Write Configuration register 2 (with SPI protocol) */ + reg[0] = 0; + reg[1] = 0; + if (MX66UW1G45G_WriteCfg2Register(&hxspi_nor[Instance], XSPI_Nor_Ctx[Instance].InterfaceMode, + XSPI_Nor_Ctx[Instance].TransferRate, MX66UW1G45G_CR2_REG1_ADDR, + reg[0]) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Wait that the configuration is effective and check that memory is ready */ + HAL_Delay(MX66UW1G45G_WRITE_REG_MAX_TIME); + + if (XSPI_Nor_Ctx[Instance].TransferRate == BSP_XSPI_NOR_DTR_TRANSFER) + { + /* Reconfigure the memory type of the peripheral */ + hxspi_nor[Instance].Init.MemoryType = HAL_XSPI_MEMTYPE_MICRON; + hxspi_nor[Instance].Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE; + if (HAL_XSPI_Init(&hxspi_nor[Instance]) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + + if (ret == BSP_ERROR_NONE) + { + /* Check Flash busy ? */ + if (MX66UW1G45G_AutoPollingMemReady(&hxspi_nor[Instance], BSP_XSPI_NOR_SPI_MODE, + BSP_XSPI_NOR_STR_TRANSFER) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + /* Check the configuration has been correctly done */ + else if (MX66UW1G45G_ReadCfg2Register(&hxspi_nor[Instance], BSP_XSPI_NOR_SPI_MODE, BSP_XSPI_NOR_STR_TRANSFER, + MX66UW1G45G_CR2_REG1_ADDR, reg) != MX66UW1G45G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (reg[0] != 0U) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Nothing to do */ + } + } + } + } + + /* Return BSP status */ + return ret; +} + + +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @addtogroup STM32H7S78_DK_XSPI_RAM_Private_Functions + * @{ + */ +/** + * @brief Initializes the XSPI MSP. + * @param hxspi XSPI handle + * @retval None + */ +static void XSPI_RAM_MspInit(XSPI_HandleTypeDef *hxspi) +{ + static DMA_HandleTypeDef hdmatx, hdmarx; + GPIO_InitTypeDef GPIO_InitStruct; + + /* hxspi unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* Enable the SBS Clock */ + __HAL_RCC_SBS_CLK_ENABLE(); + + /* Enable the power of XSPI */ + XSPI_RAM_PWR_ENABLE() ; + + /* Enable the XSPI memory interface clock */ + XSPI_RAM_CLK_ENABLE(); + XSPI_RAM_DMAx_CLK_ENABLE(); + + /* Reset the XSPI memory interface */ + XSPI_RAM_FORCE_RESET(); + XSPI_RAM_RELEASE_RESET(); + + /* Enable GPIO clocks */ + XSPI_RAM_CLK_GPIO_CLK_ENABLE(); + XSPI_RAM_DQS0_GPIO_CLK_ENABLE(); + XSPI_RAM_DQS1_GPIO_CLK_ENABLE(); + XSPI_RAM_CS_GPIO_CLK_ENABLE(); + XSPI_RAM_D0_GPIO_CLK_ENABLE(); + XSPI_RAM_D1_GPIO_CLK_ENABLE(); + XSPI_RAM_D2_GPIO_CLK_ENABLE(); + XSPI_RAM_D3_GPIO_CLK_ENABLE(); + XSPI_RAM_D4_GPIO_CLK_ENABLE(); + XSPI_RAM_D5_GPIO_CLK_ENABLE(); + XSPI_RAM_D6_GPIO_CLK_ENABLE(); + XSPI_RAM_D7_GPIO_CLK_ENABLE(); + XSPI_RAM_D8_GPIO_CLK_ENABLE(); + XSPI_RAM_D9_GPIO_CLK_ENABLE(); + XSPI_RAM_D10_GPIO_CLK_ENABLE(); + XSPI_RAM_D11_GPIO_CLK_ENABLE(); + XSPI_RAM_D12_GPIO_CLK_ENABLE(); + XSPI_RAM_D13_GPIO_CLK_ENABLE(); + XSPI_RAM_D14_GPIO_CLK_ENABLE(); + XSPI_RAM_D15_GPIO_CLK_ENABLE(); + + /* SBS: Enable HSLV on XSPI1 */ + HAL_SBS_EnableIOSpeedOptimize(SBS_IO_XSPI1_HSLV); + + /* XSPI CS GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_CS_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = XSPI_RAM_CS_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_CS_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI DQS0 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_DQS0_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_DQS0_PIN_AF; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(XSPI_RAM_DQS0_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI DQS1 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_DQS1_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_DQS1_PIN_AF; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(XSPI_RAM_DQS1_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI CLK GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_CLK_PIN; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = XSPI_RAM_CLK_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_CLK_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D0 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D0_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D0_PIN_AF; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(XSPI_RAM_D0_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D1 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D1_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D1_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D1_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D2 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D2_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D2_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D2_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D3 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D3_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D3_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D3_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D4 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D4_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D4_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D4_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D5 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D5_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D5_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D5_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D6 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D6_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D6_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D6_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D7 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D7_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D7_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D7_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D8 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D8_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D8_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D8_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D9 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D9_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D9_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D9_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D10 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D10_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D10_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D10_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D11 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D11_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D11_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D11_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D12 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D12_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D12_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D12_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D13 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D13_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D13_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D13_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D14 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D14_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D14_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D14_GPIO_PORT, &GPIO_InitStruct); + + /* XSPI D15 GPIO pin configuration */ + GPIO_InitStruct.Pin = XSPI_RAM_D15_PIN; + GPIO_InitStruct.Alternate = XSPI_RAM_D15_PIN_AF; + HAL_GPIO_Init(XSPI_RAM_D15_GPIO_PORT, &GPIO_InitStruct); + + hdmatx.Init.Request = XPSI_RAM_DMAx_Request; + hdmatx.Instance = XSPI_RAM_DMAx_TX_CHANNEL; + + /* Configure the HSPI DMA transmit */ + hdmatx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdmatx.Init.SrcInc = DMA_SINC_INCREMENTED; + hdmatx.Init.DestInc = DMA_DINC_FIXED; + hdmatx.Init.Priority = DMA_HIGH_PRIORITY; + hdmatx.Init.SrcBurstLength = 4; + hdmatx.Init.DestBurstLength = 4; + hdmatx.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + hdmatx.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + hdmatx.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + hdmatx.Init.TransferAllocatedPort = (DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT1); + __HAL_LINKDMA(hxspi, hdmatx, hdmatx); + + /* Initialize the DMA channel */ + (void)HAL_DMA_Init(&hdmatx); + + hdmarx.Init.Request = XPSI_RAM_DMAx_Request; + hdmarx.Instance = XSPI_RAM_DMAx_RX_CHANNEL; + + /* Configure the HSPI DMA receive */ + hdmarx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdmarx.Init.SrcInc = DMA_SINC_FIXED; + hdmarx.Init.DestInc = DMA_DINC_INCREMENTED; + hdmarx.Init.Priority = DMA_HIGH_PRIORITY; + hdmarx.Init.SrcBurstLength = 4; + hdmarx.Init.DestBurstLength = 4; + hdmarx.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER; + hdmarx.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD; + hdmarx.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD; + hdmarx.Init.TransferAllocatedPort = (DMA_SRC_ALLOCATED_PORT1 | DMA_DEST_ALLOCATED_PORT0); + __HAL_LINKDMA(hxspi, hdmarx, hdmarx); + + /* Initialize the DMA channel */ + (void)HAL_DMA_Init(&hdmarx); + + /* Enable and set priority of the HSPI and DMA interrupts */ + HAL_NVIC_SetPriority(XSPI1_IRQn, BSP_XSPI_RAM_IT_PRIORITY, 0); + HAL_NVIC_SetPriority(XSPI_RAM_DMAx_RX_IRQn, BSP_XSPI_RAM_DMA_IT_PRIORITY, 0); + HAL_NVIC_SetPriority(XSPI_RAM_DMAx_TX_IRQn, BSP_XSPI_RAM_DMA_IT_PRIORITY, 0); + + HAL_NVIC_EnableIRQ(XSPI1_IRQn); + HAL_NVIC_EnableIRQ(XSPI_RAM_DMAx_RX_IRQn); + HAL_NVIC_EnableIRQ(XSPI_RAM_DMAx_TX_IRQn); +} + +/** + * @brief De-Initializes the XSPI MSP. + * @param hxspi XSPI handle + * @retval None + */ +static void XSPI_RAM_MspDeInit(XSPI_HandleTypeDef *hxspi) +{ + /* hxspi unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* XSPI DMA channels de-configuration */ + (void)HAL_DMA_DeInit(hxspi->hdmarx); + (void)HAL_DMA_DeInit(hxspi->hdmatx); + + /* XSPI GPIO pins de-configuration */ + HAL_GPIO_DeInit(XSPI_RAM_CLK_GPIO_PORT, XSPI_RAM_CLK_PIN); + HAL_GPIO_DeInit(XSPI_RAM_DQS0_GPIO_PORT, XSPI_RAM_DQS0_PIN); + HAL_GPIO_DeInit(XSPI_RAM_DQS1_GPIO_PORT, XSPI_RAM_DQS1_PIN); + HAL_GPIO_DeInit(XSPI_RAM_CS_GPIO_PORT, XSPI_RAM_CS_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D0_GPIO_PORT, XSPI_RAM_D0_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D1_GPIO_PORT, XSPI_RAM_D1_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D2_GPIO_PORT, XSPI_RAM_D2_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D3_GPIO_PORT, XSPI_RAM_D3_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D4_GPIO_PORT, XSPI_RAM_D4_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D5_GPIO_PORT, XSPI_RAM_D5_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D6_GPIO_PORT, XSPI_RAM_D6_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D7_GPIO_PORT, XSPI_RAM_D7_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D8_GPIO_PORT, XSPI_RAM_D8_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D9_GPIO_PORT, XSPI_RAM_D9_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D10_GPIO_PORT, XSPI_RAM_D10_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D11_GPIO_PORT, XSPI_RAM_D11_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D12_GPIO_PORT, XSPI_RAM_D12_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D13_GPIO_PORT, XSPI_RAM_D13_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D14_GPIO_PORT, XSPI_RAM_D14_PIN); + HAL_GPIO_DeInit(XSPI_RAM_D15_GPIO_PORT, XSPI_RAM_D15_PIN); + + /* Reset the XSPI memory interface */ + XSPI_RAM_FORCE_RESET(); + XSPI_RAM_RELEASE_RESET(); + + /* Disable the XSPI memory interface clock */ + XSPI_RAM_CLK_DISABLE(); +} +#endif /* USE_RAM_MEMORY_APS256XX */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.h b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.h new file mode 100644 index 0000000..d2b0517 --- /dev/null +++ b/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_xspi.h @@ -0,0 +1,530 @@ +/** + ****************************************************************************** + * @file stm32h7s78_discovery_xspi.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32h7s78_discovery_xspi.c driver. + ****************************************************************************** + * @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 STM32H7S78_DISCOVERY_XSPI_H +#define STM32H7S78_DISCOVERY_XSPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7s78_discovery_conf.h" +#include "stm32h7s78_discovery_errno.h" + +#ifndef USE_NOR_MEMORY_MX66UW1G45G +#define USE_NOR_MEMORY_MX66UW1G45G 1 +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#ifndef USE_RAM_MEMORY_APS256XX +#define USE_RAM_MEMORY_APS256XX 1 +#endif /* USE_RAM_MEMORY_APS256XX */ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +#include "../Components/mx66uw1g45g/mx66uw1g45g.h" +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +#include "../Components/aps256xx/aps256xx.h" +#endif /* USE_RAM_MEMORY_APS256XX */ + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H7S78_DK + * @{ + */ + +/** @addtogroup STM32H7S78_DK_XSPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup STM32H7S78_DK_XSPI_Exported_Types XSPI Exported Types + * @{ + */ +typedef enum +{ + XSPI_ACCESS_NONE = 0, /*!< Instance not initialized, */ + XSPI_ACCESS_INDIRECT, /*!< Instance use indirect mode access */ + XSPI_ACCESS_MMP /*!< Instance use Memory Mapped Mode read */ +} XSPI_Access_t; + +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +typedef struct +{ + pXSPI_CallbackTypeDef pMspInitCb; + pXSPI_CallbackTypeDef pMspDeInitCb; +} BSP_XSPI_Cb_t; +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) */ + +typedef struct +{ + uint32_t MemorySize; + uint32_t ClockPrescaler; + uint32_t SampleShifting; + uint32_t TransferRate; +} MX_XSPI_InitTypeDef; +/** + * @} + */ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Exported_Types XSPI_NOR Exported Types + * @{ + */ +#define BSP_XSPI_NOR_Info_t MX66UW1G45G_Info_t +#define BSP_XSPI_NOR_Interface_t MX66UW1G45G_Interface_t +#define BSP_XSPI_NOR_Transfer_t MX66UW1G45G_Transfer_t +#define BSP_XSPI_NOR_Erase_t MX66UW1G45G_Erase_t + +typedef struct +{ + XSPI_Access_t IsInitialized; /*!< Instance access Flash method */ + BSP_XSPI_NOR_Interface_t InterfaceMode; /*!< Flash Interface mode of Instance */ + BSP_XSPI_NOR_Transfer_t TransferRate; /*!< Flash Transfer mode of Instance */ +} XSPI_NOR_Ctx_t; + +typedef struct +{ + BSP_XSPI_NOR_Interface_t InterfaceMode; /*!< Current Flash Interface mode */ + BSP_XSPI_NOR_Transfer_t TransferRate; /*!< Current Flash Transfer rate */ +} BSP_XSPI_NOR_Init_t; +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @defgroup STM32H7S78_DK_XSPI_RAM_Exported_Types XSPI_RAM Exported Types + * @{ + */ +#define BSP_XSPI_RAM_ReadLatencyCode_t APS256XX_ReadLatencyCode_t +#define BSP_XSPI_RAM_WriteLatencyCode_t APS256XX_WriteLatencyCode_t + +typedef enum +{ + BSP_XSPI_RAM_VARIABLE_LATENCY = 0U, + BSP_XSPI_RAM_FIXED_LATENCY = APS256XX_MR0_LATENCY_TYPE +} BSP_XSPI_RAM_Latency_t; + +typedef enum +{ + BSP_XSPI_RAM_IO_X8_MODE = 0U, + BSP_XSPI_RAM_IO_X16_MODE = APS256XX_MR8_X8_X16, +} BSP_XSPI_RAM_IOMode_t; + +typedef struct +{ + XSPI_Access_t IsInitialized; /*!< Instance access Flash method */ + BSP_XSPI_RAM_Latency_t LatencyType; /*!< Latency Type of Instance */ + BSP_XSPI_RAM_ReadLatencyCode_t ReadLatencyCode; /*!< Read Latency Code of Instance */ + BSP_XSPI_RAM_WriteLatencyCode_t WriteLatencyCode; /*!< Write Latency Code of Instance */ + BSP_XSPI_RAM_IOMode_t IOMode; /*!< IO Mode of Instance */ +} XSPI_RAM_Ctx_t; + +typedef struct +{ + BSP_XSPI_RAM_Latency_t LatencyType; /*!< Current XSPI PSRAM Latency Type */ + BSP_XSPI_RAM_ReadLatencyCode_t ReadLatencyCode; /*!< Current XSPI PSRAM Read Latency Code */ + BSP_XSPI_RAM_WriteLatencyCode_t WriteLatencyCode; /*!< Current XSPI PSRAM Write Latency Code */ + BSP_XSPI_RAM_IOMode_t IOMode; /*!< Current XSPI PSRAM IO Mode */ +} BSP_XSPI_RAM_Cfg_t; +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup STM32H7S78_DK_XSPI_Exported_Constants XSPI Exported Constants + * @{ + */ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/* Definition for XSPIM NOR power resources */ +#define XSPI_NOR_PWR_ENABLE() HAL_PWREx_EnableXSPIM2() + +/* Definition for XSPI NOR clock resources */ +#define XSPI_NOR_CLK_ENABLE() __HAL_RCC_XSPI2_CLK_ENABLE() +#define XSPI_NOR_CLK_DISABLE() __HAL_RCC_XSPI2_CLK_DISABLE() + +#define XSPI_NOR_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_DQS_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D4_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D5_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D6_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() +#define XSPI_NOR_D7_GPIO_CLK_ENABLE() __HAL_RCC_GPION_CLK_ENABLE() + +#define XSPI_NOR_FORCE_RESET() __HAL_RCC_XSPI2_FORCE_RESET() +#define XSPI_NOR_RELEASE_RESET() __HAL_RCC_XSPI2_RELEASE_RESET() + +/* Definition for NOR XSPI Pins */ +/* XSPI_CLK */ +#define XSPI_NOR_CLK_PIN GPIO_PIN_6 +#define XSPI_NOR_CLK_GPIO_PORT GPION +#define XSPI_NOR_CLK_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_DQS */ +#define XSPI_NOR_DQS_PIN GPIO_PIN_0 +#define XSPI_NOR_DQS_GPIO_PORT GPION +#define XSPI_NOR_DQS_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_CS */ +#define XSPI_NOR_CS_PIN GPIO_PIN_1 +#define XSPI_NOR_CS_GPIO_PORT GPION +#define XSPI_NOR_CS_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D0 */ +#define XSPI_NOR_D0_PIN GPIO_PIN_2 +#define XSPI_NOR_D0_GPIO_PORT GPION +#define XSPI_NOR_D0_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D1 */ +#define XSPI_NOR_D1_PIN GPIO_PIN_3 +#define XSPI_NOR_D1_GPIO_PORT GPION +#define XSPI_NOR_D1_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D2 */ +#define XSPI_NOR_D2_PIN GPIO_PIN_4 +#define XSPI_NOR_D2_GPIO_PORT GPION +#define XSPI_NOR_D2_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D3 */ +#define XSPI_NOR_D3_PIN GPIO_PIN_5 +#define XSPI_NOR_D3_GPIO_PORT GPION +#define XSPI_NOR_D3_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D4 */ +#define XSPI_NOR_D4_PIN GPIO_PIN_8 +#define XSPI_NOR_D4_GPIO_PORT GPION +#define XSPI_NOR_D4_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D5 */ +#define XSPI_NOR_D5_PIN GPIO_PIN_9 +#define XSPI_NOR_D5_GPIO_PORT GPION +#define XSPI_NOR_D5_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D6 */ +#define XSPI_NOR_D6_PIN GPIO_PIN_10 +#define XSPI_NOR_D6_GPIO_PORT GPION +#define XSPI_NOR_D6_PIN_AF GPIO_AF9_XSPIM_P2 +/* XSPI_D7 */ +#define XSPI_NOR_D7_PIN GPIO_PIN_11 +#define XSPI_NOR_D7_GPIO_PORT GPION +#define XSPI_NOR_D7_PIN_AF GPIO_AF9_XSPIM_P2 +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/* Definition for XSPI RAM power resources */ +#define XSPI_RAM_PWR_ENABLE() HAL_PWREx_EnableXSPIM1() + +/* Definition for XSPI RAM clock resources */ +#define XSPI_RAM_CLK_ENABLE() __HAL_RCC_XSPI1_CLK_ENABLE() +#define XSPI_RAM_CLK_DISABLE() __HAL_RCC_XSPI1_CLK_DISABLE() + +#define XSPI_RAM_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOO_CLK_ENABLE() +#define XSPI_RAM_DQS0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOO_CLK_ENABLE() +#define XSPI_RAM_DQS1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOO_CLK_ENABLE() +#define XSPI_RAM_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOO_CLK_ENABLE() +#define XSPI_RAM_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D4_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D5_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D6_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D7_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D8_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D9_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D10_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D11_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D12_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D13_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D14_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() +#define XSPI_RAM_D15_GPIO_CLK_ENABLE() __HAL_RCC_GPIOP_CLK_ENABLE() + +#define XSPI_RAM_FORCE_RESET() __HAL_RCC_XSPI1_FORCE_RESET() +#define XSPI_RAM_RELEASE_RESET() __HAL_RCC_XSPI1_RELEASE_RESET() + +/* Definition for XSPI RAM Pins */ +/* XSPI_CLK */ +#define XSPI_RAM_CLK_PIN GPIO_PIN_4 +#define XSPI_RAM_CLK_GPIO_PORT GPIOO +#define XSPI_RAM_CLK_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_DQS0 */ +#define XSPI_RAM_DQS0_PIN GPIO_PIN_2 +#define XSPI_RAM_DQS0_GPIO_PORT GPIOO +#define XSPI_RAM_DQS0_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_DQS1 */ +#define XSPI_RAM_DQS1_PIN GPIO_PIN_3 +#define XSPI_RAM_DQS1_GPIO_PORT GPIOO +#define XSPI_RAM_DQS1_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_CS */ +#define XSPI_RAM_CS_PIN GPIO_PIN_0 +#define XSPI_RAM_CS_GPIO_PORT GPIOO +#define XSPI_RAM_CS_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D0 */ +#define XSPI_RAM_D0_PIN GPIO_PIN_0 +#define XSPI_RAM_D0_GPIO_PORT GPIOP +#define XSPI_RAM_D0_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D1 */ +#define XSPI_RAM_D1_PIN GPIO_PIN_1 +#define XSPI_RAM_D1_GPIO_PORT GPIOP +#define XSPI_RAM_D1_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D2 */ +#define XSPI_RAM_D2_PIN GPIO_PIN_2 +#define XSPI_RAM_D2_GPIO_PORT GPIOP +#define XSPI_RAM_D2_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D3 */ +#define XSPI_RAM_D3_PIN GPIO_PIN_3 +#define XSPI_RAM_D3_GPIO_PORT GPIOP +#define XSPI_RAM_D3_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D4 */ +#define XSPI_RAM_D4_PIN GPIO_PIN_4 +#define XSPI_RAM_D4_GPIO_PORT GPIOP +#define XSPI_RAM_D4_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D5 */ +#define XSPI_RAM_D5_PIN GPIO_PIN_5 +#define XSPI_RAM_D5_GPIO_PORT GPIOP +#define XSPI_RAM_D5_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D6 */ +#define XSPI_RAM_D6_PIN GPIO_PIN_6 +#define XSPI_RAM_D6_GPIO_PORT GPIOP +#define XSPI_RAM_D6_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D7 */ +#define XSPI_RAM_D7_PIN GPIO_PIN_7 +#define XSPI_RAM_D7_GPIO_PORT GPIOP +#define XSPI_RAM_D7_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D8 */ +#define XSPI_RAM_D8_PIN GPIO_PIN_8 +#define XSPI_RAM_D8_GPIO_PORT GPIOP +#define XSPI_RAM_D8_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D9 */ +#define XSPI_RAM_D9_PIN GPIO_PIN_9 +#define XSPI_RAM_D9_GPIO_PORT GPIOP +#define XSPI_RAM_D9_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D10 */ +#define XSPI_RAM_D10_PIN GPIO_PIN_10 +#define XSPI_RAM_D10_GPIO_PORT GPIOP +#define XSPI_RAM_D10_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D11 */ +#define XSPI_RAM_D11_PIN GPIO_PIN_11 +#define XSPI_RAM_D11_GPIO_PORT GPIOP +#define XSPI_RAM_D11_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D12 */ +#define XSPI_RAM_D12_PIN GPIO_PIN_12 +#define XSPI_RAM_D12_GPIO_PORT GPIOP +#define XSPI_RAM_D12_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D13 */ +#define XSPI_RAM_D13_PIN GPIO_PIN_13 +#define XSPI_RAM_D13_GPIO_PORT GPIOP +#define XSPI_RAM_D13_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D14 */ +#define XSPI_RAM_D14_PIN GPIO_PIN_14 +#define XSPI_RAM_D14_GPIO_PORT GPIOP +#define XSPI_RAM_D14_PIN_AF GPIO_AF9_XSPIM_P1 +/* XSPI_D15 */ +#define XSPI_RAM_D15_PIN GPIO_PIN_15 +#define XSPI_RAM_D15_GPIO_PORT GPIOP +#define XSPI_RAM_D15_PIN_AF GPIO_AF9_XSPIM_P1 +#endif /* USE_RAM_MEMORY_APS256XX */ +/** + * @} + */ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Exported_Constants XSPI_NOR Exported Constants + * @{ + */ +#define XSPI_NOR_INSTANCES_NUMBER 1U + +/* Definition for XSPI modes */ +#define BSP_XSPI_NOR_SPI_MODE (BSP_XSPI_NOR_Interface_t)MX66UW1G45G_SPI_MODE /* 1 Cmd, 1 Address and 1 Data Lines */ +#define BSP_XSPI_NOR_OPI_MODE (BSP_XSPI_NOR_Interface_t)MX66UW1G45G_OPI_MODE /* 8 Cmd, 8 Address and 8 Data Lines */ + +/* Definition for XSPI transfer rates */ +#define BSP_XSPI_NOR_STR_TRANSFER (BSP_XSPI_NOR_Transfer_t)MX66UW1G45G_STR_TRANSFER /* Single Transfer Rate */ +#define BSP_XSPI_NOR_DTR_TRANSFER (BSP_XSPI_NOR_Transfer_t)MX66UW1G45G_DTR_TRANSFER /* Double Transfer Rate */ + +/* XSPI erase types */ +#define BSP_XSPI_NOR_ERASE_4K MX66UW1G45G_ERASE_4K +#define BSP_XSPI_NOR_ERASE_64K MX66UW1G45G_ERASE_64K +#define BSP_XSPI_NOR_ERASE_CHIP MX66UW1G45G_ERASE_BULK + +/* XSPI block sizes */ +#define BSP_XSPI_NOR_BLOCK_4K MX66UW1G45G_SUBSECTOR_4K +#define BSP_XSPI_NOR_BLOCK_64K MX66UW1G45G_SECTOR_64K +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @defgroup STM32H7S78_DK_XSPI_RAM_Exported_Constants XSPI_RAM Exported Constants + * @{ + */ +#define XSPI_RAM_INSTANCES_NUMBER 1U + +/* XSPI Read Latency Code */ +#define BSP_XSPI_RAM_READ_LATENCY_3 (BSP_XSPI_RAM_ReadLatencyCode_t)APS256XX_READ_LATENCY_3 +#define BSP_XSPI_RAM_READ_LATENCY_4 (BSP_XSPI_RAM_ReadLatencyCode_t)APS256XX_READ_LATENCY_4 +#define BSP_XSPI_RAM_READ_LATENCY_5 (BSP_XSPI_RAM_ReadLatencyCode_t)APS256XX_READ_LATENCY_5 +#define BSP_XSPI_RAM_READ_LATENCY_6 (BSP_XSPI_RAM_ReadLatencyCode_t)APS256XX_READ_LATENCY_6 +#define BSP_XSPI_RAM_READ_LATENCY_7 (BSP_XSPI_RAM_ReadLatencyCode_t)APS256XX_READ_LATENCY_7 + +/* XSPI Write Latency Code */ +#define BSP_XSPI_RAM_WRITE_LATENCY_3 (BSP_XSPI_RAM_WriteLatencyCode_t)APS256XX_WRITE_LATENCY_3 +#define BSP_XSPI_RAM_WRITE_LATENCY_4 (BSP_XSPI_RAM_WriteLatencyCode_t)APS256XX_WRITE_LATENCY_4 +#define BSP_XSPI_RAM_WRITE_LATENCY_5 (BSP_XSPI_RAM_WriteLatencyCode_t)APS256XX_WRITE_LATENCY_5 +#define BSP_XSPI_RAM_WRITE_LATENCY_6 (BSP_XSPI_RAM_WriteLatencyCode_t)APS256XX_WRITE_LATENCY_6 +#define BSP_XSPI_RAM_WRITE_LATENCY_7 (BSP_XSPI_RAM_WriteLatencyCode_t)APS256XX_WRITE_LATENCY_7 + +/* DMA definitions for XSPI RAM DMA transfer */ +#define XSPI_RAM_DMAx_CLK_ENABLE __HAL_RCC_HPDMA1_CLK_ENABLE +#define XSPI_RAM_DMAx_CLK_DISABLE __HAL_RCC_HPDMA1_CLK_DISABLE +#define XSPI_RAM_DMAx_RX_CHANNEL HPDMA1_Channel12 +#define XSPI_RAM_DMAx_RX_IRQn HPDMA1_Channel12_IRQn +#define XPSI_RAM_DMAx_RX_IRQHandler HPDMA1_Channel12_IRQHandler +#define XSPI_RAM_DMAx_TX_CHANNEL HPDMA1_Channel11 +#define XSPI_RAM_DMAx_TX_IRQn HPDMA1_Channel11_IRQn +#define XPSI_RAM_DMAx_TX_IRQHandler HPDMA1_Channel11_IRQHandler +#define XPSI_RAM_DMAx_Request HPDMA1_REQUEST_XSPI1 +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +/* Exported variables --------------------------------------------------------*/ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Exported_Variables XSPI_NOR Exported Variables + * @{ + */ +extern XSPI_HandleTypeDef hxspi_nor[XSPI_NOR_INSTANCES_NUMBER]; +extern XSPI_NOR_Ctx_t XSPI_Nor_Ctx[XSPI_NOR_INSTANCES_NUMBER]; +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @defgroup STM32H7S78_DK_XSPI_RAM_Exported_Variables XSPI_RAM Exported Variables + * @{ + */ +extern XSPI_HandleTypeDef hxspi_ram[XSPI_RAM_INSTANCES_NUMBER]; +extern XSPI_RAM_Ctx_t XSPI_Ram_Ctx[XSPI_RAM_INSTANCES_NUMBER]; +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + +/* Exported functions --------------------------------------------------------*/ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +/** @defgroup STM32H7S78_DK_XSPI_NOR_Exported_Functions XSPI_NOR Exported Functions + * @{ + */ +int32_t BSP_XSPI_NOR_Init(uint32_t Instance, BSP_XSPI_NOR_Init_t *Init); +int32_t BSP_XSPI_NOR_DeInit(uint32_t Instance); +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +int32_t BSP_XSPI_NOR_RegisterMspCallbacks(uint32_t Instance, BSP_XSPI_Cb_t *CallBacks); +int32_t BSP_XSPI_NOR_RegisterDefaultMspCallbacks(uint32_t Instance); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) */ +int32_t BSP_XSPI_NOR_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +int32_t BSP_XSPI_NOR_Write(uint32_t Instance, const uint8_t *pData, uint32_t WriteAddr, uint32_t Size); +int32_t BSP_XSPI_NOR_Erase_Block(uint32_t Instance, uint32_t BlockAddress, BSP_XSPI_NOR_Erase_t BlockSize); +int32_t BSP_XSPI_NOR_Erase_Chip(uint32_t Instance); +int32_t BSP_XSPI_NOR_GetStatus(uint32_t Instance); +int32_t BSP_XSPI_NOR_GetInfo(uint32_t Instance, BSP_XSPI_NOR_Info_t *pInfo); +int32_t BSP_XSPI_NOR_EnableMemoryMappedMode(uint32_t Instance); +int32_t BSP_XSPI_NOR_DisableMemoryMappedMode(uint32_t Instance); +int32_t BSP_XSPI_NOR_ReadID(uint32_t Instance, uint8_t *Id); +int32_t BSP_XSPI_NOR_ConfigFlash(uint32_t Instance, BSP_XSPI_NOR_Interface_t Mode, BSP_XSPI_NOR_Transfer_t Rate); +int32_t BSP_XSPI_NOR_SuspendErase(uint32_t Instance); +int32_t BSP_XSPI_NOR_ResumeErase(uint32_t Instance); +int32_t BSP_XSPI_NOR_EnterDeepPowerDown(uint32_t Instance); +int32_t BSP_XSPI_NOR_LeaveDeepPowerDown(uint32_t Instance); + +/** + * @} + */ +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +/** @defgroup STM32H7S78_DK_XSPI_RAM_Exported_Functions XSPI_RAM Exported Functions + * @{ + */ +int32_t BSP_XSPI_RAM_Init(uint32_t Instance, BSP_XSPI_RAM_Cfg_t *Init); +int32_t BSP_XSPI_RAM_DeInit(uint32_t Instance); +#if (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) +int32_t BSP_XSPI_RAM_RegisterMspCallbacks(uint32_t Instance, BSP_XSPI_Cb_t *CallBacks); +int32_t BSP_XSPI_RAM_RegisterDefaultMspCallbacks(uint32_t Instance); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS == 1) */ +int32_t BSP_XSPI_RAM_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +int32_t BSP_XSPI_RAM_Read_DMA(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +int32_t BSP_XSPI_RAM_Write(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size); +int32_t BSP_XSPI_RAM_Write_DMA(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size); +int32_t BSP_XSPI_RAM_EnableMemoryMappedMode(uint32_t Instance); +int32_t BSP_XSPI_RAM_DisableMemoryMappedMode(uint32_t Instance); +int32_t BSP_XSPI_RAM_ReadID(uint32_t Instance, uint8_t *Id); +int32_t BSP_XSPI_RAM_Config16BitsOctalRAM(uint32_t Instance, BSP_XSPI_RAM_Cfg_t *Cfg); + +void BSP_XSPI_RAM_DMA_RX_IRQHandler(uint32_t Instance); +void BSP_XSPI_RAM_DMA_TX_IRQHandler(uint32_t Instance); +void BSP_XSPI_RAM_IRQHandler(uint32_t Instance); +/** + * @} + */ +#endif /* USE_RAM_MEMORY_APS256XX */ + + +/** @defgroup STM32H7S78_DK_XSPI_Exported_Init_Functions XSPI_Init Exported Functions + * @{ + */ + +/* These functions can be modified in case the current settings + need to be changed for specific application needs */ + +#if (USE_NOR_MEMORY_MX66UW1G45G == 1) +HAL_StatusTypeDef MX_XSPI_NOR_Init(XSPI_HandleTypeDef *hxspi, MX_XSPI_InitTypeDef *Init); +#endif /* USE_NOR_MEMORY_MX66UW1G45G */ + +#if (USE_RAM_MEMORY_APS256XX == 1) +HAL_StatusTypeDef MX_XSPI_RAM_Init(XSPI_HandleTypeDef *hxspi, MX_XSPI_InitTypeDef *Init); +#endif /* USE_RAM_MEMORY_APS256XX */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7S78_DISCOVERY_XSPI_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/.DS_Store b/Drivers/STM32H7RSxx_HAL_Driver/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7a37ef63d344298f2a9594528813eff17b76a472 GIT binary patch literal 10244 zcmeHMU2GIp6uxI#V1^F#f>a82U|_+tP@r`22hgzXE@&-S=(h9^*zWF(Wngxu?96V_ zT5WtXA{u>ABEA^^;)^kgi27oTF+?9sq`|_1~aysLGD~;aLVjZ z5PBf=K|*oPhnJuuY+?Cf4fT8KlknW1aX@3!Un4GkATDl4Becb+^?u8`^~(EG({^t zw74bfI(zdb8}G`xb|L3@DY__|wzCC0?VC-uowOb@QC8_?^R8|0bv=tM)6?yn$9*<7 zWvIK?bMtcxJnai&{l9flGT7ls6YHUAd-qL*pHH#dfyb-#%7J7cIU? ztx|i@myT~eV43-zw3jsjTF8S7ZV@*kuTS>}7_+G_QHfe*3AHP|kOOy9+IaQC&^YORlr#PcThMxaoqtyeod zv{t5RF>#~XpmrQZ5Gd3WlBjx{)@i3Rrmavz>~p8OP3tNOhby#I2=7*_wC=2%%b|&$ zB4kZkTsy?J-JSOQwn5Wjk8~c#(6n8vHLZt@H5mqfpyk!eDz#Q^k4(Rmd%eTyyxBH{ z=o|~=`(&B_xF~0$rt1@`JP-MKa=0cRq_Y<6Xrk#RDlM! zLM_z6I*39Hnjj7d*aJP#3w>aK1xLV!928*~9)?HYQFt7lf~Vmbcot5>%kT=k2Cu_g z@IHJ1AHpYa0mk4Wd<9>_75D*ugkRuSxC*~Z<m`R0_6(f-m*b5xkp-tf2HKoxX8o)$F?G-j@4jaAaLt$YW_q)y+%wwd*!*!3Z12 zoB(MFm)D}5L;SkH;1K5!m;}!;9(3x8m8B?~h&vI7ofsSDahZiEofpiGtdTJ`=$wG9 ztwXkz&J}FUhK(}DA(c3*)-*;Hj5b;pup25cR@kPhx^26HQAf)IcEt{431@0*;t5>j zJe8*l(w~tF1;h!J(XhUC;)5VIL%+6AnQN`XPg$&Vd6i z90Ly_J%XSfg~#9oJP9Y^Id~pU!3*#ryvl+72D}aLz!^9T=Mdr_!{-R^OYrR^!0s+V zRZ#eD0hs~<1c*t}6exe9i?9FLTjj4%@%}XTS|AYvK8S Uno3$T{p*LAHB1FZR, DBGMCU_AHB1FZR_GPDMA_0) +#define __HAL_DBGMCU_UNFREEZE_GPDMA0() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_0) + +#define __HAL_DBGMCU_FREEZE_GPDMA1() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_1) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_1) + +#define __HAL_DBGMCU_FREEZE_GPDMA2() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_2) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_2) + +#define __HAL_DBGMCU_FREEZE_GPDMA3() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_3) +#define __HAL_DBGMCU_UNFREEZE_GPDMA3() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_3) + +#define __HAL_DBGMCU_FREEZE_GPDMA4() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_4) +#define __HAL_DBGMCU_UNFREEZE_GPDMA4() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_4) + +#define __HAL_DBGMCU_FREEZE_GPDMA5() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_5) +#define __HAL_DBGMCU_UNFREEZE_GPDMA5() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_5) + +#define __HAL_DBGMCU_FREEZE_GPDMA6() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_6) +#define __HAL_DBGMCU_UNFREEZE_GPDMA6() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_6) + +#define __HAL_DBGMCU_FREEZE_GPDMA7() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_7) +#define __HAL_DBGMCU_UNFREEZE_GPDMA7() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_7) + +#define __HAL_DBGMCU_FREEZE_GPDMA8() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_8) +#define __HAL_DBGMCU_UNFREEZE_GPDMA8() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_8) + +#define __HAL_DBGMCU_FREEZE_GPDMA9() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_9) +#define __HAL_DBGMCU_UNFREEZE_GPDMA9() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_9) + +#define __HAL_DBGMCU_FREEZE_GPDMA10() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_10) +#define __HAL_DBGMCU_UNFREEZE_GPDMA10() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_10) + +#define __HAL_DBGMCU_FREEZE_GPDMA11() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_11) +#define __HAL_DBGMCU_UNFREEZE_GPDMA11() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_11) + +#define __HAL_DBGMCU_FREEZE_GPDMA12() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_12) +#define __HAL_DBGMCU_UNFREEZE_GPDMA12() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_12) + +#define __HAL_DBGMCU_FREEZE_GPDMA13() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_13) +#define __HAL_DBGMCU_UNFREEZE_GPDMA13() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_13) + +#define __HAL_DBGMCU_FREEZE_GPDMA14() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_14) +#define __HAL_DBGMCU_UNFREEZE_GPDMA14() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_14) + +#define __HAL_DBGMCU_FREEZE_GPDMA15() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_15) +#define __HAL_DBGMCU_UNFREEZE_GPDMA15() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_GPDMA_15) + +#define __HAL_DBGMCU_FREEZE_HPDMA0() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_0) +#define __HAL_DBGMCU_UNFREEZE_HPDMA0() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_0) + +#define __HAL_DBGMCU_FREEZE_HPDMA1() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_1) +#define __HAL_DBGMCU_UNFREEZE_HPDMA1() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_1) + +#define __HAL_DBGMCU_FREEZE_HPDMA2() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_2) +#define __HAL_DBGMCU_UNFREEZE_HPDMA2() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_2) + +#define __HAL_DBGMCU_FREEZE_HPDMA3() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_3) +#define __HAL_DBGMCU_UNFREEZE_HPDMA3() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_3) + +#define __HAL_DBGMCU_FREEZE_HPDMA4() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_4) +#define __HAL_DBGMCU_UNFREEZE_HPDMA4() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_4) + +#define __HAL_DBGMCU_FREEZE_HPDMA5() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_5) +#define __HAL_DBGMCU_UNFREEZE_HPDMA5() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_5) + +#define __HAL_DBGMCU_FREEZE_HPDMA6() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_6) +#define __HAL_DBGMCU_UNFREEZE_HPDMA6() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_6) + +#define __HAL_DBGMCU_FREEZE_HPDMA7() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_7) +#define __HAL_DBGMCU_UNFREEZE_HPDMA7() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_7) + +#define __HAL_DBGMCU_FREEZE_HPDMA8() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_8) +#define __HAL_DBGMCU_UNFREEZE_HPDMA8() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_8) + +#define __HAL_DBGMCU_FREEZE_HPDMA9() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_9) +#define __HAL_DBGMCU_UNFREEZE_HPDMA9() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_9) + +#define __HAL_DBGMCU_FREEZE_HPDMA10() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_10) +#define __HAL_DBGMCU_UNFREEZE_HPDMA10() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_10) + +#define __HAL_DBGMCU_FREEZE_HPDMA11() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_11) +#define __HAL_DBGMCU_UNFREEZE_HPDMA11() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_11) + +#define __HAL_DBGMCU_FREEZE_HPDMA12() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_12) +#define __HAL_DBGMCU_UNFREEZE_HPDMA12() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_12) + +#define __HAL_DBGMCU_FREEZE_HPDMA13() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_13) +#define __HAL_DBGMCU_UNFREEZE_HPDMA13() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_13) + +#define __HAL_DBGMCU_FREEZE_HPDMA14() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_14) +#define __HAL_DBGMCU_UNFREEZE_HPDMA14() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_14) + +#define __HAL_DBGMCU_FREEZE_HPDMA15() SET_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_15) +#define __HAL_DBGMCU_UNFREEZE_HPDMA15() CLEAR_BIT(DBGMCU->AHB5FZR, DBGMCU_AHB5FZR_HPDMA_15) + +#define __HAL_DBGMCU_FREEZE_I2C1() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_I2C1) +#define __HAL_DBGMCU_UNFREEZE_I2C1() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_I2C1) + +#define __HAL_DBGMCU_FREEZE_I2C2() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_I2C2) +#define __HAL_DBGMCU_UNFREEZE_I2C2() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_I2C2) + +#define __HAL_DBGMCU_FREEZE_I2C3() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_I2C3) +#define __HAL_DBGMCU_UNFREEZE_I2C3() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_I2C3) + +#define __HAL_DBGMCU_FREEZE_TIM2() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM2) +#define __HAL_DBGMCU_UNFREEZE_TIM2() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM2) + +#define __HAL_DBGMCU_FREEZE_TIM3() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM3) +#define __HAL_DBGMCU_UNFREEZE_TIM3() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM3) + +#define __HAL_DBGMCU_FREEZE_TIM4() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM4) +#define __HAL_DBGMCU_UNFREEZE_TIM4() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM4) + +#define __HAL_DBGMCU_FREEZE_TIM5() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM5) +#define __HAL_DBGMCU_UNFREEZE_TIM5() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM5) + +#define __HAL_DBGMCU_FREEZE_TIM6() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM6) +#define __HAL_DBGMCU_UNFREEZE_TIM6() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM6) + +#define __HAL_DBGMCU_FREEZE_TIM7() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM7) +#define __HAL_DBGMCU_UNFREEZE_TIM7() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM7) + +#define __HAL_DBGMCU_FREEZE_TIM9() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM9) +#define __HAL_DBGMCU_UNFREEZE_TIM9() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM9) + +#define __HAL_DBGMCU_FREEZE_TIM12() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM12) +#define __HAL_DBGMCU_UNFREEZE_TIM12() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM12) + +#define __HAL_DBGMCU_FREEZE_TIM13() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM13) +#define __HAL_DBGMCU_UNFREEZE_TIM13() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM13) + +#define __HAL_DBGMCU_FREEZE_TIM14() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM14) +#define __HAL_DBGMCU_UNFREEZE_TIM14() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_TIM14) + +#define __HAL_DBGMCU_FREEZE_TIM1() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM1) +#define __HAL_DBGMCU_UNFREEZE_TIM1() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM1) + +#define __HAL_DBGMCU_FREEZE_TIM15() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM15) +#define __HAL_DBGMCU_UNFREEZE_TIM15() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM15) + +#define __HAL_DBGMCU_FREEZE_TIM16() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM16) +#define __HAL_DBGMCU_UNFREEZE_TIM16() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM16) + +#define __HAL_DBGMCU_FREEZE_TIM17() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM17) +#define __HAL_DBGMCU_UNFREEZE_TIM17() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_TIM17) + +#define __HAL_DBGMCU_FREEZE_LPTIM1() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_LPTIM1) +#define __HAL_DBGMCU_UNFREEZE_LPTIM1() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_LPTIM1) + +#define __HAL_DBGMCU_FREEZE_LPTIM2() SET_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM2) +#define __HAL_DBGMCU_UNFREEZE_LPTIM2() CLEAR_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM2) + +#define __HAL_DBGMCU_FREEZE_LPTIM3() SET_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM3) +#define __HAL_DBGMCU_UNFREEZE_LPTIM3() CLEAR_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM3) + +#define __HAL_DBGMCU_FREEZE_LPTIM4() SET_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM4) +#define __HAL_DBGMCU_UNFREEZE_LPTIM4() CLEAR_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM4) + +#define __HAL_DBGMCU_FREEZE_LPTIM5() SET_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM5) +#define __HAL_DBGMCU_UNFREEZE_LPTIM5() CLEAR_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_LPTIM5) + +#define __HAL_DBGMCU_FREEZE_IWDG() SET_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_IWDG) +#define __HAL_DBGMCU_UNFREEZE_IWDG() CLEAR_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_IWDG) + +#define __HAL_DBGMCU_FREEZE_PWM1() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_PWM1) +#define __HAL_DBGMCU_UNFREEZE_PWM1() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_PWM1) + +#define __HAL_DBGMCU_FREEZE_RTC() SET_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_RTC) +#define __HAL_DBGMCU_UNFREEZE_RTC() CLEAR_BIT(DBGMCU->APB4FZR, DBGMCU_APB4FZR_RTC) + +#define __HAL_DBGMCU_FREEZE_WWDG() SET_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_WWDG) +#define __HAL_DBGMCU_UNFREEZE_WWDG() CLEAR_BIT(DBGMCU->APB1FZR, DBGMCU_APB1FZR_WWDG) + +/** + * @} + */ + +/** @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 Check SBS Memories Erase Status Flags. + * @retval The state of memory erase. + */ +#define __HAL_SBS_GET_MEMORIES_ERASE_STATUS() ((SBS->MESR) & (SBS_MESR_MEF)) + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup VREFBUF_VoltageScale VREFBUF Voltage Scale + * @{ + */ +#define VREFBUF_VOLTAGE_SCALE0 VREFBUF_CSR_VRS_OUT1 /*!< Voltage reference scale 0 (VREF_OUT1) */ +#define VREFBUF_VOLTAGE_SCALE1 VREFBUF_CSR_VRS_OUT2 /*!< Voltage reference scale 1 (VREF_OUT2) */ +#define VREFBUF_VOLTAGE_SCALE2 VREFBUF_CSR_VRS_OUT3 /*!< Voltage reference scale 2 (VREF_OUT3) */ +#define VREFBUF_VOLTAGE_SCALE3 VREFBUF_CSR_VRS_OUT4 /*!< Voltage reference scale 3 (VREF_OUT4) */ + + +#define IS_VREFBUF_VOLTAGE_SCALE(__SCALE__) (((__SCALE__) == VREFBUF_VOLTAGE_SCALE0) || \ + ((__SCALE__) == VREFBUF_VOLTAGE_SCALE1) || \ + ((__SCALE__) == VREFBUF_VOLTAGE_SCALE2) || \ + ((__SCALE__) == VREFBUF_VOLTAGE_SCALE3)) + + +/** + * @} + */ + +/** @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 */ + +#define IS_VREFBUF_HIGH_IMPEDANCE(__VALUE__) (((__VALUE__) == VREFBUF_HIGH_IMPEDANCE_DISABLE) || \ + ((__VALUE__) == VREFBUF_HIGH_IMPEDANCE_ENABLE)) + +#define IS_VREFBUF_TRIMMING(__VALUE__) ((__VALUE__) <= VREFBUF_CCR_TRIM) + +/** + * @} + */ + +/** @defgroup FMC_SwapBankMapping_Config FMC SwapBankMapping Config + * @{ + */ +#define FMC_SWAPBANK_MODE0 (0x00000000U) /*!< FMC memory default mapping is used */ +#define FMC_SWAPBANK_MODE1 FMC_BCR1_BMAP_0 /*!< FMC SDRAM bank1 and NOR/SRAM/PSRAM bank are swapped */ + +#define IS_FMC_SWAPBANK_MODE(__MODE__) (((__MODE__) == FMC_SWAPBANK_MODE0) || \ + ((__MODE__) == FMC_SWAPBANK_MODE1)) +/** + * @} + */ + +/** @addtogroup 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_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_COMPENSATION_CELL(__CELL__) (((__CELL__) == SBS_IO_ANALOG_CELL) || \ + ((__CELL__) == SBS_IO_XSPI1_CELL) || \ + ((__CELL__) == SBS_IO_XSPI2_CELL)) + +#define IS_SBS_COMPENSATION_CELL_READY(__CELL__) (((__CELL__) == SBS_IO_ANALOG_CELL_READY) || \ + ((__CELL__) == SBS_IO_XSPI1_CELL_READY) || \ + ((__CELL__) == SBS_IO_XSPI2_CELL_READY)) + +#define IS_SBS_IOHSLV(__HSLV__) (((__HSLV__) == SBS_IO_ANALOG_HSLV) || \ + ((__HSLV__) == SBS_IO_XSPI1_HSLV) || \ + ((__HSLV__) == SBS_IO_XSPI2_HSLV)) + +#define IS_SBS_EXTI_INPUT(__INPUT__) ((__INPUT__) < 16U) + +#define IS_SBS_EXTI_PIN(__PIN__) (((__PIN__) == SBS_EXTI_PIN_PORTA) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTB) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTC) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTD) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTE) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTF) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTG) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTH) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTM) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTN) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTO) || \ + ((__PIN__) == SBS_EXTI_PIN_PORTP)) +/** + * @} + */ + +/** @addtogroup AXIM_Private_Macros + * @{ + */ +#define IS_AXIM_ASIB_READ_ISS(__ISS__) (((__ISS__) == AXIM_ASIB_READ_ISS_NORMAL) || \ + ((__ISS__) == AXIM_ASIB_READ_ISS_FORCE_TO_1)) + +#define IS_AXIM_ASIB_WRITE_ISS(__ISS__) (((__ISS__) == AXIM_ASIB_WRITE_ISS_NORMAL) || \ + ((__ISS__) == AXIM_ASIB_WRITE_ISS_FORCE_TO_1)) + +#define IS_AXIM_QOS(__QOS__) ((__QOS__) <= AXIM_ASIB_READQOS_AR_QOS) + +#define IS_AXIM_AMIB_READ_ISS(__ISS__) (((__ISS__) == AXIM_AMIB_READ_ISS_NORMAL) || \ + ((__ISS__) == AXIM_AMIB_READ_ISS_FORCE_TO_1)) + +#define IS_AXIM_AMIB_WRITE_ISS(__ISS__) (((__ISS__) == AXIM_AMIB_WRITE_ISS_NORMAL) || \ + ((__ISS__) == AXIM_AMIB_WRITE_ISS_FORCE_TO_1)) + +#define IS_AXIM_AMIB_READ_ISS_BM(__ISS__) (((__ISS__) == AXIM_AMIB_READ_ISS_NORMAL) || \ + ((__ISS__) == AXIM_AMIB_READ_ISS_FORCE_TO_1)) + +#define IS_AXIM_AMIB_WRITE_ISS_BM(__ISS__) (((__ISS__) == AXIM_AMIB_WRITE_ISS_BM_NORMAL) || \ + ((__ISS__) == AXIM_AMIB_WRITE_ISS_BM_FORCE_TO_1)) + +/** + * @} + */ + +/* Exported variables --------------------------------------------------------*/ + +/** @addtogroup HAL_Exported_Variables + * @{ + */ +extern __IO uint32_t uwTick; +extern uint32_t uwTickPrio; +extern HAL_TickFreqTypeDef uwTickFreq; +/** + * @} + */ + +/* 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_EnableDBGSleepMode(void); +void HAL_DBGMCU_DisableDBGSleepMode(void); +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 + * @{ + */ + +/* SBS Control functions *****************************************************/ +uint32_t HAL_SBS_GetBootAddress(void); + +void HAL_SBS_IncrementHDPLValue(void); +uint32_t HAL_SBS_GetHDPLValue(void); + +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_UnlockDebugConfig(void); +void HAL_SBS_LockDebugConfig(void); + +void HAL_SBS_ConfigRSSCommand(uint32_t Cmd); +uint32_t HAL_SBS_GetRSSCommand(void); + +void HAL_SBS_EnableIOAnalogBooster(void); +void HAL_SBS_DisableIOAnalogBooster(void); +void HAL_SBS_EnableIOAnalogSwitchVdd(void); +void HAL_SBS_DisableIOAnalogSwitchVdd(void); +void HAL_SBS_ConfigEthernetPHY(uint32_t Config); +void HAL_SBS_ConfigAXISRAMWaitState(uint32_t Config); + +void HAL_SBS_EnableCompensationCell(uint32_t Selection); +void HAL_SBS_DisableCompensationCell(uint32_t Selection); +uint32_t HAL_SBS_GetCompensationCellReadyStatus(uint32_t Selection); +void HAL_SBS_ConfigCompensationCell(uint32_t Selection, uint32_t Code, uint32_t NmosValue, + uint32_t PmosValue); +HAL_StatusTypeDef HAL_SBS_GetCompensationCell(uint32_t Selection, uint32_t *pCode, uint32_t *pNmosValue, + uint32_t *pPmosValue); + +void HAL_SBS_EnableIOSpeedOptimize(uint32_t Selection); +void HAL_SBS_DisableIOSpeedOptimize(uint32_t Selection); + +void HAL_SBS_ConfigTimerBreakInput(uint32_t Input); +uint32_t HAL_SBS_GetTimerBreakInputConfig(void); + +void HAL_SBS_EXTIConfig(uint32_t Exti, uint32_t Port); +uint32_t HAL_SBS_GetEXTIConfig(uint32_t Exti); +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group5 + * @{ + */ + +/* VREFBUF Control functions *************************************************/ +void HAL_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling); +void HAL_VREFBUF_HighImpedanceConfig(uint32_t Mode); +void HAL_VREFBUF_TrimmingConfig(uint32_t TrimmingValue); +HAL_StatusTypeDef HAL_VREFBUF_Enable(void); +void HAL_VREFBUF_Disable(void); + + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group6 + * @{ + */ + +/* AXIM Configuration functions *************************************************/ +void HAL_AXIM_ASIB_EnablePacking(AXIM_ASIB_TypeDef *AsibInstance); +void HAL_AXIM_ASIB_DisablePacking(AXIM_ASIB_TypeDef *AsibInstance); +void HAL_AXIM_ASIB_IssuingConfig(AXIM_ASIB_TypeDef *AsibInstance, uint32_t ReadIssuing, + uint32_t WriteIssuing); +void HAL_AXIM_ASIB_ReadQoSConfig(AXIM_ASIB_TypeDef *AsibInstance, uint32_t QosPriority); +void HAL_AXIM_ASIB_WriteQoSConfig(AXIM_ASIB_TypeDef *AsibInstance, uint32_t QosPriority); + + +void HAL_AXIM_AMIB_EnablePacking(AXIM_AMIB_TypeDef *AmibInstance); +void HAL_AXIM_AMIB_DisablePacking(AXIM_AMIB_TypeDef *AmibInstance); +void HAL_AXIM_AMIB_IssuingConfig(AXIM_AMIB_TypeDef *AmibInstance, uint32_t ReadIssuing, + uint32_t WriteIssuing); +void HAL_AXIM_AMIB_IssuingConfigBusMatrix(AXIM_AMIB_TypeDef *AmibInstance, uint32_t ReadIssuing, + uint32_t WriteIssuing); +void HAL_AXIM_AMIB_EnableLongBurst(AXIM_AMIB_TypeDef *AmibInstance); +void HAL_AXIM_AMIB_DisableLongBurst(AXIM_AMIB_TypeDef *AmibInstance); +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group7 + * @{ + */ + +/* FMC Configuration functions *************************************************/ +void HAL_FMC_SetBankSwapConfig(uint32_t BankMapConfig); +uint32_t HAL_FMC_GetBankSwapConfig(void); +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_cortex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_cortex.h new file mode 100644 index 0000000..0be211f --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_cortex.h @@ -0,0 +1,413 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX 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 STM32H7RSxx_HAL_CORTEX_H +#define STM32H7RSxx_HAL_CORTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup CORTEX CORTEX + * @brief CORTEX HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Types CORTEX Exported Types + * @{ + */ + +/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition + * @brief MPU Region initialization structure + * @{ + */ +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 number 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. + */ + uint8_t Size; /*!< Specifies the size of the region to protect. + This parameter can be a value of @ref CORTEX_MPU_Region_Size */ + uint8_t SubRegionDisable; /*!< Specifies the number of the subregion protection to disable. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + uint8_t TypeExtField; /*!< Specifies the TEX field level. + This parameter can be a value of @ref CORTEX_MPU_TEX_Levels */ + 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 */ + uint8_t IsCacheable; /*!< Specifies the cacheable status of the region protected. + This parameter can be a value of @ref CORTEX_MPU_Access_Cacheable */ + uint8_t IsBufferable; /*!< Specifies the bufferable status of the protected region. + This parameter can be a value of @ref CORTEX_MPU_Access_Bufferable */ +} MPU_Region_InitTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group + * @{ + */ +#define NVIC_PRIORITYGROUP_0 7U /*!< 0 bit for pre-emption priority, + 4 bits for subpriority */ +#define NVIC_PRIORITYGROUP_1 6U /*!< 1 bit for pre-emption priority, + 3 bits for subpriority */ +#define NVIC_PRIORITYGROUP_2 5U /*!< 2 bits for pre-emption priority, + 2 bits for subpriority */ +#define NVIC_PRIORITYGROUP_3 4U /*!< 3 bits for pre-emption priority, + 1 bit for subpriority */ +#define NVIC_PRIORITYGROUP_4 3U /*!< 4 bits for pre-emption priority, + 0 bit for subpriority */ +/** + * @} + */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 0U +#define SYSTICK_CLKSOURCE_HCLK SysTick_CTRL_CLKSOURCE_Msk + +/** + * @} + */ + +/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control CORTEX MPU HFNMI and PRIVILEGED Access control + * @{ + */ +#define MPU_HFNMI_PRIVDEF_NONE 0U +#define MPU_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk +#define MPU_PRIVILEGED_DEFAULT MPU_CTRL_PRIVDEFENA_Msk +#define MPU_HFNMI_PRIVDEF (MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk) +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable + * @{ + */ +#define MPU_REGION_ENABLE 1U +#define MPU_REGION_DISABLE 0U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access + * @{ + */ +#define MPU_INSTRUCTION_ACCESS_ENABLE 0U +#define MPU_INSTRUCTION_ACCESS_DISABLE 1U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable + * @{ + */ +#define MPU_ACCESS_NOT_SHAREABLE 0U +#define MPU_ACCESS_SHAREABLE 1U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Cacheable CORTEX MPU Instruction Access Cacheable + * @{ + */ +#define MPU_ACCESS_CACHEABLE 1U +#define MPU_ACCESS_NOT_CACHEABLE 0U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Bufferable CORTEX MPU Instruction Access Bufferable + * @{ + */ +#define MPU_ACCESS_BUFFERABLE 1U +#define MPU_ACCESS_NOT_BUFFERABLE 0U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_TEX_Levels CORTEX MPU TEX Levels + * @{ + */ +#define MPU_TEX_LEVEL0 0U +#define MPU_TEX_LEVEL1 1U +#define MPU_TEX_LEVEL2 2U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Size CORTEX MPU Region Size + * @{ + * + * @brief MPU region size encoding: + * Size (Bytes) = 2^(MPU_REGION_SIZE + 1), + * where MPU_REGION_SIZE represents one of the values defined below. + */ +#define MPU_REGION_SIZE_32B 0x04U /* 32 Bytes */ +#define MPU_REGION_SIZE_64B 0x05U /* 64 Bytes */ +#define MPU_REGION_SIZE_128B 0x06U /* 128 Bytes */ +#define MPU_REGION_SIZE_256B 0x07U /* 256 Bytes */ +#define MPU_REGION_SIZE_512B 0x08U /* 512 Bytes */ +#define MPU_REGION_SIZE_1KB 0x09U /* 1 Kilobyte (1024 Bytes) */ +#define MPU_REGION_SIZE_2KB 0x0AU /* 2 Kilobytes */ +#define MPU_REGION_SIZE_4KB 0x0BU /* 4 Kilobytes */ +#define MPU_REGION_SIZE_8KB 0x0CU /* 8 Kilobytes */ +#define MPU_REGION_SIZE_16KB 0x0DU /* 16 Kilobytes */ +#define MPU_REGION_SIZE_32KB 0x0EU /* 32 Kilobytes */ +#define MPU_REGION_SIZE_64KB 0x0FU /* 64 Kilobytes */ +#define MPU_REGION_SIZE_128KB 0x10U /* 128 Kilobytes */ +#define MPU_REGION_SIZE_256KB 0x11U /* 256 Kilobytes */ +#define MPU_REGION_SIZE_512KB 0x12U /* 512 Kilobytes */ +#define MPU_REGION_SIZE_1MB 0x13U /* 1 Megabyte (1024 KB) */ +#define MPU_REGION_SIZE_2MB 0x14U /* 2 Megabytes */ +#define MPU_REGION_SIZE_4MB 0x15U /* 4 Megabytes */ +#define MPU_REGION_SIZE_8MB 0x16U /* 8 Megabytes */ +#define MPU_REGION_SIZE_16MB 0x17U /* 16 Megabytes */ +#define MPU_REGION_SIZE_32MB 0x18U /* 32 Megabytes */ +#define MPU_REGION_SIZE_64MB 0x19U /* 64 Megabytes */ +#define MPU_REGION_SIZE_128MB 0x1AU /* 128 Megabytes */ +#define MPU_REGION_SIZE_256MB 0x1BU /* 256 Megabytes */ +#define MPU_REGION_SIZE_512MB 0x1CU /* 512 Megabytes */ +#define MPU_REGION_SIZE_1GB 0x1DU /* 1 Gigabyte (1024 MB) */ +#define MPU_REGION_SIZE_2GB 0x1EU /* 2 Gigabytes */ +#define MPU_REGION_SIZE_4GB 0x1FU /* 4 Gigabytes (maximum region size) */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes + * @{ + */ +#define MPU_REGION_NO_ACCESS 0U +#define MPU_REGION_PRIV_RW 1U +#define MPU_REGION_PRIV_RW_URO 2U +#define MPU_REGION_FULL_ACCESS 3U +#define MPU_REGION_PRIV_RO 5U +#define MPU_REGION_PRIV_RO_URO 6U +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number + * @{ + */ +#define MPU_REGION_NUMBER0 0U +#define MPU_REGION_NUMBER1 1U +#define MPU_REGION_NUMBER2 2U +#define MPU_REGION_NUMBER3 3U +#define MPU_REGION_NUMBER4 4U +#define MPU_REGION_NUMBER5 5U +#define MPU_REGION_NUMBER6 6U +#define MPU_REGION_NUMBER7 7U +#define MPU_REGION_NUMBER8 8U +#define MPU_REGION_NUMBER9 9U +#define MPU_REGION_NUMBER10 10U +#define MPU_REGION_NUMBER11 11U +#define MPU_REGION_NUMBER12 12U +#define MPU_REGION_NUMBER13 13U +#define MPU_REGION_NUMBER14 14U +#define MPU_REGION_NUMBER15 15U +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + +/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * @{ + */ +/* Initialization and Configuration 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_SYSTICK_Config(uint32_t TicksNumb); +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * @{ + */ +/* Peripheral Control functions ***********************************************/ +uint32_t HAL_NVIC_GetPriorityGrouping(void); +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *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); +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); +void HAL_SYSTICK_IRQHandler(void); +void HAL_SYSTICK_Callback(void); +void HAL_MPU_Enable(uint32_t MPU_Control); +void HAL_MPU_Disable(void); +void HAL_MPU_EnableRegion(uint32_t RegionNumber); +void HAL_MPU_DisableRegion(uint32_t RegionNumber); +void HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef *pMPU_RegionInit); +void HAL_CORTEX_ClearEvent(void); +/** + * @} + */ + +/** + * @} + */ + +/* 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(__PRIO__, __PRIOGRP__) (((__PRIO__) < (1uL << __NVIC_PRIO_BITS)) && \ + ((__PRIO__) < (0x1uL << (0x07u - __PRIOGRP__)))) + +#define IS_NVIC_SUB_PRIORITY(__PRIO__, __PRIOGRP__) \ + ((__PRIOGRP__ < (0x07u - __NVIC_PRIO_BITS)) ?\ + ((__PRIO__) < (1u)): \ + ((__PRIO__) < (0x1uL << (__PRIOGRP__ - (0x07u - __NVIC_PRIO_BITS))))) + +#define IS_NVIC_DEVICE_IRQ(__IRQ__) ((__IRQ__) > SysTick_IRQn) + +#define IS_NVIC_PRIO_INTERRUPT(__IT__) (((__IT__) > HardFault_IRQn) && ((__IT__) != DebugMonitor_IRQn)) + +#define IS_SYSTICK_CLK_SOURCE(__SOURCE__) (((__SOURCE__) == SYSTICK_CLKSOURCE_HCLK) || \ + ((__SOURCE__) == SYSTICK_CLKSOURCE_HCLK_DIV8)) + +#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_SHAREABLE) || \ + ((__STATE__) == MPU_ACCESS_NOT_SHAREABLE)) + +#define IS_MPU_ACCESS_CACHEABLE(__STATE__) (((__STATE__) == MPU_ACCESS_CACHEABLE) || \ + ((__STATE__) == MPU_ACCESS_NOT_CACHEABLE)) + +#define IS_MPU_ACCESS_BUFFERABLE(__STATE__) (((__STATE__) == MPU_ACCESS_BUFFERABLE) || \ + ((__STATE__) == MPU_ACCESS_NOT_BUFFERABLE)) + +#define IS_MPU_TEX_LEVEL(__TYPE__) (((__TYPE__) == MPU_TEX_LEVEL0) || \ + ((__TYPE__) == MPU_TEX_LEVEL1) || \ + ((__TYPE__) == MPU_TEX_LEVEL2)) + +#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(__TYPE__) (((__TYPE__) == MPU_REGION_NO_ACCESS) || \ + ((__TYPE__) == MPU_REGION_PRIV_RW) || \ + ((__TYPE__) == MPU_REGION_PRIV_RW_URO) || \ + ((__TYPE__) == MPU_REGION_FULL_ACCESS) || \ + ((__TYPE__) == MPU_REGION_PRIV_RO) || \ + ((__TYPE__) == MPU_REGION_PRIV_RO_URO)) + +#define IS_MPU_REGION_NUMBER(__NUMBER__) ((__NUMBER__) <= MPU_REGION_NUMBER15) + +#define IS_MPU_REGION_SIZE(__SIZE__) (((__SIZE__) == MPU_REGION_SIZE_32B) || \ + ((__SIZE__) == MPU_REGION_SIZE_64B) || \ + ((__SIZE__) == MPU_REGION_SIZE_128B) || \ + ((__SIZE__) == MPU_REGION_SIZE_256B) || \ + ((__SIZE__) == MPU_REGION_SIZE_512B) || \ + ((__SIZE__) == MPU_REGION_SIZE_1KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_2KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_4KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_8KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_16KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_32KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_64KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_128KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_256KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_512KB) || \ + ((__SIZE__) == MPU_REGION_SIZE_1MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_2MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_4MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_8MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_16MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_32MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_64MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_128MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_256MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_512MB) || \ + ((__SIZE__) == MPU_REGION_SIZE_1GB) || \ + ((__SIZE__) == MPU_REGION_SIZE_2GB) || \ + ((__SIZE__) == MPU_REGION_SIZE_4GB)) + +#define IS_MPU_SUB_REGION_DISABLE(__SUBREGION__) ((__SUBREGION__) < (uint16_t)0x00FFU) + +#define IS_MPU_ADDRESS_MULTIPLE_SIZE(__ADDRESS__, __SIZE__) (((__ADDRESS__) & ((1<<(__SIZE__+1U))- 1U)) == 0U) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_CORTEX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc.h new file mode 100644 index 0000000..dfce8c0 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc.h @@ -0,0 +1,342 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_crc.h + * @author MCD Application Team + * @brief Header file of CRC 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 STM32H7RSxx_HAL_CRC_H +#define STM32H7RSxx_HAL_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 "stm32h7rsxx_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 /* STM32H7RSxx_HAL_CRC_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc_ex.h new file mode 100644 index 0000000..3602d57 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_crc_ex.h @@ -0,0 +1,150 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_crc_ex.h + * @author MCD Application Team + * @brief Header file of CRC HAL extended 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 STM32H7RSxx_HAL_CRC_EX_H +#define STM32H7RSxx_HAL_CRC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 /* STM32H7RSxx_HAL_CRC_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_def.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_def.h new file mode 100644 index 0000000..1adf214 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_def.h @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_def.h + * @author MCD Application Team + * @brief This file contains HAL common defines, enumeration, macros and + * structures definitions. + * + ****************************************************************************** + * @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 STM32H7RSxx_HAL_DEF_H +#define STM32H7RSxx_HAL_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.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 -----------------------------------------------------------*/ + +#if !defined(UNUSED) +#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ +#endif /* UNUSED */ + +#define HAL_MAX_DELAY 0xFFFFFFFFU + +#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) + +/** @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 (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((packed)) +#endif /* packed */ +#elif defined (__GNUC__) /* GNU Compiler */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + +/* Macro to get buffer 32-bytes aligned (aligned to cache line width) */ +#define ALIGN_32BYTES(buf) buf __attribute__((aligned(32))) + +/* Macro to get buffer 8-bytes aligned (aligned to double-word width) */ +/* This alignment is required for double-word DMA transfers */ +#define ALIGN_8BYTES(buf) buf __attribute__((aligned(8))) + +/* Legacy macros to get variable 4-bytes aligned */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__((aligned(4))) +#endif /* __ALIGN_END */ + +/** + * @brief __RAM_FUNC definition + */ +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +/* ARM Compiler V6 + --------------- + 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 + +#elif defined (__ICCARM__) +/* ICCARM Compiler + --------------- + RAM functions are defined using a specific toolchain keyword "__ramfunc". +*/ +#define __RAM_FUNC __ramfunc + +#elif defined (__GNUC__) +/* GNU Compiler + ------------ + RAM functions are defined using a specific toolchain attribute + "__attribute__((section(".RamFunc")))". +*/ +#define __RAM_FUNC __attribute__((section(".RamFunc"))) + +#endif /* __ARMCC_VERSION */ + +/** + * @brief __NOINLINE definition + */ +#if (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || defined (__GNUC__) +/* ARM V6 & GNU Compiler + --------------------- +*/ +#define __NOINLINE __attribute__((noinline)) + +#elif defined (__ICCARM__) +/* ICCARM Compiler + --------------- +*/ +#define __NOINLINE _Pragma("optimize = no_inline") + +#endif /* __ARMCC_VERSION || __GNUC__ */ + + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_DEF_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma.h new file mode 100644 index 0000000..38ed6be --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma.h @@ -0,0 +1,874 @@ +/** + ********************************************************************************************************************** + * @file stm32h7rsxx_hal_dma.h + * @author MCD Application Team + * @brief Header file of DMA 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 STM32H7RSxx_HAL_DMA_H +#define STM32H7RSxx_HAL_DMA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 + * @{ + */ +/* HPDMA1 requests */ +#define HPDMA1_REQUEST_JPEG_RX 0U /*!< HPDMA1 HW request is JPEG_DMA_RX */ +#define HPDMA1_REQUEST_JPEG_TX 1U /*!< HPDMA1 HW request is JPEG_DMA_TX */ +#define HPDMA1_REQUEST_XSPI1 2U /*!< HPDMA1 HW request is XSPI1 */ +#define HPDMA1_REQUEST_XSPI2 3U /*!< HPDMA1 HW request is XSPI2 */ +#define HPDMA1_REQUEST_SPI3_RX 4U /*!< HPDMA1 HW request is SPI3_RX */ +#define HPDMA1_REQUEST_SPI3_TX 5U /*!< HPDMA1 HW request is SPI3_TX */ +#define HPDMA1_REQUEST_SPI4_RX 6U /*!< HPDMA1 HW request is SPI4_RX */ +#define HPDMA1_REQUEST_SPI4_TX 7U /*!< HPDMA1 HW request is SPI4_TX */ +#define HPDMA1_REQUEST_ADC1 8U /*!< HPDMA1 HW request is ADC1 */ +#define HPDMA1_REQUEST_ADC2 9U /*!< HPDMA1 HW request is ADC2 */ +#define HPDMA1_REQUEST_ADF1_FLT0 10U /*!< HPDMA1 HW request is ADF1_FLT0 */ +#define HPDMA1_REQUEST_UART4_RX 11U /*!< HPDMA1 HW request is UART4_RX */ +#define HPDMA1_REQUEST_UART4_TX 12U /*!< HPDMA1 HW request is UART4_TX */ +#define HPDMA1_REQUEST_UART5_RX 13U /*!< HPDMA1 HW request is UART5_RX */ +#define HPDMA1_REQUEST_UART5_TX 14U /*!< HPDMA1 HW request is UART5_TX */ +#define HPDMA1_REQUEST_UART7_RX 15U /*!< HPDMA1 HW request is UART7_RX */ +#define HPDMA1_REQUEST_UART7_TX 16U /*!< HPDMA1 HW request is UART7_TX */ +#define HPDMA1_REQUEST_LPTIM2_IC1 17U /*!< HPDMA1 HW request is LPTIM2_IC1 */ +#define HPDMA1_REQUEST_LPTIM2_IC2 18U /*!< HPDMA1 HW request is LPTIM2_IC2 */ +#define HPDMA1_REQUEST_LPTIM2_UE 19U /*!< HPDMA1 HW request is LPTIM2_UE */ + +/* GPDMA1 requests */ +#define GPDMA1_REQUEST_ADC1 0U /*!< GPDMA1 HW request is ADC1 */ +#define GPDMA1_REQUEST_ADC2 1U /*!< GPDMA1 HW request is ADC2 */ +#define GPDMA1_REQUEST_CRYP_IN 2U /*!< GPDMA1 HW request is CRYP_IN */ +#define GPDMA1_REQUEST_CRYP_OUT 3U /*!< GPDMA1 HW request is CRYP_OUT */ +#define GPDMA1_REQUEST_SAES_IN 4U /*!< GPDMA1 HW request is SAES_IN */ +#define GPDMA1_REQUEST_SAES_OUT 5U /*!< GPDMA1 HW request is SAES_OUT */ +#define GPDMA1_REQUEST_HASH_IN 6U /*!< GPDMA1 HW request is HASH_IN */ +#define GPDMA1_REQUEST_TIM1_CH1 7U /*!< GPDMA1 HW request is TIM1_CH1 */ +#define GPDMA1_REQUEST_TIM1_CH2 8U /*!< GPDMA1 HW request is TIM1_CH2 */ +#define GPDMA1_REQUEST_TIM1_CH3 9U /*!< GPDMA1 HW request is TIM1_CH3 */ +#define GPDMA1_REQUEST_TIM1_CH4 10U /*!< GPDMA1 HW request is TIM1_CH4 */ +#define GPDMA1_REQUEST_TIM1_UP 11U /*!< GPDMA1 HW request is TIM1_UP */ +#define GPDMA1_REQUEST_TIM1_TRIG 12U /*!< GPDMA1 HW request is TIM1_TRIG */ +#define GPDMA1_REQUEST_TIM1_COM 13U /*!< GPDMA1 HW request is TIM1_COM */ +#define GPDMA1_REQUEST_TIM2_CH1 14U /*!< GPDMA1 HW request is TIM2_CH1 */ +#define GPDMA1_REQUEST_TIM2_CH2 15U /*!< GPDMA1 HW request is TIM2_CH2 */ +#define GPDMA1_REQUEST_TIM2_CH3 16U /*!< GPDMA1 HW request is TIM2_CH3 */ +#define GPDMA1_REQUEST_TIM2_CH4 17U /*!< GPDMA1 HW request is TIM2_CH4 */ +#define GPDMA1_REQUEST_TIM2_UP 18U /*!< GPDMA1 HW request is TIM2_UP */ +#define GPDMA1_REQUEST_TIM2_TRIG 19U /*!< GPDMA1 HW request is TIM2_TRIG */ +#define GPDMA1_REQUEST_TIM3_CH1 20U /*!< GPDMA1 HW request is TIM3_CH1 */ +#define GPDMA1_REQUEST_TIM3_CH2 21U /*!< GPDMA1 HW request is TIM3_CH2 */ +#define GPDMA1_REQUEST_TIM3_CH3 22U /*!< GPDMA1 HW request is TIM3_CH3 */ +#define GPDMA1_REQUEST_TIM3_CH4 23U /*!< GPDMA1 HW request is TIM3_CH4 */ +#define GPDMA1_REQUEST_TIM3_UP 24U /*!< GPDMA1 HW request is TIM3_UP */ +#define GPDMA1_REQUEST_TIM3_TRIG 25U /*!< GPDMA1 HW request is TIM3_TRIG */ +#define GPDMA1_REQUEST_TIM4_CH1 26U /*!< GPDMA1 HW request is TIM4_CH1 */ +#define GPDMA1_REQUEST_TIM4_CH2 27U /*!< GPDMA1 HW request is TIM4_CH2 */ +#define GPDMA1_REQUEST_TIM4_CH3 28U /*!< GPDMA1 HW request is TIM4_CH3 */ +#define GPDMA1_REQUEST_TIM4_CH4 29U /*!< GPDMA1 HW request is TIM4_CH4 */ +#define GPDMA1_REQUEST_TIM4_UP 30U /*!< GPDMA1 HW request is TIM4_UP */ +#define GPDMA1_REQUEST_TIM4_TRIG 31U /*!< GPDMA1 HW request is TIM4_TRIG */ +#define GPDMA1_REQUEST_TIM5_CH1 32U /*!< GPDMA1 HW request is TIM5_CH1 */ +#define GPDMA1_REQUEST_TIM5_CH2 33U /*!< GPDMA1 HW request is TIM5_CH2 */ +#define GPDMA1_REQUEST_TIM5_CH3 34U /*!< GPDMA1 HW request is TIM5_CH3 */ +#define GPDMA1_REQUEST_TIM5_CH4 35U /*!< GPDMA1 HW request is TIM5_CH4 */ +#define GPDMA1_REQUEST_TIM5_UP 36U /*!< GPDMA1 HW request is TIM5_UP */ +#define GPDMA1_REQUEST_TIM5_TRIG 37U /*!< GPDMA1 HW request is TIM5_TRIG */ +#define GPDMA1_REQUEST_TIM6_UP 38U /*!< GPDMA1 HW request is TIM6_UP */ +#define GPDMA1_REQUEST_TIM7_UP 39U /*!< GPDMA1 HW request is TIM7_UP */ +#define GPDMA1_REQUEST_TIM15_CH1 40U /*!< GPDMA1 HW request is TIM15_CH1 */ +#define GPDMA1_REQUEST_TIM15_CH2 41U /*!< GPDMA1 HW request is TIM15_CH2 */ +#define GPDMA1_REQUEST_TIM15_UP 42U /*!< GPDMA1 HW request is TIM15_UP */ +#define GPDMA1_REQUEST_TIM15_TRIG 43U /*!< GPDMA1 HW request is TIM15_TRIG */ +#define GPDMA1_REQUEST_TIM15_COM 44U /*!< GPDMA1 HW request is TIM15_COM */ +#define GPDMA1_REQUEST_TIM16_CH1 45U /*!< GPDMA1 HW request is TIM16_CH1 */ +#define GPDMA1_REQUEST_TIM16_UP 46U /*!< GPDMA1 HW request is TIM16_UP */ +#define GPDMA1_REQUEST_TIM16_COM 47U /*!< GPDMA1 HW request is TIM16_COM */ +#define GPDMA1_REQUEST_TIM17_CH1 48U /*!< GPDMA1 HW request is TIM17_CH1 */ +#define GPDMA1_REQUEST_TIM17_UP 49U /*!< GPDMA1 HW request is TIM17_UP */ +#define GPDMA1_REQUEST_TIM17_COM 50U /*!< GPDMA1 HW request is TIM17_COM */ +#define GPDMA1_REQUEST_SPI1_RX 51U /*!< GPDMA1 HW request is SPI1_RX */ +#define GPDMA1_REQUEST_SPI1_TX 52U /*!< GPDMA1 HW request is SPI1_TX */ +#define GPDMA1_REQUEST_SPI2_RX 53U /*!< GPDMA1 HW request is SPI2_RX */ +#define GPDMA1_REQUEST_SPI2_TX 54U /*!< GPDMA1 HW request is SPI2_TX */ +#define GPDMA1_REQUEST_SPI3_RX 55U /*!< GPDMA1 HW request is SPI3_RX */ +#define GPDMA1_REQUEST_SPI3_TX 56U /*!< GPDMA1 HW request is SPI3_TX */ +#define GPDMA1_REQUEST_SPI4_RX 57U /*!< GPDMA1 HW request is SPI4_RX */ +#define GPDMA1_REQUEST_SPI4_TX 58U /*!< GPDMA1 HW request is SPI4_TX */ +#define GPDMA1_REQUEST_SPI5_RX 59U /*!< GPDMA1 HW request is SPI5_RX */ +#define GPDMA1_REQUEST_SPI5_TX 60U /*!< GPDMA1 HW request is SPI5_TX */ +#define GPDMA1_REQUEST_SPI6_RX 61U /*!< GPDMA1 HW request is SPI6_RX */ +#define GPDMA1_REQUEST_SPI6_TX 62U /*!< GPDMA1 HW request is SPI6_TX */ +#define GPDMA1_REQUEST_SAI1_A 63U /*!< GPDMA1 HW request is SAI1_A */ +#define GPDMA1_REQUEST_SAI1_B 64U /*!< GPDMA1 HW request is SAI1_B */ +#define GPDMA1_REQUEST_SAI2_A 65U /*!< GPDMA1 HW request is SAI2_A */ +#define GPDMA1_REQUEST_SAI2_B 66U /*!< GPDMA1 HW request is SAI2_B */ +#define GPDMA1_REQUEST_I2C1_RX 67U /*!< GPDMA1 HW request is I2C1_RX */ +#define GPDMA1_REQUEST_I2C1_TX 68U /*!< GPDMA1 HW request is I2C1_TX */ +#define GPDMA1_REQUEST_I2C2_RX 69U /*!< GPDMA1 HW request is I2C2_RX */ +#define GPDMA1_REQUEST_I2C2_TX 70U /*!< GPDMA1 HW request is I2C2_TX */ +#define GPDMA1_REQUEST_I2C3_RX 71U /*!< GPDMA1 HW request is I2C3_RX */ +#define GPDMA1_REQUEST_I2C3_TX 72U /*!< GPDMA1 HW request is I2C3_TX */ +#define GPDMA1_REQUEST_USART1_RX 73U /*!< GPDMA1 HW request is USART1_RX */ +#define GPDMA1_REQUEST_USART1_TX 74U /*!< GPDMA1 HW request is USART1_TX */ +#define GPDMA1_REQUEST_USART2_RX 75U /*!< GPDMA1 HW request is USART2_RX */ +#define GPDMA1_REQUEST_USART2_TX 76U /*!< GPDMA1 HW request is USART2_TX */ +#define GPDMA1_REQUEST_USART3_RX 77U /*!< GPDMA1 HW request is USART3_RX */ +#define GPDMA1_REQUEST_USART3_TX 78U /*!< GPDMA1 HW request is USART3_TX */ +#define GPDMA1_REQUEST_UART4_RX 79U /*!< GPDMA1 HW request is UART4_RX */ +#define GPDMA1_REQUEST_UART4_TX 80U /*!< GPDMA1 HW request is UART4_TX */ +#define GPDMA1_REQUEST_UART5_RX 81U /*!< GPDMA1 HW request is UART5_RX */ +#define GPDMA1_REQUEST_UART5_TX 82U /*!< GPDMA1 HW request is UART5_TX */ +#define GPDMA1_REQUEST_UART7_RX 83U /*!< GPDMA1 HW request is UART7_RX */ +#define GPDMA1_REQUEST_UART7_TX 84U /*!< GPDMA1 HW request is UART7_TX */ +#define GPDMA1_REQUEST_UART8_RX 85U /*!< GPDMA1 HW request is UART8_RX */ +#define GPDMA1_REQUEST_UART8_TX 86U /*!< GPDMA1 HW request is UART8_TX */ +#define GPDMA1_REQUEST_CORDIC_READ 87U /*!< GPDMA1 HW request is CORDIC_READ */ +#define GPDMA1_REQUEST_CORDIC_WRITE 88U /*!< GPDMA1 HW request is CORDIC_WRITE */ +#define GPDMA1_REQUEST_LPTIM1_IC1 89U /*!< GPDMA1 HW request is LPTIM1_IC1 */ +#define GPDMA1_REQUEST_LPTIM1_IC2 90U /*!< GPDMA1 HW request is LPTIM1_IC2 */ +#define GPDMA1_REQUEST_LPTIM1_UE 91U /*!< GPDMA1 HW request is LPTIM1_UE */ +#define GPDMA1_REQUEST_LPTIM2_IC1 92U /*!< GPDMA1 HW request is LPTIM2_IC1 */ +#define GPDMA1_REQUEST_LPTIM2_IC2 93U /*!< GPDMA1 HW request is LPTIM2_IC2 */ +#define GPDMA1_REQUEST_LPTIM2_UE 94U /*!< GPDMA1 HW request is LPTIM2_UE */ +#define GPDMA1_REQUEST_SPDIF_RX_DT 95U /*!< GPDMA1 HW request is SPDIF_RX_DT */ +#define GPDMA1_REQUEST_SPDIF_RX_CS 96U /*!< GPDMA1 HW request is SPDIF_RX_CS */ +#define GPDMA1_REQUEST_ADF1_FLT0 97U /*!< GPDMA1 HW request is ADF1_FLT0 */ +#define GPDMA1_REQUEST_UCPD1_TX 98U /*!< GPDMA1 HW request is UCPD1_TX */ +#define GPDMA1_REQUEST_UCPD1_RX 99U /*!< GPDMA1 HW request is UCPD1_RX */ +#define GPDMA1_REQUEST_PSSI 100U /*!< GPDMA1 HW request is PSSI */ +#define GPDMA1_REQUEST_LPUART1_RX 101U /*!< GPDMA1 HW request is LPUART1_RX */ +#define GPDMA1_REQUEST_LPUART1_TX 102U /*!< GPDMA1 HW request is LPUART1_TX */ +#define GPDMA1_REQUEST_LPTIM3_IC1 103U /*!< GPDMA1 HW request is LPTIM3_IC1 */ +#define GPDMA1_REQUEST_LPTIM3_IC2 104U /*!< GPDMA1 HW request is LPTIM3_IC2 */ +#define GPDMA1_REQUEST_LPTIM3_UE 105U /*!< GPDMA1 HW request is LPTIM3_UE */ +#define GPDMA1_REQUEST_I3C1_RX 106U /*!< GPDMA1 HW request is I3C1_RX */ +#define GPDMA1_REQUEST_I3C1_TX 107U /*!< GPDMA1 HW request is I3C1_TX */ +#define GPDMA1_REQUEST_I3C1_TC 108U /*!< GPDMA1 HW request is I3C1_TC */ +#define GPDMA1_REQUEST_I3C1_RS 109U /*!< GPDMA1 HW request is I3C1_RS */ + +#define GPDMA1_MAX_REQUEST 109U + +/* 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 */ +#define DMA_SRC_DATAWIDTH_DOUBLEWORD DMA_CTR1_SDW_LOG2 /*!< Source data width : DoubleWord */ +/** + * @} + */ + +/** @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 */ +#define DMA_DEST_DATAWIDTH_DOUBLEWORD DMA_CTR1_DDW_LOG2 /*!< Destination data width : DoubleWord */ + +/** + * @} + */ + +/** @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 Privilege Attribute + * @{ + */ + + +#define DMA_CHANNEL_PRIV (DMA_CHANNEL_ATTR_PRIV_MASK | (1U<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 "stm32h7rsxx_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); + +HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma); +HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, + uint32_t *const pLockState); + + +/** + * @} + */ + +/** + * @} + */ + + +/* 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 (0x01000000U) /* DMA channel privilege */ +#define DMA_CHANNEL_PRIV_VAL_POS 0U +#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) || \ + ((WIDTH) == DMA_SRC_DATAWIDTH_DOUBLEWORD)) + +#define IS_DMA_DESTINATION_DATA_WIDTH(WIDTH) \ + (((WIDTH) == DMA_DEST_DATAWIDTH_BYTE) || \ + ((WIDTH) == DMA_DEST_DATAWIDTH_HALFWORD) || \ + ((WIDTH) == DMA_DEST_DATAWIDTH_WORD) || \ + ((WIDTH) == DMA_DEST_DATAWIDTH_DOUBLEWORD)) + +#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) + +#define IS_DMA_REQUEST(REQUEST) \ + (((REQUEST) == DMA_REQUEST_SW) || \ + ((REQUEST) <= GPDMA1_REQUEST_I3C1_RS)) + +#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)) + +#define IS_DMA_GLOBAL_ACTIVE_FLAG(INSTANCE, GLOBAL_FLAG) \ + (((INSTANCE)->MISR & (GLOBAL_FLAG))) +#define IS_DMA_ATTRIBUTES(ATTRIBUTE) \ + (((ATTRIBUTE) == DMA_CHANNEL_PRIV) || \ + ((ATTRIBUTE) == DMA_CHANNEL_NPRIV)) + +/** + * @} + */ + + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Private_Functions DMA Private Functions + * @brief DMA Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_DMA_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma2d.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma2d.h new file mode 100644 index 0000000..86559f0 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma2d.h @@ -0,0 +1,715 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_dma2d.h + * @author MCD Application Team + * @brief Header file of DMA2D 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 STM32H7RSxx_HAL_DMA2D_H +#define STM32H7RSxx_HAL_DMA2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +#if defined (DMA2D) + +/** @addtogroup DMA2D DMA2D + * @brief DMA2D HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Types DMA2D Exported Types + * @{ + */ +#define MAX_DMA2D_LAYER 2U /*!< DMA2D maximum number of layers */ + +/** + * @brief DMA2D CLUT Structure definition + */ +typedef struct +{ + uint32_t *pCLUT; /*!< Configures the DMA2D CLUT memory address.*/ + + uint32_t CLUTColorMode; /*!< Configures the DMA2D CLUT color mode. + This parameter can be one value of @ref DMA2D_CLUT_CM. */ + + uint32_t Size; /*!< Configures the DMA2D CLUT size. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.*/ +} DMA2D_CLUTCfgTypeDef; + +/** + * @brief DMA2D Init structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Configures the DMA2D transfer mode. + This parameter can be one value of @ref DMA2D_Mode. */ + + uint32_t ColorMode; /*!< Configures the color format of the output image. + This parameter can be one value of @ref DMA2D_Output_Color_Mode. */ + + uint32_t OutputOffset; /*!< Specifies the Offset value. + This parameter must be a number between + Min_Data = 0x0000 and Max_Data = 0x3FFF. */ + uint32_t AlphaInverted; /*!< Select regular or inverted alpha value for the output pixel format converter. + This parameter can be one value of @ref DMA2D_Alpha_Inverted. */ + + uint32_t RedBlueSwap; /*!< Select regular mode (RGB or ARGB) or swap mode (BGR or ABGR) + for the output pixel format converter. + This parameter can be one value of @ref DMA2D_RB_Swap. */ + + + uint32_t BytesSwap; /*!< Select byte regular mode or bytes swap mode (two by two). + This parameter can be one value of @ref DMA2D_Bytes_Swap. */ + + uint32_t LineOffsetMode; /*!< Configures how is expressed the line offset for the foreground, background and output. + This parameter can be one value of @ref DMA2D_Line_Offset_Mode. */ + +} DMA2D_InitTypeDef; + + +/** + * @brief DMA2D Layer structure definition + */ +typedef struct +{ + uint32_t InputOffset; /*!< Configures the DMA2D foreground or background offset. + This parameter must be a number between + Min_Data = 0x0000 and Max_Data = 0x3FFF. */ + + uint32_t InputColorMode; /*!< Configures the DMA2D foreground or background color mode. + This parameter can be one value of @ref DMA2D_Input_Color_Mode. */ + + uint32_t AlphaMode; /*!< Configures the DMA2D foreground or background alpha mode. + This parameter can be one value of @ref DMA2D_Alpha_Mode. */ + + uint32_t InputAlpha; /*!< Specifies the DMA2D foreground or background alpha value and color value + in case of A8 or A4 color mode. + This parameter must be a number between Min_Data = 0x00 + and Max_Data = 0xFF except for the color modes detailed below. + @note In case of A8 or A4 color mode (ARGB), + this parameter must be a number between + Min_Data = 0x00000000 and Max_Data = 0xFFFFFFFF where + - InputAlpha[24:31] is the alpha value ALPHA[0:7] + - InputAlpha[16:23] is the red value RED[0:7] + - InputAlpha[8:15] is the green value GREEN[0:7] + - InputAlpha[0:7] is the blue value BLUE[0:7]. */ + uint32_t AlphaInverted; /*!< Select regular or inverted alpha value. + This parameter can be one value of @ref DMA2D_Alpha_Inverted. */ + + uint32_t RedBlueSwap; /*!< Select regular mode (RGB or ARGB) or swap mode (BGR or ABGR). + This parameter can be one value of @ref DMA2D_RB_Swap. */ + + uint32_t ChromaSubSampling; /*!< Configure the chroma sub-sampling mode for the YCbCr color mode + This parameter can be one value of @ref DMA2D_Chroma_Sub_Sampling */ + +} DMA2D_LayerCfgTypeDef; + +/** + * @brief HAL DMA2D State structures definition + */ +typedef enum +{ + HAL_DMA2D_STATE_RESET = 0x00U, /*!< DMA2D not yet initialized or disabled */ + HAL_DMA2D_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_DMA2D_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_DMA2D_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_DMA2D_STATE_ERROR = 0x04U, /*!< DMA2D state error */ + HAL_DMA2D_STATE_SUSPEND = 0x05U /*!< DMA2D process is suspended */ +} HAL_DMA2D_StateTypeDef; + +/** + * @brief DMA2D handle Structure definition + */ +typedef struct __DMA2D_HandleTypeDef +{ + DMA2D_TypeDef *Instance; /*!< DMA2D register base address. */ + + DMA2D_InitTypeDef Init; /*!< DMA2D communication parameters. */ + + void (* XferCpltCallback)(struct __DMA2D_HandleTypeDef *hdma2d); /*!< DMA2D transfer complete callback. */ + + void (* XferErrorCallback)(struct __DMA2D_HandleTypeDef *hdma2d); /*!< DMA2D transfer error callback. */ + +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) + void (* LineEventCallback)(struct __DMA2D_HandleTypeDef *hdma2d); /*!< DMA2D line event callback. */ + + void (* CLUTLoadingCpltCallback)(struct __DMA2D_HandleTypeDef *hdma2d); /*!< DMA2D CLUT loading completion callback */ + + void (* MspInitCallback)(struct __DMA2D_HandleTypeDef *hdma2d); /*!< DMA2D Msp Init callback. */ + + void (* MspDeInitCallback)(struct __DMA2D_HandleTypeDef *hdma2d); /*!< DMA2D Msp DeInit callback. */ + +#endif /* (USE_HAL_DMA2D_REGISTER_CALLBACKS) */ + + DMA2D_LayerCfgTypeDef LayerCfg[MAX_DMA2D_LAYER]; /*!< DMA2D Layers parameters */ + + HAL_LockTypeDef Lock; /*!< DMA2D lock. */ + + __IO HAL_DMA2D_StateTypeDef State; /*!< DMA2D transfer state. */ + + __IO uint32_t ErrorCode; /*!< DMA2D error code. */ +} DMA2D_HandleTypeDef; + +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) +/** + * @brief HAL DMA2D Callback pointer definition + */ +typedef void (*pDMA2D_CallbackTypeDef)(DMA2D_HandleTypeDef *hdma2d); /*!< Pointer to a DMA2D common callback function */ +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Constants DMA2D Exported Constants + * @{ + */ + +/** @defgroup DMA2D_Error_Code DMA2D Error Code + * @{ + */ +#define HAL_DMA2D_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_DMA2D_ERROR_TE 0x00000001U /*!< Transfer error */ +#define HAL_DMA2D_ERROR_CE 0x00000002U /*!< Configuration error */ +#define HAL_DMA2D_ERROR_CAE 0x00000004U /*!< CLUT access error */ +#define HAL_DMA2D_ERROR_TIMEOUT 0x00000020U /*!< Timeout error */ +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) +#define HAL_DMA2D_ERROR_INVALID_CALLBACK 0x00000040U /*!< Invalid callback error */ +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup DMA2D_Mode DMA2D Mode + * @{ + */ +#define DMA2D_M2M 0x00000000U /*!< DMA2D memory to memory transfer mode */ +#define DMA2D_M2M_PFC DMA2D_CR_MODE_0 /*!< DMA2D memory to memory with pixel format conversion transfer mode */ +#define DMA2D_M2M_BLEND DMA2D_CR_MODE_1 /*!< DMA2D memory to memory with blending transfer mode */ +#define DMA2D_R2M (DMA2D_CR_MODE_1 | DMA2D_CR_MODE_0) /*!< DMA2D register to memory transfer mode */ +#define DMA2D_M2M_BLEND_FG DMA2D_CR_MODE_2 /*!< DMA2D memory to memory with blending transfer mode and fixed color FG */ +#define DMA2D_M2M_BLEND_BG (DMA2D_CR_MODE_2 | DMA2D_CR_MODE_0) /*!< DMA2D memory to memory with blending transfer mode and fixed color BG */ +/** + * @} + */ + +/** @defgroup DMA2D_Output_Color_Mode DMA2D Output Color Mode + * @{ + */ +#define DMA2D_OUTPUT_ARGB8888 0x00000000U /*!< ARGB8888 DMA2D color mode */ +#define DMA2D_OUTPUT_RGB888 DMA2D_OPFCCR_CM_0 /*!< RGB888 DMA2D color mode */ +#define DMA2D_OUTPUT_RGB565 DMA2D_OPFCCR_CM_1 /*!< RGB565 DMA2D color mode */ +#define DMA2D_OUTPUT_ARGB1555 (DMA2D_OPFCCR_CM_0|DMA2D_OPFCCR_CM_1) /*!< ARGB1555 DMA2D color mode */ +#define DMA2D_OUTPUT_ARGB4444 DMA2D_OPFCCR_CM_2 /*!< ARGB4444 DMA2D color mode */ +/** + * @} + */ + +/** @defgroup DMA2D_Input_Color_Mode DMA2D Input Color Mode + * @{ + */ +#define DMA2D_INPUT_ARGB8888 0x00000000U /*!< ARGB8888 color mode */ +#define DMA2D_INPUT_RGB888 0x00000001U /*!< RGB888 color mode */ +#define DMA2D_INPUT_RGB565 0x00000002U /*!< RGB565 color mode */ +#define DMA2D_INPUT_ARGB1555 0x00000003U /*!< ARGB1555 color mode */ +#define DMA2D_INPUT_ARGB4444 0x00000004U /*!< ARGB4444 color mode */ +#define DMA2D_INPUT_L8 0x00000005U /*!< L8 color mode */ +#define DMA2D_INPUT_AL44 0x00000006U /*!< AL44 color mode */ +#define DMA2D_INPUT_AL88 0x00000007U /*!< AL88 color mode */ +#define DMA2D_INPUT_L4 0x00000008U /*!< L4 color mode */ +#define DMA2D_INPUT_A8 0x00000009U /*!< A8 color mode */ +#define DMA2D_INPUT_A4 0x0000000AU /*!< A4 color mode */ +#define DMA2D_INPUT_YCBCR 0x0000000BU /*!< YCbCr color mode */ +/** + * @} + */ + +/** @defgroup DMA2D_Alpha_Mode DMA2D Alpha Mode + * @{ + */ +#define DMA2D_NO_MODIF_ALPHA 0x00000000U /*!< No modification of the alpha channel value */ +#define DMA2D_REPLACE_ALPHA 0x00000001U /*!< Replace original alpha channel value by programmed alpha value */ +#define DMA2D_COMBINE_ALPHA 0x00000002U /*!< Replace original alpha channel value by programmed alpha value + with original alpha channel value */ +/** + * @} + */ + +/** @defgroup DMA2D_Alpha_Inverted DMA2D Alpha Inversion + * @{ + */ +#define DMA2D_REGULAR_ALPHA 0x00000000U /*!< No modification of the alpha channel value */ +#define DMA2D_INVERTED_ALPHA 0x00000001U /*!< Invert the alpha channel value */ +/** + * @} + */ + +/** @defgroup DMA2D_RB_Swap DMA2D Red and Blue Swap + * @{ + */ +#define DMA2D_RB_REGULAR 0x00000000U /*!< Select regular mode (RGB or ARGB) */ +#define DMA2D_RB_SWAP 0x00000001U /*!< Select swap mode (BGR or ABGR) */ +/** + * @} + */ + + + +/** @defgroup DMA2D_Line_Offset_Mode DMA2D Line Offset Mode + * @{ + */ +#define DMA2D_LOM_PIXELS 0x00000000U /*!< Line offsets expressed in pixels */ +#define DMA2D_LOM_BYTES DMA2D_CR_LOM /*!< Line offsets expressed in bytes */ +/** + * @} + */ + +/** @defgroup DMA2D_Bytes_Swap DMA2D Bytes Swap + * @{ + */ +#define DMA2D_BYTES_REGULAR 0x00000000U /*!< Bytes in regular order in output FIFO */ +#define DMA2D_BYTES_SWAP DMA2D_OPFCCR_SB /*!< Bytes are swapped two by two in output FIFO */ +/** + * @} + */ + +/** @defgroup DMA2D_Chroma_Sub_Sampling DMA2D Chroma Sub Sampling + * @{ + */ +#define DMA2D_NO_CSS 0x00000000U /*!< No chroma sub-sampling 4:4:4 */ +#define DMA2D_CSS_422 0x00000001U /*!< chroma sub-sampling 4:2:2 */ +#define DMA2D_CSS_420 0x00000002U /*!< chroma sub-sampling 4:2:0 */ +/** + * @} + */ + +/** @defgroup DMA2D_CLUT_CM DMA2D CLUT Color Mode + * @{ + */ +#define DMA2D_CCM_ARGB8888 0x00000000U /*!< ARGB8888 DMA2D CLUT color mode */ +#define DMA2D_CCM_RGB888 0x00000001U /*!< RGB888 DMA2D CLUT color mode */ +/** + * @} + */ + +/** @defgroup DMA2D_Interrupts DMA2D Interrupts + * @{ + */ +#define DMA2D_IT_CE DMA2D_CR_CEIE /*!< Configuration Error Interrupt */ +#define DMA2D_IT_CTC DMA2D_CR_CTCIE /*!< CLUT Transfer Complete Interrupt */ +#define DMA2D_IT_CAE DMA2D_CR_CAEIE /*!< CLUT Access Error Interrupt */ +#define DMA2D_IT_TW DMA2D_CR_TWIE /*!< Transfer Watermark Interrupt */ +#define DMA2D_IT_TC DMA2D_CR_TCIE /*!< Transfer Complete Interrupt */ +#define DMA2D_IT_TE DMA2D_CR_TEIE /*!< Transfer Error Interrupt */ +/** + * @} + */ + +/** @defgroup DMA2D_Flags DMA2D Flags + * @{ + */ +#define DMA2D_FLAG_CE DMA2D_ISR_CEIF /*!< Configuration Error Interrupt Flag */ +#define DMA2D_FLAG_CTC DMA2D_ISR_CTCIF /*!< CLUT Transfer Complete Interrupt Flag */ +#define DMA2D_FLAG_CAE DMA2D_ISR_CAEIF /*!< CLUT Access Error Interrupt Flag */ +#define DMA2D_FLAG_TW DMA2D_ISR_TWIF /*!< Transfer Watermark Interrupt Flag */ +#define DMA2D_FLAG_TC DMA2D_ISR_TCIF /*!< Transfer Complete Interrupt Flag */ +#define DMA2D_FLAG_TE DMA2D_ISR_TEIF /*!< Transfer Error Interrupt Flag */ +/** + * @} + */ + +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) +/** + * @brief HAL DMA2D common Callback ID enumeration definition + */ +typedef enum +{ + HAL_DMA2D_MSPINIT_CB_ID = 0x00U, /*!< DMA2D MspInit callback ID */ + HAL_DMA2D_MSPDEINIT_CB_ID = 0x01U, /*!< DMA2D MspDeInit callback ID */ + HAL_DMA2D_TRANSFERCOMPLETE_CB_ID = 0x02U, /*!< DMA2D transfer complete callback ID */ + HAL_DMA2D_TRANSFERERROR_CB_ID = 0x03U, /*!< DMA2D transfer error callback ID */ + HAL_DMA2D_LINEEVENT_CB_ID = 0x04U, /*!< DMA2D line event callback ID */ + HAL_DMA2D_CLUTLOADINGCPLT_CB_ID = 0x05U, /*!< DMA2D CLUT loading completion callback ID */ +} HAL_DMA2D_CallbackIDTypeDef; +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ + + +/** + * @} + */ +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Macros DMA2D Exported Macros + * @{ + */ + +/** @brief Reset DMA2D handle state + * @param __HANDLE__ specifies the DMA2D handle. + * @retval None + */ +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) +#define __HAL_DMA2D_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_DMA2D_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + }while(0) +#else +#define __HAL_DMA2D_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DMA2D_STATE_RESET) +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ + + +/** + * @brief Enable the DMA2D. + * @param __HANDLE__ DMA2D handle + * @retval None. + */ +#define __HAL_DMA2D_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= DMA2D_CR_START) + + +/* Interrupt & Flag management */ +/** + * @brief Get the DMA2D pending flags. + * @param __HANDLE__ DMA2D handle + * @param __FLAG__ flag to check. + * This parameter can be any combination of the following values: + * @arg DMA2D_FLAG_CE: Configuration error flag + * @arg DMA2D_FLAG_CTC: CLUT transfer complete flag + * @arg DMA2D_FLAG_CAE: CLUT access error flag + * @arg DMA2D_FLAG_TW: Transfer Watermark flag + * @arg DMA2D_FLAG_TC: Transfer complete flag + * @arg DMA2D_FLAG_TE: Transfer error flag + * @retval The state of FLAG. + */ +#define __HAL_DMA2D_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR & (__FLAG__)) + +/** + * @brief Clear the DMA2D pending flags. + * @param __HANDLE__ DMA2D handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA2D_FLAG_CE: Configuration error flag + * @arg DMA2D_FLAG_CTC: CLUT transfer complete flag + * @arg DMA2D_FLAG_CAE: CLUT access error flag + * @arg DMA2D_FLAG_TW: Transfer Watermark flag + * @arg DMA2D_FLAG_TC: Transfer complete flag + * @arg DMA2D_FLAG_TE: Transfer error flag + * @retval None + */ +#define __HAL_DMA2D_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->IFCR = (__FLAG__)) + +/** + * @brief Enable the specified DMA2D interrupts. + * @param __HANDLE__ DMA2D handle + * @param __INTERRUPT__ specifies the DMA2D interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DMA2D_IT_CE: Configuration error interrupt mask + * @arg DMA2D_IT_CTC: CLUT transfer complete interrupt mask + * @arg DMA2D_IT_CAE: CLUT access error interrupt mask + * @arg DMA2D_IT_TW: Transfer Watermark interrupt mask + * @arg DMA2D_IT_TC: Transfer complete interrupt mask + * @arg DMA2D_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA2D_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the specified DMA2D interrupts. + * @param __HANDLE__ DMA2D handle + * @param __INTERRUPT__ specifies the DMA2D interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg DMA2D_IT_CE: Configuration error interrupt mask + * @arg DMA2D_IT_CTC: CLUT transfer complete interrupt mask + * @arg DMA2D_IT_CAE: CLUT access error interrupt mask + * @arg DMA2D_IT_TW: Transfer Watermark interrupt mask + * @arg DMA2D_IT_TC: Transfer complete interrupt mask + * @arg DMA2D_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA2D_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified DMA2D interrupt source is enabled or not. + * @param __HANDLE__ DMA2D handle + * @param __INTERRUPT__ specifies the DMA2D interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA2D_IT_CE: Configuration error interrupt mask + * @arg DMA2D_IT_CTC: CLUT transfer complete interrupt mask + * @arg DMA2D_IT_CAE: CLUT access error interrupt mask + * @arg DMA2D_IT_TW: Transfer Watermark interrupt mask + * @arg DMA2D_IT_TC: Transfer complete interrupt mask + * @arg DMA2D_IT_TE: Transfer error interrupt mask + * @retval The state of INTERRUPT source. + */ +#define __HAL_DMA2D_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR & (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DMA2D_Exported_Functions DMA2D Exported Functions + * @{ + */ + +/** @addtogroup DMA2D_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions *******************************/ +HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_DeInit(DMA2D_HandleTypeDef *hdma2d); +void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d); +void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d); +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_DMA2D_RegisterCallback(DMA2D_HandleTypeDef *hdma2d, HAL_DMA2D_CallbackIDTypeDef CallbackID, + pDMA2D_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_DMA2D_UnRegisterCallback(DMA2D_HandleTypeDef *hdma2d, HAL_DMA2D_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ + +/** + * @} + */ + + +/** @addtogroup DMA2D_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_DMA2D_Start(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, + uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_BlendingStart(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, + uint32_t DstAddress, uint32_t Width, uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, + uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, + uint32_t DstAddress, uint32_t Width, uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_Suspend(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_Resume(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_Abort(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_EnableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad(DMA2D_HandleTypeDef *hdma2d, const DMA2D_CLUTCfgTypeDef *CLUTCfg, + uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad_IT(DMA2D_HandleTypeDef *hdma2d, const DMA2D_CLUTCfgTypeDef *CLUTCfg, + uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTLoad(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTLoad_IT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Abort(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Suspend(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Resume(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout); +void HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef *hdma2d); +void HAL_DMA2D_LineEventCallback(DMA2D_HandleTypeDef *hdma2d); +void HAL_DMA2D_CLUTLoadingCpltCallback(DMA2D_HandleTypeDef *hdma2d); + +/** + * @} + */ + +/** @addtogroup DMA2D_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ + +/* Peripheral Control functions *************************************************/ +HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef *hdma2d, uint32_t Line); +HAL_StatusTypeDef HAL_DMA2D_EnableDeadTime(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_DisableDeadTime(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_ConfigDeadTime(DMA2D_HandleTypeDef *hdma2d, uint8_t DeadTime); + +/** + * @} + */ + +/** @addtogroup DMA2D_Exported_Functions_Group4 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State functions ***************************************************/ +HAL_DMA2D_StateTypeDef HAL_DMA2D_GetState(const DMA2D_HandleTypeDef *hdma2d); +uint32_t HAL_DMA2D_GetError(const DMA2D_HandleTypeDef *hdma2d); + +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @addtogroup DMA2D_Private_Constants DMA2D Private Constants + * @{ + */ + +/** @defgroup DMA2D_Maximum_Line_WaterMark DMA2D Maximum Line Watermark + * @{ + */ +#define DMA2D_LINE_WATERMARK_MAX DMA2D_LWR_LW /*!< DMA2D maximum line watermark */ +/** + * @} + */ + +/** @defgroup DMA2D_Color_Value DMA2D Color Value + * @{ + */ +#define DMA2D_COLOR_VALUE 0x000000FFU /*!< Color value mask */ +/** + * @} + */ + +/** @defgroup DMA2D_Max_Layer DMA2D Maximum Number of Layers + * @{ + */ +#define DMA2D_MAX_LAYER 2U /*!< DMA2D maximum number of layers */ +/** + * @} + */ + +/** @defgroup DMA2D_Layers DMA2D Layers + * @{ + */ +#define DMA2D_BACKGROUND_LAYER 0x00000000U /*!< DMA2D Background Layer (layer 0) */ +#define DMA2D_FOREGROUND_LAYER 0x00000001U /*!< DMA2D Foreground Layer (layer 1) */ +/** + * @} + */ + +/** @defgroup DMA2D_Offset DMA2D Offset + * @{ + */ +#define DMA2D_OFFSET DMA2D_FGOR_LO /*!< maximum Line Offset */ +/** + * @} + */ + +/** @defgroup DMA2D_Size DMA2D Size + * @{ + */ +#define DMA2D_PIXEL (DMA2D_NLR_PL >> 16U) /*!< DMA2D maximum number of pixels per line */ +#define DMA2D_LINE DMA2D_NLR_NL /*!< DMA2D maximum number of lines */ +/** + * @} + */ + +/** @defgroup DMA2D_CLUT_Size DMA2D CLUT Size + * @{ + */ +#define DMA2D_CLUT_SIZE (DMA2D_FGPFCCR_CS >> 8U) /*!< DMA2D maximum CLUT size */ +/** + * @} + */ + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Macros DMA2D Private Macros + * @{ + */ +#define IS_DMA2D_LAYER(LAYER) (((LAYER) == DMA2D_BACKGROUND_LAYER)\ + || ((LAYER) == DMA2D_FOREGROUND_LAYER)) + +#define IS_DMA2D_MODE(MODE) (((MODE) == DMA2D_M2M) || ((MODE) == DMA2D_M2M_PFC) || \ + ((MODE) == DMA2D_M2M_BLEND) || ((MODE) == DMA2D_R2M) || \ + ((MODE) == DMA2D_M2M_BLEND_FG) || ((MODE) == DMA2D_M2M_BLEND_BG)) + +#define IS_DMA2D_CMODE(MODE_ARGB) (((MODE_ARGB) == DMA2D_OUTPUT_ARGB8888) || \ + ((MODE_ARGB) == DMA2D_OUTPUT_RGB888) || \ + ((MODE_ARGB) == DMA2D_OUTPUT_RGB565) || \ + ((MODE_ARGB) == DMA2D_OUTPUT_ARGB1555) || \ + ((MODE_ARGB) == DMA2D_OUTPUT_ARGB4444)) + +#define IS_DMA2D_COLOR(COLOR) ((COLOR) <= DMA2D_COLOR_VALUE) +#define IS_DMA2D_LINE(LINE) ((LINE) <= DMA2D_LINE) +#define IS_DMA2D_PIXEL(PIXEL) ((PIXEL) <= DMA2D_PIXEL) +#define IS_DMA2D_OFFSET(OOFFSET) ((OOFFSET) <= DMA2D_OFFSET) + +#define IS_DMA2D_INPUT_COLOR_MODE(INPUT_CM) (((INPUT_CM) == DMA2D_INPUT_ARGB8888) || \ + ((INPUT_CM) == DMA2D_INPUT_RGB888) || \ + ((INPUT_CM) == DMA2D_INPUT_RGB565) || \ + ((INPUT_CM) == DMA2D_INPUT_ARGB1555) || \ + ((INPUT_CM) == DMA2D_INPUT_ARGB4444) || \ + ((INPUT_CM) == DMA2D_INPUT_L8) || \ + ((INPUT_CM) == DMA2D_INPUT_AL44) || \ + ((INPUT_CM) == DMA2D_INPUT_AL88) || \ + ((INPUT_CM) == DMA2D_INPUT_L4) || \ + ((INPUT_CM) == DMA2D_INPUT_A8) || \ + ((INPUT_CM) == DMA2D_INPUT_A4) || \ + ((INPUT_CM) == DMA2D_INPUT_YCBCR)) + +#define IS_DMA2D_ALPHA_MODE(AlphaMode) (((AlphaMode) == DMA2D_NO_MODIF_ALPHA) || \ + ((AlphaMode) == DMA2D_REPLACE_ALPHA) || \ + ((AlphaMode) == DMA2D_COMBINE_ALPHA)) + +#define IS_DMA2D_ALPHA_INVERTED(Alpha_Inverted) (((Alpha_Inverted) == DMA2D_REGULAR_ALPHA) || \ + ((Alpha_Inverted) == DMA2D_INVERTED_ALPHA)) + +#define IS_DMA2D_RB_SWAP(RB_Swap) (((RB_Swap) == DMA2D_RB_REGULAR) || \ + ((RB_Swap) == DMA2D_RB_SWAP)) + +#define IS_DMA2D_LOM_MODE(LOM) (((LOM) == DMA2D_LOM_PIXELS) || \ + ((LOM) == DMA2D_LOM_BYTES)) + +#define IS_DMA2D_BYTES_SWAP(BYTES_SWAP) (((BYTES_SWAP) == DMA2D_BYTES_REGULAR) || \ + ((BYTES_SWAP) == DMA2D_BYTES_SWAP)) + +#define IS_DMA2D_CHROMA_SUB_SAMPLING(CSS) (((CSS) == DMA2D_NO_CSS) || \ + ((CSS) == DMA2D_CSS_422) || \ + ((CSS) == DMA2D_CSS_420)) + +#define IS_DMA2D_CLUT_CM(CLUT_CM) (((CLUT_CM) == DMA2D_CCM_ARGB8888) || ((CLUT_CM) == DMA2D_CCM_RGB888)) +#define IS_DMA2D_CLUT_SIZE(CLUT_SIZE) ((CLUT_SIZE) <= DMA2D_CLUT_SIZE) +#define IS_DMA2D_LINEWATERMARK(LineWatermark) ((LineWatermark) <= DMA2D_LINE_WATERMARK_MAX) +#define IS_DMA2D_IT(IT) (((IT) == DMA2D_IT_CTC) || ((IT) == DMA2D_IT_CAE) || \ + ((IT) == DMA2D_IT_TW) || ((IT) == DMA2D_IT_TC) || \ + ((IT) == DMA2D_IT_TE) || ((IT) == DMA2D_IT_CE)) +#define IS_DMA2D_GET_FLAG(FLAG) (((FLAG) == DMA2D_FLAG_CTC) || ((FLAG) == DMA2D_FLAG_CAE) || \ + ((FLAG) == DMA2D_FLAG_TW) || ((FLAG) == DMA2D_FLAG_TC) || \ + ((FLAG) == DMA2D_FLAG_TE) || ((FLAG) == DMA2D_FLAG_CE)) +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (DMA2D) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_DMA2D_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma_ex.h new file mode 100644 index 0000000..95674c9 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_dma_ex.h @@ -0,0 +1,719 @@ +/** + ********************************************************************************************************************** + * @file stm32h7rsxx_hal_dma_ex.h + * @author MCD Application Team + * @brief Header file of DMA HAL extension 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 STM32H7RSxx_HAL_DMA_EX_H +#define STM32H7RSxx_HAL_DMA_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 */ + +} 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 */ +#define DMA_DATA_UNPACK DMA_CTR1_PAM_1 /*!< If source data width > destination data width + => Unpacked at the destination data width */ +/** + * @} + */ + +/** @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 */ +#define DMA_EXCHANGE_DEST_WORD DMA_CTR1_DWX /*!< Destination Word exchange when destination 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 + * @{ + */ +/* HPDMA1 triggers */ +#define HPDMA1_TRIGGER_DCMIPP_EVT_FRAMEEND 0U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_FRAMEEND */ +#define HPDMA1_TRIGGER_DCMIPP_EVT_HSYNC 1U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_HSYNC */ +#define HPDMA1_TRIGGER_DCMIPP_EVT_LINEEND 2U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_LINEEND */ +#define HPDMA1_TRIGGER_DCMIPP_EVT_VSYNC 3U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_VSYNC */ +#define HPDMA1_TRIGGER_DMA2D_CTC_FLAG 4U /*!< HPDMA1 HW Trigger signal is DMA2D_CTC_FLAG */ +#define HPDMA1_TRIGGER_DMA2D_TC_FLAG 5U /*!< HPDMA1 HW Trigger signal is DMA2D_TC_FLAG */ +#define HPDMA1_TRIGGER_DMA2D_TW_FLAG 6U /*!< HPDMA1 HW Trigger signal is DMA2D_TW_FLAG */ +#define HPDMA1_TRIGGER_JPEG_EOC_FLAG 7U /*!< HPDMA1 HW Trigger signal is JPEG_EOC_FLAG */ +#define HPDMA1_TRIGGER_JPEG_IFNF_FLAG 8U /*!< HPDMA1 HW Trigger signal is JPEG_IFNF_FLAG */ +#define HPDMA1_TRIGGER_JPEG_IFT_FLAG 9U /*!< HPDMA1 HW Trigger signal is JPEG_IFT_FLAG */ +#define HPDMA1_TRIGGER_JPEG_OFNE_FLAG 10U /*!< HPDMA1 HW Trigger signal is JPEG_OFNE_FLAG */ +#define HPDMA1_TRIGGER_JPEG_OFT_FLAG 11U /*!< HPDMA1 HW Trigger signal is JPEG_OFT_FLAG */ +#define HPDMA1_TRIGGER_LCD 12U /*!< HPDMA1 HW Trigger signal is LCD */ +#define HPDMA1_TRIGGER_GPU2D1_GP_FLAG0 13U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG0 */ +#define HPDMA1_TRIGGER_GPU2D1_GP_FLAG1 14U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG1 */ +#define HPDMA1_TRIGGER_GPU2D1_GP_FLAG2 15U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG2 */ +#define HPDMA1_TRIGGER_GPU2D1_GP_FLAG3 16U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG3 */ +#define HPDMA1_TRIGGER_GFXTIM_0_EVT_4 17U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_4 */ +#define HPDMA1_TRIGGER_GFXTIM_0_EVT_3 18U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_3 */ +#define HPDMA1_TRIGGER_GFXTIM_0_EVT_2 19U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_2 */ +#define HPDMA1_TRIGGER_GFXTIM_0_EVT_1 20U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_1 */ +#define HPDMA1_TRIGGER_GPDMA1_CH0_TCF 21U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH0_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH1_TCF 22U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH2_TCF 23U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH2_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH3_TCF 24U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH3_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH4_TCF 25U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH4_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH5_TCF 26U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH5_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH6_TCF 27U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH6_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH7_TCF 28U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH7_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH8_TCF 29U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH8_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH9_TCF 30U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH9_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH10_TCF 31U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH10_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH11_TCF 32U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH11_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH12_TCF 33U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH12_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH13_TCF 34U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH13_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH14_TCF 35U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH14_TCF */ +#define HPDMA1_TRIGGER_GPDMA1_CH15_TCF 36U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH15_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH0_TCF 37U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH0_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH1_TCF 38U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH1_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH2_TCF 39U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH2_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH3_TCF 40U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH3_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH4_TCF 41U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH4_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH5_TCF 42U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH5_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH6_TCF 43U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH6_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH7_TCF 44U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH7_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH8_TCF 45U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH8_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH9_TCF 46U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH9_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH10_TCF 47U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH10_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH11_TCF 48U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH11_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH12_TCF 49U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH12_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH13_TCF 50U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH13_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH14_TCF 51U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH14_TCF */ +#define HPDMA1_TRIGGER_HPDMA1_CH15_TCF 52U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH15_TCF */ + +/* GPDMA1 triggers */ +#define GPDMA1_TRIGGER_HPDMA1_CH0_TCF 0U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH0_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH1_TCF 1U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH1_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH2_TCF 2U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH2_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH3_TCF 3U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH3_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH4_TCF 4U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH4_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH5_TCF 5U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH5_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH6_TCF 6U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH6_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH7_TCF 7U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH7_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH8_TCF 8U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH8_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH9_TCF 9U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH9_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH10_TCF 10U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH10_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH11_TCF 11U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH11_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH12_TCF 12U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH12_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH13_TCF 13U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH13_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH14_TCF 14U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH14_TCF */ +#define GPDMA1_TRIGGER_HPDMA1_CH15_TCF 15U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH15_TCF */ +#define GPDMA1_TRIGGER_LPTIM1_CH1 16U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH1 */ +#define GPDMA1_TRIGGER_LPTIM1_CH2 17U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH2 */ +#define GPDMA1_TRIGGER_LPTIM2_CH1 18U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH1 */ +#define GPDMA1_TRIGGER_LPTIM2_CH2 19U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH2 */ +#define GPDMA1_TRIGGER_LPTIM3_CH1 20U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH1 */ +#define GPDMA1_TRIGGER_LPTIM3_CH2 21U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH2 */ +#define GPDMA1_TRIGGER_LPTIM4_OUT 22U /*!< GPDMA1 HW Trigger signal is LPTIM4_OUT */ +#define GPDMA1_TRIGGER_LPTIM5_OUT 23U /*!< GPDMA1 HW Trigger signal is LPTIM5_OUT */ +#define GPDMA1_TRIGGER_EXTIT0_SYNC 24U /*!< GPDMA1 HW Trigger signal is EXTIT0_SYNC */ +#define GPDMA1_TRIGGER_RTC_WKUP 25U /*!< GPDMA1 HW Trigger signal is RTC_WKUP */ +#define GPDMA1_TRIGGER_LPUART1_IT_R_WUP_ASYNC 26U /*!< GPDMA1 HW Trigger signal is R_WUP_ASYNC */ +#define GPDMA1_TRIGGER_LPUART1_IT_T_WUP_ASYNC 27U /*!< GPDMA1 HW Trigger signal is T_WUP_ASYNC */ +#define GPDMA1_TRIGGER_SPI6_IT_OR_SPI6_AIT_SYNC 28U /*!< GPDMA1 HW Trigger signal is SPI6_OR_SPI6_AIT_SYNC */ +#define GPDMA1_TRIGGER_GPDMA1_CH0_TCF 29U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH1_TCF 30U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH2_TCF 31U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH2_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH3_TCF 32U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH3_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH4_TCF 33U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH4_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH5_TCF 34U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH5_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH6_TCF 35U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH6_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH7_TCF 36U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH7_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH8_TCF 37U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH8_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH9_TCF 38U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH9_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH10_TCF 39U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH10_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH11_TCF 40U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH11_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH12_TCF 41U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH12_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH13_TCF 42U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH13_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH14_TCF 43U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH14_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH15_TCF 44U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH15_TCF */ +#define GPDMA1_TRIGGER_TIM1_TRGO 45U /*!< GPDMA1 HW Trigger signal is TIM1_TRGO */ +#define GPDMA1_TRIGGER_TIM1_TRGO2 46U /*!< GPDMA1 HW Trigger signal is TIM1_TRGO2 */ +#define GPDMA1_TRIGGER_TIM2_TRGO 47U /*!< GPDMA1 HW Trigger signal is TIM2_TRGO */ +#define GPDMA1_TRIGGER_TIM3_TRGO 48U /*!< GPDMA1 HW Trigger signal is TIM3_TRGO */ +#define GPDMA1_TRIGGER_TIM4_TRGO 49U /*!< GPDMA1 HW Trigger signal is TIM4_TRGO */ +#define GPDMA1_TRIGGER_TIM5_TRGO 50U /*!< GPDMA1 HW Trigger signal is TIM5_TRGO */ +#define GPDMA1_TRIGGER_TIM6_TRGO 51U /*!< GPDMA1 HW Trigger signal is TIM6_TRGO */ +#define GPDMA1_TRIGGER_TIM7_TRGO 52U /*!< GPDMA1 HW Trigger signal is TIM7_TRGO */ +#define GPDMA1_TRIGGER_TIM9_TRGO 53U /*!< GPDMA1 HW Trigger signal is TIM9_TRGO */ +#define GPDMA1_TRIGGER_TIM12_TRGO 54U /*!< GPDMA1 HW Trigger signal is TIM12_TRGO */ +#define GPDMA1_TRIGGER_TIM15_TRGO 55U /*!< GPDMA1 HW Trigger signal is TIM15_TRGO */ + +#define GPDMA1_MAX_TRIGGER 55U +/** + * @} + */ + +/** @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 */ +#define DMA_HPDMA_LINEAR_NODE (DMA_CHANNEL_TYPE_HPDMA | DMA_CHANNEL_TYPE_LINEAR_ADDR) /*!< Defines the HPDMA linear addressing node type */ +#define DMA_HPDMA_2D_NODE (DMA_CHANNEL_TYPE_HPDMA | DMA_CHANNEL_TYPE_2D_ADDR) /*!< Defines the HPDMA 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 (0x0080UL) /* DMA channel linked-list mode */ + +#define DMA_CHANNEL_TYPE_LINEAR_ADDR (0x0001UL) /* DMA channel linear addressing mode */ +#define DMA_CHANNEL_TYPE_2D_ADDR (0x0002UL) /* DMA channel 2D addressing mode */ +#define DMA_CHANNEL_TYPE_GPDMA (0x0020UL) /* GPDMA channel node */ +#define DMA_CHANNEL_TYPE_HPDMA (0x0040UL) /* HPDMA channel node */ + +#define NODE_TYPE_MASK (0x00FFUL) /* DMA channel node type */ +#define NODE_CLLR_IDX (0x0700UL) /* DMA channel node CLLR index mask */ +#define NODE_CLLR_IDX_POS (0x0008UL) /* DMA channel node CLLR index position */ + +#define NODE_MAXIMUM_SIZE (0x0008UL) /* Amount of registers of the node */ + +#define NODE_STATIC_FORMAT (0x0000UL) /* DMA channel node static format */ +#define NODE_DYNAMIC_FORMAT (0x0001UL) /* DMA channel node dynamic format */ + +#define UPDATE_CLLR_POSITION (0x0000UL) /* DMA channel update CLLR position */ +#define UPDATE_CLLR_VALUE (0x0001UL) /* DMA channel update CLLR value */ + +#define LASTNODE_ISNOT_CIRCULAR (0x0000UL) /* Last node is not first circular node */ +#define LASTNODE_IS_CIRCULAR (0x0001UL) /* Last node is first circular node */ + +#define QUEUE_TYPE_STATIC (0x0000UL) /* DMA channel static queue */ +#define QUEUE_TYPE_DYNAMIC (0x0001UL) /* DMA channel dynamic queue */ + +#define NODE_CTR1_DEFAULT_OFFSET (0x0000UL) /* CTR1 default offset */ +#define NODE_CTR2_DEFAULT_OFFSET (0x0001UL) /* CTR2 default offset */ +#define NODE_CBR1_DEFAULT_OFFSET (0x0002UL) /* CBR1 default offset */ +#define NODE_CSAR_DEFAULT_OFFSET (0x0003UL) /* CSAR default offset */ +#define NODE_CDAR_DEFAULT_OFFSET (0x0004UL) /* CDAR default offset */ +#define NODE_CTR3_DEFAULT_OFFSET (0x0005UL) /* CTR3 2D addressing default offset */ +#define NODE_CBR2_DEFAULT_OFFSET (0x0006UL) /* CBR2 2D addressing default offset */ +#define NODE_CLLR_2D_DEFAULT_OFFSET (0x0007UL) /* CLLR 2D addressing default offset */ +#define NODE_CLLR_LINEAR_DEFAULT_OFFSET (0x0005UL) /* 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 | \ + DMA_EXCHANGE_DEST_WORD))) == 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)) + +#define IS_DMA_TRIGGER_SELECTION(TRIGGER) \ + ((TRIGGER) <= GPDMA1_TRIGGER_TIM15_TRGO) + +#define IS_DMA_NODE_TYPE(TYPE) \ + (((TYPE) == DMA_GPDMA_LINEAR_NODE) || \ + ((TYPE) == DMA_GPDMA_2D_NODE) || \ + ((TYPE) == DMA_HPDMA_LINEAR_NODE) || \ + ((TYPE) == DMA_HPDMA_2D_NODE)) +/** + * @} + */ + + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Functions DMAEx Private Functions + * @brief DMAEx Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H7RSxx_HAL_DMA_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_exti.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_exti.h new file mode 100644 index 0000000..3aee9b9 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_exti.h @@ -0,0 +1,347 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_exti.h + * @author MCD Application Team + * @brief Header file of EXTI 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 STM32H7RSxx_HAL_EXTI_H +#define STM32H7RSxx_HAL_EXTI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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, +} EXTI_CallbackIDTypeDef; + + +/** + * @brief EXTI Handle structure definition + */ +typedef struct +{ + uint32_t Line; /*!< Exti line number */ + void (* PendingCallback)(void); /*!< Exti pending 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 | EXTI_EVENT | 0x00u) +#define EXTI_LINE_1 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x01u) +#define EXTI_LINE_2 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x02u) +#define EXTI_LINE_3 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x03u) +#define EXTI_LINE_4 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x04u) +#define EXTI_LINE_5 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x05u) +#define EXTI_LINE_6 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x06u) +#define EXTI_LINE_7 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x07u) +#define EXTI_LINE_8 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x08u) +#define EXTI_LINE_9 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x09u) +#define EXTI_LINE_10 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x0Au) +#define EXTI_LINE_11 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x0Bu) +#define EXTI_LINE_12 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x0Cu) +#define EXTI_LINE_13 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x0Du) +#define EXTI_LINE_14 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x0Eu) +#define EXTI_LINE_15 (EXTI_GPIO | EXTI_REG1 | EXTI_EVENT | 0x0Fu) +#define EXTI_LINE_16 (EXTI_CONFIG | EXTI_REG1 | EXTI_EVENT | 0x10u) +#define EXTI_LINE_17 (EXTI_CONFIG | EXTI_REG1 | EXTI_EVENT | 0x11u) +#define EXTI_LINE_18 (EXTI_CONFIG | EXTI_REG1 | EXTI_EVENT | 0x12u) +#define EXTI_LINE_19 (EXTI_CONFIG | EXTI_REG1 | EXTI_EVENT | 0x13u) +#define EXTI_LINE_20 (EXTI_CONFIG | EXTI_REG1 | EXTI_EVENT | 0x14u) +#define EXTI_LINE_21 (EXTI_CONFIG | EXTI_REG1 | EXTI_EVENT | 0x15u) +#define EXTI_LINE_22 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x16u) +#define EXTI_LINE_23 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x17u) +#define EXTI_LINE_24 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x18u) +#define EXTI_LINE_25 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x19u) +#define EXTI_LINE_26 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x1Au) +#define EXTI_LINE_27 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x1Bu) +#define EXTI_LINE_28 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x1Cu) +#define EXTI_LINE_29 (EXTI_RESERVED | EXTI_REG1 | 0x1Du) +#define EXTI_LINE_30 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x1Eu) +#define EXTI_LINE_31 (EXTI_DIRECT | EXTI_REG1 | EXTI_EVENT | 0x1Fu) +#define EXTI_LINE_32 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x00u) +#define EXTI_LINE_33 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x01u) +#define EXTI_LINE_34 (EXTI_CONFIG | EXTI_REG2 | EXTI_EVENT | 0x02u) +#define EXTI_LINE_35 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x03u) +#define EXTI_LINE_36 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x04u) +#define EXTI_LINE_37 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x05u) +#define EXTI_LINE_38 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x06u) +#define EXTI_LINE_39 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x07u) +#define EXTI_LINE_40 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x08u) +#define EXTI_LINE_41 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x09u) +#define EXTI_LINE_42 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x0Au) +#define EXTI_LINE_43 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x0Bu) +#define EXTI_LINE_44 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x0Cu) +#define EXTI_LINE_45 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x0Du) +#define EXTI_LINE_46 (EXTI_CONFIG | EXTI_REG2 | EXTI_EVENT | 0x0Eu) +#define EXTI_LINE_47 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x0Fu) +#define EXTI_LINE_48 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x10u) +#define EXTI_LINE_49 (EXTI_CONFIG | EXTI_REG2 | EXTI_EVENT | 0x11u) +#define EXTI_LINE_50 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x12u) +#define EXTI_LINE_51 (EXTI_CONFIG | EXTI_REG2 | EXTI_EVENT | 0x13u) +#define EXTI_LINE_52 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x14u) +#define EXTI_LINE_53 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x15u) +#define EXTI_LINE_54 (EXTI_CONFIG | EXTI_REG2 | EXTI_EVENT | 0x16u) +#define EXTI_LINE_55 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x17u) +#define EXTI_LINE_56 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x18u) +#define EXTI_LINE_57 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x19u) +#define EXTI_LINE_58 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x1Au) +#define EXTI_LINE_59 (EXTI_DIRECT | EXTI_REG2 | EXTI_EVENT | 0x1Bu) +#define EXTI_LINE_77 (EXTI_DIRECT | EXTI_REG3 | EXTI_EVENT | 0x0Du) +/** + * @} + */ + +/** @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_GPIOM 0x0000000Cu +#define EXTI_GPION 0x0000000Du +#define EXTI_GPIOO 0x0000000Eu +#define EXTI_GPIOP 0x0000000Fu +/** + * @} + */ + +/** + * @} + */ + +/* 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 (0x01uL << EXTI_PROPERTY_SHIFT) +#define EXTI_CONFIG (0x02uL << EXTI_PROPERTY_SHIFT) +#define EXTI_GPIO ((0x04uL << EXTI_PROPERTY_SHIFT) | EXTI_CONFIG) +#define EXTI_RESERVED (0x08uL << EXTI_PROPERTY_SHIFT) +#define EXTI_PROPERTY_MASK (EXTI_DIRECT | EXTI_CONFIG | EXTI_GPIO) + +/** + * @brief EXTI Event presence definition + */ +#define EXTI_EVENT_PRESENCE_SHIFT 28u +#define EXTI_EVENT (0x01uL << EXTI_EVENT_PRESENCE_SHIFT) +#define EXTI_EVENT_PRESENCE_MASK (EXTI_EVENT) + +/** + * @brief EXTI Register and bit usage + */ +#define EXTI_REG_SHIFT 16u +#define EXTI_REG1 (0x00uL << EXTI_REG_SHIFT) +#define EXTI_REG2 (0x01uL << EXTI_REG_SHIFT) +#define EXTI_REG3 (0x02uL << EXTI_REG_SHIFT) +#define EXTI_REG_MASK (EXTI_REG1 | EXTI_REG2 | EXTI_REG3) +#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 78u + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup EXTI_Private_Macros EXTI Private Macros + * @{ + */ +#define IS_EXTI_LINE(__LINE__) ((((__LINE__) & ~(EXTI_PROPERTY_MASK | EXTI_EVENT_PRESENCE_MASK | EXTI_REG_MASK | EXTI_PIN_MASK)) == 0x00u) && \ + ((((__LINE__) & EXTI_PROPERTY_MASK) == EXTI_DIRECT) || \ + (((__LINE__) & EXTI_PROPERTY_MASK) == EXTI_CONFIG) || \ + (((__LINE__) & EXTI_PROPERTY_MASK) == EXTI_GPIO)) && \ + ((((__LINE__) & (EXTI_REG_MASK | EXTI_PIN_MASK)) < \ + (((EXTI_LINE_NB / 32u) << EXTI_REG_SHIFT) | (EXTI_LINE_NB % 32u))) || \ + (((__LINE__) & (EXTI_REG_MASK | EXTI_PIN_MASK)) == 0x0002000DUL))) + +#define IS_EXTI_MODE(__LINE__) ((((__LINE__) & EXTI_MODE_MASK) != 0x00u) && \ + (((__LINE__) & ~EXTI_MODE_MASK) == 0x00u)) + +#define IS_EXTI_TRIGGER(__LINE__) (((__LINE__) & ~EXTI_TRIGGER_MASK) == 0x00u) + +#define IS_EXTI_PENDING_EDGE(__LINE__) ((__LINE__) == EXTI_TRIGGER_RISING_FALLING) + +#define IS_EXTI_CONFIG_LINE(__LINE__) (((__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_GPIOM) || \ + ((__PORT__) == EXTI_GPION) || \ + ((__PORT__) == EXTI_GPIOO) || \ + ((__PORT__) == EXTI_GPIOP)) + +#define IS_EXTI_GPIO_PIN(__PIN__) ((__PIN__) < 16u) +/** + * @} + */ + + +/* 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,const 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); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_EXTI_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash.h new file mode 100644 index 0000000..f0a8bfe --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash.h @@ -0,0 +1,803 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_flash.h + * @author MCD Application Team + * @brief Header file of FLASH 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 STM32H7RSxx_HAL_FLASH_H +#define STM32H7RSxx_HAL_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Types FLASH Exported Types + * @{ + */ + +/** + * @brief FLASH Erase structure definition + */ +typedef struct +{ + uint32_t TypeErase; /*!< Mass erase or page erase. + This parameter can be a value of @ref FLASH_Type_Erase */ + uint32_t Sector; /*!< Initial Flash sector to erase when sector erase is enabled + This parameter must be a value between 0 and (max number of sector - 1) + (eg : 15 for 128KB single bank) */ + uint32_t NbSectors; /*!< Number of sectors to be erased. + This parameter must be a value between 1 and + (max number of sectors - value of initial page)*/ +} FLASH_EraseInitTypeDef; + +/** + * @brief FLASH Option Bytes Program structure definition + */ +#define FLASH_KEY_DATA_NB_REG (8U) /*!< 8 Key data registers */ + +typedef struct +{ + uint32_t OptionType; /*!< Option byte to be configured. + This parameter can be a combination of the values of @ref FLASH_OB_TYPE */ + uint32_t WRPState; /*!< Write protection activation or deactivation (used for OPTIONBYTE_WRP). + This parameter can be value of @ref FLASH_OB_WRP_STATE */ + uint32_t WRPSector; /*!< Specifies the sector(s) to be write protected (used for OPTIONBYTE_WRP). + The value of this parameter depend on device used within the same series */ + uint32_t USERType; /*!< 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 USERConfig1; /*!< Value of the user option byte (used for OPTIONBYTE_USER). + This parameter can be a combination of @ref FLASH_OB_USER_BOR_LEV, + @ref FLASH_OB_USER_IWDG_SW, @ref FLASH_OB_USER_nRST_STOP, + @ref FLASH_OB_USER_nRST_STDBY, @ref FLASH_OB_USER_XSPI1_HSLV, + @ref FLASH_OB_USER_XSPI2_HSLV, @ref FLASH_OB_USER_IWDG_STOP, + @ref FLASH_OB_USER_IWDG_STANDBY, @ref FLASH_OB_USER_VDDIO_HSLV */ + uint32_t USERConfig2; /*!< Value of the user option byte (used for OPTIONBYTE_USER). + This parameter can be a combination of @ref FLASH_OB_USER_ITCM_AXI_SHARE, + @ref FLASH_OB_USER_DTCM_AXI_SHARE, @ref FLASH_OB_USER_ECC_ON_SRAM, + @ref FLASH_OB_USER_I2C_NI3C */ + uint32_t HDPStartPage; /*!< Start address that contains the first 256-byte block of HDP area (used for OPTIONBYTE_HDP). + This parameter must be a value between 0 or 0xFFF */ + uint32_t HDPEndPage; /*!< End address that contains the last 256-byte block of HDP area (used for OPTIONBYTE_HDP). + This parameter must be a value between 0 or 0xFFF */ + uint32_t NVState; /*!< Value of the non-volatile state (used for OPTIONBYTE_NV). + This parameter must be a value of @ref FLASH_OB_NVSTATE */ + uint32_t ROTConfig; /*!< Value of the RoT status (only used for read configuration). + This parameter can be a combination of @ref FLASH_OB_ROT_OEM_PROVD, + @ref FLASH_OB_ROT_DBG_AUTH, @ref FLASH_OB_ROT_IROT_SELECT */ + uint32_t EPOCH; /*!< Value of the epoch (only used for read configuration). + This parameter must be a value between 0x0 and 0xFFFFFF */ +} FLASH_OBProgramInitTypeDef; + +/** + * @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 in IT context */ + uint32_t Sector; /* Internal variable to define the current sector which is being erased in + IT context */ + 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_Flags FLASH Flags Definition + * @{ + */ +#define FLASH_FLAG_EOP FLASH_ISR_EOPF /*!< FLASH End of program flag */ +#define FLASH_FLAG_WRPERR FLASH_ISR_WRPERRF /*!< FLASH Write protection error flag */ +#define FLASH_FLAG_PGSERR FLASH_ISR_PGSERRF /*!< FLASH Programming sequence error flag */ +#define FLASH_FLAG_STRBERR FLASH_ISR_STRBERRF /*!< FLASH Strobe error flag */ +#define FLASH_FLAG_OBLERR FLASH_ISR_OBLERRF /*!< FLASH Option byte loading error flag */ +#define FLASH_FLAG_INCERR FLASH_ISR_INCERRF /*!< FLASH Inconsistency error flag */ +#define FLASH_FLAG_RDSERR FLASH_ISR_RDSERRF /*!< FLASH Read security error flag */ +#define FLASH_FLAG_SNECCERR FLASH_ISR_SNECCERRF /*!< FLASH ECC single error flag */ +#define FLASH_FLAG_DBECCERR FLASH_ISR_DBECCERRF /*!< FLASH ECC double error flag */ +#define FLASH_FLAG_CRCEND FLASH_ISR_CRCENDF /*!< FLASH CRC end of calculation flag */ +#define FLASH_FLAG_CRCERR FLASH_ISR_CRCRDERRF /*!< FLASH CRC error flag */ +#define FLASH_FLAG_KVERR FLASH_OPTISR_KVEF /*!< FLASH Key valid error flag */ +#define FLASH_FLAG_KTERR FLASH_OPTISR_KTEF /*!< FLASH Key transfer error flag */ +#define FLASH_FLAG_OPTERR FLASH_OPTISR_OPTERRF /*!< FLASH Options byte change error flag */ + +#define FLASH_FLAG_ISR_ERRORS (FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_STRBERR | \ + FLASH_FLAG_OBLERR | FLASH_FLAG_INCERR | FLASH_FLAG_RDSERR | \ + FLASH_FLAG_CRCERR) +#define FLASH_FLAG_ECC_ERRORS (FLASH_FLAG_SNECCERR | FLASH_FLAG_DBECCERR) +#define FLASH_FLAG_OPTISR_ERRORS (FLASH_FLAG_KVERR | FLASH_FLAG_KTERR | FLASH_FLAG_OPTERR) +#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_ISR_ERRORS | FLASH_FLAG_ECC_ERRORS | FLASH_FLAG_OPTISR_ERRORS) + +#define FLASH_FLAG_ISR_FLAGS (FLASH_FLAG_ISR_ERRORS | FLASH_FLAG_ECC_ERRORS | FLASH_FLAG_EOP) +/** + * @} + */ + +/** @defgroup FLASH_Interrupt_definition FLASH Interrupts Definition + * @brief FLASH Interrupt definition + * @{ + */ +#define FLASH_IT_EOP FLASH_IER_EOPIE /*!< End of program interrupt source */ +#define FLASH_IT_WRPERR FLASH_IER_WRPERRIE /*!< FLASH Write protection error interrupt source */ +#define FLASH_IT_PGSERR FLASH_IER_PGSERRIE /*!< FLASH Programming sequence error interrupt source */ +#define FLASH_IT_STRBERR FLASH_IER_STRBERRIE /*!< FLASH Strobe error interrupt source */ +#define FLASH_IT_OBLERR FLASH_IER_OBLERRIE /*!< FLASH Option byte loading error interrupt source */ +#define FLASH_IT_INCERR FLASH_IER_INCERRIE /*!< FLASH Inconsistency error interrupt source */ +#define FLASH_IT_RDSERR FLASH_IER_RDSERRIE /*!< FLASH Read security error interrupt source */ +#define FLASH_IT_SNECCERR FLASH_IER_SNECCERRIE /*!< FLASH ECC single error interrupt source */ +#define FLASH_IT_DBECCERR FLASH_IER_DBECCERRIE /*!< FLASH ECC double error interrupt source */ +#define FLASH_IT_CRCEND FLASH_IER_CRCENDIE /*!< FLASH CRC end of calculation interrupt source */ +#define FLASH_IT_CRCERR FLASH_IER_CRCRDERRIE /*!< FLASH CRC error interrupt source */ +#define FLASH_IT_KVERR FLASH_OPTCR_KVEIE /*!< FLASH Key valid error interrupt source */ +#define FLASH_IT_KTERR FLASH_OPTCR_KTEIE /*!< FLASH Key transfer error interrupt source */ +#define FLASH_IT_OPTERR FLASH_OPTCR_OPTERRIE /*!< FLASH Options byte change error interrupt source */ + +#define FLASH_IT_IER (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | FLASH_IT_STRBERR | \ + FLASH_IT_OBLERR | FLASH_IT_INCERR | FLASH_IT_RDSERR | FLASH_IT_SNECCERR | \ + FLASH_IT_DBECCERR | FLASH_IT_CRCEND | FLASH_IT_CRCERR) +#define FLASH_IT_OPTCR (FLASH_IT_KVERR | FLASH_IT_KTERR | FLASH_IT_OPTERR) +/** + * @} + */ + +/** @defgroup FLASH_Error FLASH Error + * @{ + */ +#define HAL_FLASH_ERROR_NONE 0x00000000U +#define HAL_FLASH_ERROR_WRP FLASH_FLAG_WRPERR +#define HAL_FLASH_ERROR_PGS FLASH_FLAG_PGSERR +#define HAL_FLASH_ERROR_STRB FLASH_FLAG_STRBERR +#define HAL_FLASH_ERROR_OBL FLASH_FLAG_OBLERR +#define HAL_FLASH_ERROR_INC FLASH_FLAG_INCERR +#define HAL_FLASH_ERROR_RDS FLASH_FLAG_RDSERR +#define HAL_FLASH_ERROR_SNECC FLASH_FLAG_SNECCERR +#define HAL_FLASH_ERROR_DBECC FLASH_FLAG_DBECCERR +#define HAL_FLASH_ERROR_CRC FLASH_FLAG_CRCERR +#define HAL_FLASH_ERROR_KV FLASH_FLAG_KVERR +#define HAL_FLASH_ERROR_KT FLASH_FLAG_KTERR +#define HAL_FLASH_ERROR_OPT FLASH_FLAG_OPTERR +/** + * @} + */ + +/** @defgroup FLASH_Type_Erase FLASH Erase Type + * @{ + */ +#define FLASH_TYPEERASE_SECTORS FLASH_CR_SER /*!< Sectors erase activation */ +#define FLASH_TYPEERASE_MASSERASE FLASH_CR_BER /*!< Flash mass erase activation */ +/** + * @} + */ + +/** @defgroup FLASH_Type_Program FLASH Program Type + * @{ + */ +#define FLASH_TYPEPROGRAM_BYTE (FLASH_CR_PG | FLASH_CR_FW) /*!< Program a byte (8-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_HALFWORD (FLASH_HALFWORD_MASK | FLASH_CR_PG | FLASH_CR_FW) /*!< Program a half-word (16-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_WORD (FLASH_WORD_MASK | FLASH_CR_PG | FLASH_CR_FW) /*!< Program a word (32-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_DOUBLEWORD (FLASH_DOUBLEWORD_MASK | FLASH_CR_PG | FLASH_CR_FW) /*!< Program a double-word (64-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_QUADWORD (FLASH_CR_PG) /*!< Program a quad-word (128-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_OTP_HALFWORD (FLASH_HALFWORD_MASK | FLASH_CR_PG_OTP | FLASH_CR_FW) /*!< Program a half-word (16-bit) at a OTP address */ +#define FLASH_TYPEPROGRAM_OTP_WORD (FLASH_WORD_MASK | FLASH_CR_PG_OTP | FLASH_CR_FW) /*!< Program a word (32-bit) at a OTP address */ +/** + * @} + */ + +/** @defgroup FLASH_OB_TYPE FLASH Option Bytes Type + * @{ + */ +#define OPTIONBYTE_WRP 0x00000001U /*!< WRP option byte configuration */ +#define OPTIONBYTE_USER 0x00000002U /*!< User option byte configuration */ +#define OPTIONBYTE_HDP 0x00000004U /*!< HDP option byte configuration */ +#define OPTIONBYTE_NV 0x00000008U /*!< Non-Volatile State option byte configuration */ +/** + * @} + */ + +/** @defgroup FLASH_OB_WRP_STATE FLASH Option Bytes WRP State + * @{ + */ +#define OB_WRPSTATE_DISABLE 0x00000000U /*!< Disable the write protection of the desired sectors */ +#define OB_WRPSTATE_ENABLE 0x00000001U /*!< Enable the write protection of the desired sectors */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_TYPE FLASH Option Bytes User Type + * @{ + */ +#define OB_USER_BOR_LEV 0x00000001U /*!< Brownout level */ +#define OB_USER_IWDG_SW 0x00000002U /*!< IWDG control mode */ +#define OB_USER_NRST_STOP 0x00000004U /*!< Stop entry reset */ +#define OB_USER_NRST_STDBY 0x00000008U /*!< Standby entry reset */ +#define OB_USER_XSPI1_HSLV 0x00000010U /*!< XSPI1 High-speed at low voltage */ +#define OB_USER_XSPI2_HSLV 0x00000020U /*!< XSPI2 High-speed at low voltage */ +#define OB_USER_IWDG_STOP 0x00000040U /*!< IWDG Stop mode freeze */ +#define OB_USER_IWDG_STDBY 0x00000080U /*!< IWDG Standby mode freeze */ +#define OB_USER_VDDIO_HSLV 0x00000100U /*!< I/O High-speed at low voltage */ +#define OB_USER_ITCM_AXI_SHARE 0x00000200U /*!< ITCM AXI share */ +#define OB_USER_DTCM_AXI_SHARE 0x00000400U /*!< DTCM AXI share */ +#define OB_USER_SRAM_ECC 0x00000800U /*!< ECC on SRAM */ +#define OB_USER_I2C_NI3C 0x00001000U /*!< I2C Not I3C */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_BOR_LEV FLASH Option Bytes User BOR Level + * @{ + */ +#define OB_BOR_LEVEL_0 0x00000000U /*!< BOR OFF, POR/PDR reset threshold level is applied */ +#define OB_BOR_LEVEL_1 FLASH_OBW1SRP_BOR_LEVEL_0 /*!< BOR Level 1, the threshold level is low (around 2.1 V) */ +#define OB_BOR_LEVEL_2 FLASH_OBW1SRP_BOR_LEVEL_1 /*!< BOR Level 2, the threshold level is medium (around 2.4 V) */ +#define OB_BOR_LEVEL_3 FLASH_OBW1SRP_BOR_LEVEL /*!< BOR Level 3, the threshold level is high (around 2.7 V) */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IWDG_SW FLASH Option Bytes User IWDG control mode + * @{ + */ +#define OB_IWDG_HW 0x00000000U /*!< IWDG watchdog is controlled by hardware */ +#define OB_IWDG_SW FLASH_OBW1SRP_IWDG_HW /*!< IWDG watchdog is controlled by software */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_nRST_STOP FLASH Option Bytes User stop entry reset + * @{ + */ +#define OB_STOP_RST 0x00000000U /*!< Reset generated when entering stop mode */ +#define OB_STOP_NORST FLASH_OBW1SRP_NRST_STOP /*!< No reset generated when entering stop mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_nRST_STDBY FLASH Option Bytes User standby entry reset + * @{ + */ +#define OB_STANDBY_RST 0x00000000U /*!< Reset generated when entering standby mode */ +#define OB_STANDBY_NORST FLASH_OBW1SRP_NRST_STBY /*!< No reset generated when entering standby mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_XSPI1_HSLV FLASH Option Bytes User XSPI 1 High-Speed at Low-Voltage + * @{ + */ +#define OB_XSPI1_HSLV_DISABLE 0x00000000U /*!< I/O speed optimization at low-voltage disabled */ +#define OB_XSPI1_HSLV_ENABLE FLASH_OBW1SRP_XSPI1_HSLV /*!< I/O speed optimization at low-voltage feature allowed */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_XSPI2_HSLV FLASH Option Bytes User XSPI 2 High-Speed at Low-Voltage + * @{ + */ +#define OB_XSPI2_HSLV_DISABLE 0x00000000U /*!< I/O speed optimization at low-voltage disabled */ +#define OB_XSPI2_HSLV_ENABLE FLASH_OBW1SRP_XSPI2_HSLV /*!< I/O speed optimization at low-voltage feature allowed */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IWDG_STOP FLASH Option Bytes User IWDG Stop Mode Freeze + * @{ + */ +#define OB_IWDG_STOP_FREEZE 0x00000000U /*!< Independent watchdog frozen in Stop mode */ +#define OB_IWDG_STOP_RUN FLASH_OBW1SRP_IWDG_FZ_STOP /*!< Independent watchdog running in Stop mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IWDG_STANDBY FLASH Option Bytes User IWDG Standby Mode Freeze + * @{ + */ +#define OB_IWDG_STDBY_FREEZE 0x00000000U /*!< Independent watchdog frozen in Standby mode */ +#define OB_IWDG_STDBY_RUN FLASH_OBW1SRP_IWDG_FZ_STBY /*!< Independent watchdog running in Standby mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_VDDIO_HSLV FLASH Option Bytes User I/O High-Speed at Low-Voltage + * @{ + */ +#define OB_VDDIO_HSLV_DISABLE 0x00000000U /*!< I/O speed optimization at low-voltage disabled */ +#define OB_VDDIO_HSLV_ENABLE FLASH_OBW1SRP_VDDIO_HSLV /*!< I/O speed optimization at low-voltage feature allowed */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_ITCM_AXI_SHARE FLASH Option Bytes User ITCM AXI share + * @{ + */ +#define OB_ITCM_AXI_SHARE_0 0x00000000U +#define OB_ITCM_AXI_SHARE_1 FLASH_OBW2SRP_ITCM_AXI_SHARE_0 +#define OB_ITCM_AXI_SHARE_2 FLASH_OBW2SRP_ITCM_AXI_SHARE_1 +#define OB_ITCM_AXI_SHARE_3 (FLASH_OBW2SRP_ITCM_AXI_SHARE_0 | FLASH_OBW2SRP_ITCM_AXI_SHARE_1) +#define OB_ITCM_AXI_SHARE_4 FLASH_OBW2SRP_ITCM_AXI_SHARE_2 +#define OB_ITCM_AXI_SHARE_5 (FLASH_OBW2SRP_ITCM_AXI_SHARE_2 | FLASH_OBW2SRP_ITCM_AXI_SHARE_0) +#define OB_ITCM_AXI_SHARE_6 (FLASH_OBW2SRP_ITCM_AXI_SHARE_2 | FLASH_OBW2SRP_ITCM_AXI_SHARE_1) +#define OB_ITCM_AXI_SHARE_7 FLASH_OBW2SRP_ITCM_AXI_SHARE +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_DTCM_AXI_SHARE FLASH Option Bytes User DTCM AXI share + * @{ + */ +#define OB_DTCM_AXI_SHARE_0 0x00000000U +#define OB_DTCM_AXI_SHARE_1 FLASH_OBW2SRP_DTCM_AXI_SHARE_0 +#define OB_DTCM_AXI_SHARE_2 FLASH_OBW2SRP_DTCM_AXI_SHARE_1 +#define OB_DTCM_AXI_SHARE_3 (FLASH_OBW2SRP_DTCM_AXI_SHARE_0 | FLASH_OBW2SRP_DTCM_AXI_SHARE_1) +#define OB_DTCM_AXI_SHARE_4 FLASH_OBW2SRP_DTCM_AXI_SHARE_2 +#define OB_DTCM_AXI_SHARE_5 (FLASH_OBW2SRP_DTCM_AXI_SHARE_2 | FLASH_OBW2SRP_DTCM_AXI_SHARE_0) +#define OB_DTCM_AXI_SHARE_6 (FLASH_OBW2SRP_DTCM_AXI_SHARE_2 | FLASH_OBW2SRP_DTCM_AXI_SHARE_1) +#define OB_DTCM_AXI_SHARE_7 FLASH_OBW2SRP_DTCM_AXI_SHARE +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_ECC_ON_SRAM FLASH Option Bytes User ECC on sRAM + * @{ + */ +#define OB_AXISRAM_ECC_DISABLE 0x00000000U /*!< AXISRAM ECC check disable */ +#define OB_AXISRAM_ECC_ENABLE FLASH_OBW2SRP_ECC_ON_SRAM /*!< AXISRAM ECC check enable */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_I2C_NI3C FLASH Option Bytes User I2C Not I3C + * @{ + */ +#define OB_I2C_NI3C_I2C FLASH_OBW2SRP_I2C_NI3C +#define OB_I2C_NI3C_I3C 0x00000000U +/** + * @} + */ + +/** @defgroup FLASH_OB_NVSTATE FLASH Option Bytes Non-volatile state + * @{ + */ +#define OB_NVSTATE_OPEN (uint8_t)0xB4 +#define OB_NVSTATE_CLOSE (uint8_t)0x51 +/** + * @} + */ + +/** @defgroup FLASH_OB_ROT_OEM_PROVD FLASH Option Bytes Root-Of-Trust OEM Provisioned state + * @{ + */ +#define OB_OEM_PROVD_ENABLE (0xB4UL << FLASH_ROTSR_OEM_PROVD_Pos) /*!< Device is in OEM provisioned state */ +#define OB_OEM_PROVD_DEFAULT (0x6AUL << FLASH_ROTSR_OEM_PROVD_Pos) /*!< Device is not in OEM provisioned state (default value)*/ +/** + * @} + */ + +/** @defgroup FLASH_OB_ROT_DBG_AUTH FLASH Option Bytes Root-Of-Trust Debug authentication method + * @{ + */ +#define OB_DBG_AUTH_LOCKED (0xB4UL << FLASH_ROTSR_DBG_AUTH_Pos) /*!< Locked device (no debug allowed) */ +#define OB_DBG_AUTH_ECDSA_SIGN (0x51UL << FLASH_ROTSR_DBG_AUTH_Pos) /*!< Authentication method using ECDSA signature (NISTP256) */ +#define OB_DBG_AUTH_PASSWORD (0x8AUL << FLASH_ROTSR_DBG_AUTH_Pos) /*!< Authentication method using password */ +#define OB_DBG_AUTH_DEFAULT (0xFFUL << FLASH_ROTSR_DBG_AUTH_Pos) /*!< No authentication method selected (default value) */ +/** + * @} + */ + +/** @defgroup FLASH_OB_ROT_IROT_SELECT FLASH Option Bytes iRoT selection + * @{ + */ +#define OB_IROT_SELECTION_ST (0xB4UL << FLASH_ROTSR_IROT_SELECT_Pos) /*!< ST iRoT is selected at boot */ +#define OB_IROT_SELECTION_OEM (0x6AUL << FLASH_ROTSR_IROT_SELECT_Pos) /*!< OEM iRoT is selected at boot */ +/** + * @} + */ + +/** @defgroup FLASH_Latency FLASH Latency + * @{ + */ +#define FLASH_LATENCY_0 0U /*!< FLASH Zero wait state */ +#define FLASH_LATENCY_1 FLASH_ACR_LATENCY_0 /*!< FLASH One wait state */ +#define FLASH_LATENCY_2 (FLASH_ACR_LATENCY_1 | FLASH_ACR_WRHIGHFREQ_0) /*!< FLASH Two wait states */ +#define FLASH_LATENCY_3 (FLASH_ACR_LATENCY_1 | FLASH_ACR_LATENCY_0 | FLASH_ACR_WRHIGHFREQ_0) /*!< FLASH Three wait states */ +#define FLASH_LATENCY_4 (FLASH_ACR_LATENCY_2 | FLASH_ACR_WRHIGHFREQ_1) /*!< FLASH Four wait states */ +#define FLASH_LATENCY_5 (FLASH_ACR_LATENCY_2 | FLASH_ACR_LATENCY_0 | FLASH_ACR_WRHIGHFREQ_1) /*!< FLASH Five wait states */ +#define FLASH_LATENCY_6 (FLASH_ACR_LATENCY_2 | FLASH_ACR_LATENCY_1 | FLASH_ACR_WRHIGHFREQ) /*!< FLASH Six wait state */ +#define FLASH_LATENCY_7 (FLASH_ACR_LATENCY_2 | FLASH_ACR_LATENCY_1 | FLASH_ACR_LATENCY_0 | FLASH_ACR_WRHIGHFREQ) /*!< FLASH Seven wait states */ +/** + * @} + */ + +/** @defgroup FLASH_Keys FLASH Keys + * @{ + */ +#define FLASH_KEY1 0x45670123U /*!< Flash key1 */ +#define FLASH_KEY2 0xCDEF89ABU /*!< Flash key2: used with FLASH_KEY1 + to unlock the FLASH registers access */ + +#define FLASH_OPT_KEY1 0x08192A3BU /*!< Flash option byte key1 */ +#define FLASH_OPT_KEY2 0x4C5D6E7FU /*!< Flash option byte key2: used with FLASH_OPT_KEY1 + to allow option bytes operations */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Macros FLASH Exported Macros + * @brief macros to control FLASH features + * @{ + */ + +/** + * @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 + * @retval None + */ +#define __HAL_FLASH_SET_LATENCY(__LATENCY__) MODIFY_REG(FLASH->ACR, (FLASH_ACR_LATENCY |\ + FLASH_ACR_WRHIGHFREQ), (__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 + */ +#define __HAL_FLASH_GET_LATENCY() READ_BIT(FLASH->ACR, (FLASH_ACR_LATENCY | FLASH_ACR_WRHIGHFREQ)) + +/** + * @} + */ + +/** @defgroup FLASH_Interrupt FLASH Interrupts Macros + * @brief macros to handle FLASH interrupts + * @{ + */ + +/** + * @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 program interrupt + * @arg FLASH_IT_WRPERR: Write protection error interrupt + * @arg FLASH_IT_PGSERR: Programming sequence error interrupt + * @arg FLASH_IT_STRBERR: Strobe error interrupt + * @arg FLASH_IT_OBLERR: Option byte loading error interrupt + * @arg FLASH_IT_INCERR: Inconsistency error interrupt + * @arg FLASH_IT_RDSERR: Read security error interrupt + * @arg FLASH_IT_SNECCERR: ECC single error interrupt + * @arg FLASH_IT_DBECCERR: ECC double error interrupt + * @arg FLASH_IT_CRCEND: CRC end of calculation interrupt + * @arg FLASH_IT_CRCERR: CRC error interrupt + * @arg FLASH_IT_KVERR: Key valid error interrupt + * @arg FLASH_IT_KTERR: Key transfer error interrupt + * @arg FLASH_IT_OPTERR: Options byte change error interrupt + * @retval none + */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_IER) != 0U)\ + { SET_BIT(FLASH->IER, ((__INTERRUPT__) & FLASH_IT_IER)); }\ + if(((__INTERRUPT__) & FLASH_IT_OPTCR) != 0U)\ + { SET_BIT(FLASH->OPTCR, ((__INTERRUPT__) & FLASH_IT_OPTCR)); }\ + } while(0) + +/** + * @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 program interrupt + * @arg FLASH_IT_WRPERR: Write protection error interrupt + * @arg FLASH_IT_PGSERR: Programming sequence error interrupt + * @arg FLASH_IT_STRBERR: Strobe error interrupt + * @arg FLASH_IT_OBLERR: Option byte loading error interrupt + * @arg FLASH_IT_INCERR: Inconsistency error interrupt + * @arg FLASH_IT_RDSERR: Read security error interrupt + * @arg FLASH_IT_SNECCERR: ECC single error interrupt + * @arg FLASH_IT_DBECCERR: ECC double error interrupt + * @arg FLASH_IT_CRCEND: CRC end of calculation interrupt + * @arg FLASH_IT_CRCERR: CRC error interrupt + * @arg FLASH_IT_KVERR: Key valid error interrupt + * @arg FLASH_IT_KTERR: Key transfer error interrupt + * @arg FLASH_IT_OPTERR: Options byte change error interrupt + * @retval none + */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_IER) != 0U)\ + { CLEAR_BIT(FLASH->IER, ((__INTERRUPT__) & FLASH_IT_IER)); }\ + if(((__INTERRUPT__) & FLASH_IT_OPTCR) != 0U)\ + { CLEAR_BIT(FLASH->OPTCR, ((__INTERRUPT__) & FLASH_IT_OPTCR)); }\ + } while(0) + +/** + * @brief Check 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_EOP: FLASH End of program flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protection error flag + * @arg FLASH_FLAG_PGSERR: FLASH Programming sequence error flag + * @arg FLASH_FLAG_STRBERR: FLASH Strobe error flag + * @arg FLASH_FLAG_OBLERR: FLASH Option byte loading error flag + * @arg FLASH_FLAG_INCERR: FLASH Inconsistency error flag + * @arg FLASH_FLAG_RDSERR: FLASH Read security error flag + * @arg FLASH_FLAG_SNECCERR: FLASH ECC single error flag + * @arg FLASH_FLAG_DBECCERR: FLASH ECC double error flag + * @arg FLASH_FLAG_CRCEND: FLASH CRC end of calculation flag + * @arg FLASH_FLAG_CRCERR: FLASH CRC error flag + * @arg FLASH_FLAG_KVERR: FLASH Key valid error flag + * @arg FLASH_FLAG_KTERR: FLASH Key transfer error flag + * @arg FLASH_FLAG_OPTERR: FLASH Options byte change error flag + * @retval The new state of FLASH_FLAG (SET or RESET). + */ +#define __HAL_FLASH_GET_FLAG(__FLAG__) ((((__FLAG__) & FLASH_FLAG_OPTISR_ERRORS) != 0U) ? \ + (READ_BIT(FLASH->OPTISR, (__FLAG__)) == (__FLAG__)) : \ + (READ_BIT(FLASH->ISR, (__FLAG__)) == (__FLAG__))) + +/** + * @brief Clear the FLASH's pending flags. + * @param __FLAG__ specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg FLASH_FLAG_EOP: FLASH End of program flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protection error flag + * @arg FLASH_FLAG_PGSERR: FLASH Programming sequence error flag + * @arg FLASH_FLAG_STRBERR: FLASH Strobe error flag + * @arg FLASH_FLAG_OBLERR: FLASH Option byte loading error flag + * @arg FLASH_FLAG_INCERR: FLASH Inconsistency error flag + * @arg FLASH_FLAG_RDSERR: FLASH Read security error flag + * @arg FLASH_FLAG_SNECCERR: FLASH ECC single error flag + * @arg FLASH_FLAG_DBECCERR: FLASH ECC double error flag + * @arg FLASH_FLAG_CRCEND: FLASH CRC end of calculation flag + * @arg FLASH_FLAG_CRCERR: FLASH CRC error flag + * @arg FLASH_FLAG_KVERR: FLASH Key valid error flag + * @arg FLASH_FLAG_KTERR: FLASH Key transfer error flag + * @arg FLASH_FLAG_OPTERR: FLASH Options byte change error flag + * @retval None + */ +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { if(((__FLAG__) & FLASH_FLAG_OPTISR_ERRORS) != 0U)\ + { WRITE_REG(FLASH->OPTICR, ((__FLAG__) & FLASH_FLAG_OPTISR_ERRORS)); }\ + if(((__FLAG__) & FLASH_FLAG_ISR_FLAGS) != 0U)\ + { WRITE_REG(FLASH->ICR, ((__FLAG__) & FLASH_FLAG_ISR_FLAGS)); }\ + } while(0) +/** + * @} + */ + +/* Include FLASH HAL Extended module */ +#include "stm32h7rsxx_hal_flash_ex.h" + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASH_Exported_Functions + * @{ + */ + +/* Program operation functions ***********************************************/ +/** @addtogroup FLASH_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t DataAddress); +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, 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); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup FLASH_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_FLASH_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_Lock(void); +/* Option bytes control */ +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup FLASH_Exported_Functions_Group3 + * @{ + */ +uint32_t HAL_FLASH_GetError(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup FLASH_Private_Variables FLASH Private Variables + * @{ + */ +extern FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/* Private constants --------------------------------------------------------*/ +/** @defgroup FLASH_Private_Constants FLASH Private Constants + * @{ + */ +#define FLASH_BANK_SIZE FLASH_SIZE + +#define FLASH_SECTOR_NB 8U + +#define FLASH_SECTOR_SIZE 0x2000UL /* 8 KB */ + +#define FLASH_HDP_BLOCK_NB 0x100U + +#define FLASH_TIMEOUT_VALUE 1000U /* 1 s */ + +#define FLASH_BYTE_MASK 0x00000000U +#define FLASH_HALFWORD_MASK 0x40000000U +#define FLASH_WORD_MASK 0x80000000U +#define FLASH_DOUBLEWORD_MASK 0xC0000000U +#define FLASH_WORD_SIZE_MASK FLASH_DOUBLEWORD_MASK +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FLASH_Private_Macros FLASH Private Macros + * @{ + */ +#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_SECTORS) ||\ + ((VALUE) == FLASH_TYPEERASE_MASSERASE)) + +#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_BYTE) ||\ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) ||\ + ((VALUE) == FLASH_TYPEPROGRAM_WORD) ||\ + ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD) ||\ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD) ||\ + ((VALUE) == FLASH_TYPEPROGRAM_OTP_HALFWORD) ||\ + ((VALUE) == FLASH_TYPEPROGRAM_OTP_WORD)) + +#define IS_FLASH_MAIN_MEM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && ((ADDRESS) < (FLASH_BASE+FLASH_SIZE))) + +#define IS_FLASH_OTP_ADDRESS(ADDRESS) (((ADDRESS) >= OTP_AREA_BASE) && ((ADDRESS) < (OTP_AREA_BASE + OTP_SIZE))) + +#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) ((IS_FLASH_MAIN_MEM_ADDRESS(ADDRESS)) || (IS_FLASH_OTP_ADDRESS(ADDRESS))) + +#define IS_FLASH_SECTOR(SECTOR) ((SECTOR) < FLASH_SECTOR_NB) + +#define IS_OPTIONBYTE(VALUE) (((VALUE) <= (OPTIONBYTE_WRP |\ + OPTIONBYTE_USER | OPTIONBYTE_HDP | OPTIONBYTE_NV))) + +#define IS_OB_WRPSTATE(VALUE) (((VALUE) == OB_WRPSTATE_DISABLE) || ((VALUE) == OB_WRPSTATE_ENABLE)) + +#define IS_OB_USER_TYPE(TYPE) (((TYPE) <= 0x1FFFU) && ((TYPE) != 0U)) + +#define IS_OB_USER_BOR_LEVEL(LEVEL) (((LEVEL) == OB_BOR_LEVEL_0) || ((LEVEL) == OB_BOR_LEVEL_1) || \ + ((LEVEL) == OB_BOR_LEVEL_2) || ((LEVEL) == OB_BOR_LEVEL_3)) + +#define IS_OB_USER_IWDG(VALUE) (((VALUE) == OB_IWDG_HW) || ((VALUE) == OB_IWDG_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_XSPI1_HSLV(VALUE) (((VALUE) == OB_XSPI1_HSLV_DISABLE) || ((VALUE) == OB_XSPI1_HSLV_ENABLE)) + +#define IS_OB_USER_XSPI2_HSLV(VALUE) (((VALUE) == OB_XSPI2_HSLV_DISABLE) || ((VALUE) == OB_XSPI2_HSLV_ENABLE)) + +#define IS_OB_USER_IWDG_STOP(VALUE) (((VALUE) == OB_IWDG_STOP_FREEZE) || ((VALUE) == OB_IWDG_STOP_RUN)) + +#define IS_OB_USER_IWDG_STDBY(VALUE) (((VALUE) == OB_IWDG_STDBY_FREEZE) || ((VALUE) == OB_IWDG_STDBY_RUN)) + +#define IS_OB_USER_VDDIO_HSLV(VALUE) (((VALUE) == OB_VDDIO_HSLV_DISABLE) || ((VALUE) == OB_VDDIO_HSLV_ENABLE)) + +#define IS_OB_USER_ITCM_AXI_SHARE(VALUE) (((VALUE) == OB_ITCM_AXI_SHARE_0) || ((VALUE) == OB_ITCM_AXI_SHARE_1) || \ + ((VALUE) == OB_ITCM_AXI_SHARE_2) || ((VALUE) == OB_ITCM_AXI_SHARE_3) || \ + ((VALUE) == OB_ITCM_AXI_SHARE_4) || ((VALUE) == OB_ITCM_AXI_SHARE_5) || \ + ((VALUE) == OB_ITCM_AXI_SHARE_6) || ((VALUE) == OB_ITCM_AXI_SHARE_7)) + +#define IS_OB_USER_DTCM_AXI_SHARE(VALUE) (((VALUE) == OB_DTCM_AXI_SHARE_0) || ((VALUE) == OB_DTCM_AXI_SHARE_1) || \ + ((VALUE) == OB_DTCM_AXI_SHARE_2) || ((VALUE) == OB_DTCM_AXI_SHARE_3) || \ + ((VALUE) == OB_DTCM_AXI_SHARE_4) || ((VALUE) == OB_DTCM_AXI_SHARE_5) || \ + ((VALUE) == OB_DTCM_AXI_SHARE_6) || ((VALUE) == OB_DTCM_AXI_SHARE_7)) + +#define IS_OB_USER_AXISRAM_ECC(VALUE) (((VALUE) == OB_AXISRAM_ECC_ENABLE) || ((VALUE) == OB_AXISRAM_ECC_DISABLE)) + +#define IS_OB_USER_I2C_NI3C(VALUE) (((VALUE) == OB_I2C_NI3C_I2C) || ((VALUE) == OB_I2C_NI3C_I3C)) + +#define IS_OB_HDP_PAGE(PAGE) ((PAGE) < FLASH_HDP_BLOCK_NB) + +#define IS_OB_NVSTATE(VALUE) (((VALUE) == OB_NVSTATE_OPEN) || ((VALUE) ==OB_NVSTATE_CLOSE)) + +#define IS_OB_ROT_TYPE(VALUE) ((VALUE) <= 0x7U) + +#define IS_OB_OEM_PROVD(VALUE) ((VALUE) <= 0x000000FFU) + +#define IS_OB_DBG_AUTH(VALUE) ((VALUE) <= 0x0000FF00U) + +#define IS_OB_IROT_SELECT(VALUE) ((VALUE) <= 0xFF000000U) + +#define IS_OB_EPOCH(VALUE) ((VALUE) <= 0xFFFFFFU) + +#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)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup FLASH_Private_Functions + * @{ + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_FLASH_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash_ex.h new file mode 100644 index 0000000..c74a492 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_flash_ex.h @@ -0,0 +1,262 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_flash_ex.h + * @author MCD Application Team + * @brief Header file of FLASH HAL Extended 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 STM32H7RSxx_HAL_FLASH_EX_H +#define STM32H7RSxx_HAL_FLASH_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASHEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @addtogroup FLASH_Exported_Types FLASH Exported Types + * @{ + */ +/** + * @brief FLASH Erase structure definition + */ +typedef struct +{ + uint32_t Index; /*!< Index of the key. + This parameter can be a value between 0 and 31 */ + uint32_t Size; /*!< Size of the key. + This parameter must be a value of @ref FLASH_Key_Size */ + uint32_t HDPLLevel; /*!< HDPL level of the key. + This parameter must be a value of @ref FLASH_KEY_Level */ +} FLASH_KeyConfigTypeDef; + +/** + * @brief FLASH CRC configuration structure definition + */ +typedef struct +{ + uint32_t TypeCRC; /*!< CRC Selection Type. + This parameter can be a value of @ref FLASHEx_CRC_Selection_Type */ + + uint32_t BurstSize; /*!< CRC Burst Size. + This parameter can be a value of @ref FLASHEx_CRC_Burst_Size */ + + uint32_t Sector; /*!< Initial FLASH sector from which starts the CRC computation + This parameter must be a value between 0 and (max number of sector - 1)*/ + + uint32_t NbSectors; /*!< Number of sectors to be computed. + This parameter must be a value between 1 and + (max number of sectors - value of Initial sector)*/ + + uint32_t CRCStartAddr; /*!< CRC Start address. + This parameter must be a value between begin address and end address of a bank */ + + uint32_t CRCEndAddr; /*!< CRC End address. + This parameter must be a value between CRC Start address and end address of a bank */ + +} FLASH_CRCInitTypeDef; + +/** + * @brief FLASH ECC information structure definition + */ +typedef struct +{ + uint32_t Area; /*!< Area from which an ECC was detected. + This parameter can be a value of @ref FLASHEx_ECC_Area */ + uint32_t Address; /*!< Flash address from which en ECC error was detected. + This parameter must be a value between begin address and end address of the Flash */ + uint32_t MasterID; /*!< Master that initiated transfer on which error was detected + This parameter can be a value of @ref FLASHEx_ECC_Master */ +} FLASH_EccInfoTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @addtogroup FLASHEx_Exported_Constants + * @{ + */ +/** @defgroup FLASH_Key_Size FLASH Option Bytes Key Size + * @{ + */ +#define FLASH_KEY_32_BITS 0x0000000U /*!< Key size is 32 bits */ +#define FLASH_KEY_64_BITS FLASH_OBKCR_OBKSIZE_0 /*!< Key size is 64 bits */ +#define FLASH_KEY_128_BITS FLASH_OBKCR_OBKSIZE_1 /*!< Key size is 128 bits */ +#define FLASH_KEY_256_BITS FLASH_OBKCR_OBKSIZE /*!< Key size is 256 bits */ +/** + * @} + */ + +/** @defgroup FLASH_KEY_Level FLASH Option Bytes Key HDPL level + * @{ + */ +#define FLASH_KEY_LEVEL_CURRENT 0x00000000U /*!< Key stored for the HDPL indicated in SBS_HDPLSR */ +#define FLASH_KEY_LEVEL_NEXT FLASH_OBKCR_NEXTKL_0 /*!< Key stored for the HDPL indicated in SBS_HDPLSR + 1 */ +#define FLASH_KEY_LEVEL_PLUS_TWO FLASH_OBKCR_NEXTKL_1 /*!< Key stored for the HDPL indicated in SBS_HDPLSR + 2 */ +/** + * @} + */ + +/** @defgroup FLASHEx_CRC_Selection_Type FLASH CRC Selection Type + * @{ + */ +#define FLASH_CRC_ADDR 0x00000000U /*!< CRC selection type by address */ +#define FLASH_CRC_SECTORS FLASH_CRCCR_CRC_BY_SECT /*!< CRC selection type by sectors */ +#define FLASH_CRC_BANK (FLASH_CRCCR_ALL_SECT | FLASH_CRCCR_CRC_BY_SECT) /*!< CRC selection type all bank */ +/** + * @} + */ + +/** @defgroup FLASHEx_CRC_Burst_Size FLASH CRC Burst Size + * @{ + */ +#define FLASH_CRC_BURST_SIZE_4 0x00000000U /*!< Every burst has a size of 4 Flash words (64 Bytes) */ +#define FLASH_CRC_BURST_SIZE_16 FLASH_CRCCR_CRC_BURST_0 /*!< Every burst has a size of 16 Flash words (256 Bytes) */ +#define FLASH_CRC_BURST_SIZE_64 FLASH_CRCCR_CRC_BURST_1 /*!< Every burst has a size of 64 Flash words (1 kByte) */ +#define FLASH_CRC_BURST_SIZE_256 FLASH_CRCCR_CRC_BURST /*!< Every burst has a size of 256 Flash words (4 kBytes) */ +/** + * @} + */ + +/** @defgroup FLASHEx_ECC_Area FLASH ECC Area + * @{ + */ +#define FLASH_ECC_AREA_USER_BANK1 0x00000000U /*!< FLASH bank 1 area */ +#define FLASH_ECC_AREA_SYSTEM 0x00000001U /*!< System FLASH area */ +#define FLASH_ECC_AREA_OTP 0x00000002U /*!< FLASH OTP area */ +#define FLASH_ECC_AREA_READ_ONLY 0x00000004U /*!< FLASH Read-only area */ +/** + * @} + */ + +/** @defgroup FLASHEx_ECC_Master FLASH ECC Master + * @{ + */ +#define FLASH_ECC_MASTER_CPU1 0x00000000U /*!< ECC error occurs on a CPU1 transaction */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASHEx_Exported_Functions + * @{ + */ + +/* Extended Program operation functions *************************************/ +/** @addtogroup FLASHEx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase(const FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError); +HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(const FLASH_EraseInitTypeDef *pEraseInit); +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(const FLASH_OBProgramInitTypeDef *pOBInit); +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit); +/** + * @} + */ + +/** @addtogroup FLASHEx_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_FLASHEx_OTPLockConfig(uint32_t OTPLBlock); +uint32_t HAL_FLASHEx_GetOTPLock(void); +HAL_StatusTypeDef HAL_FLASHEx_KeyConfig(const FLASH_KeyConfigTypeDef *pKeyConfig, const uint32_t *pKey); +HAL_StatusTypeDef HAL_FLASHEx_GetKey(const FLASH_KeyConfigTypeDef *pKeyConfig, uint32_t *pKey); +HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(const FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result); +/** + * @} + */ + +/** @addtogroup FLASHEx_Exported_Functions_Group3 + * @{ + */ +void HAL_FLASHEx_EnableEccCorrectionInterrupt(void); +void HAL_FLASHEx_DisableEccCorrectionInterrupt(void); +void HAL_FLASHEx_EnableEccDetectionInterrupt(void); +void HAL_FLASHEx_DisableEccDetectionInterrupt(void); +void HAL_FLASHEx_GetEccInfo(FLASH_EccInfoTypeDef *pData); +void HAL_FLASHEx_ECCD_IRQHandler(void); +void HAL_FLASHEx_EccDetectionCallback(void); +void HAL_FLASHEx_EccCorrectionCallback(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private function ----------------------------------------------------------*/ +/** @addtogroup FLASHEx_Private_Functions FLASHEx Private Functions + * @{ + */ +void FLASH_SectorErase(uint32_t Sector); +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Macros FLASH Private Macros + * @{ + */ +#define IS_KEY_INDEX(VALUE) ((VALUE) < 0x20U) + +#define IS_KEY_SIZE(VALUE) (((VALUE) == FLASH_KEY_32_BITS) || ((VALUE) == FLASH_KEY_64_BITS) || \ + ((VALUE) == FLASH_KEY_128_BITS) || ((VALUE) == FLASH_KEY_256_BITS)) + +#define IS_KEY_HDPL_LEVEL(VALUE) (((VALUE) == FLASH_KEY_LEVEL_CURRENT) || \ + ((VALUE) == FLASH_KEY_LEVEL_NEXT) || \ + ((VALUE) == FLASH_KEY_LEVEL_PLUS_TWO)) + +#define IS_OB_OTP_BLOCK(VALUE) ((VALUE) <= 0xFFFFU) + +#define IS_FLASH_TYPE_CRC(VALUE) (((VALUE) == FLASH_CRC_ADDR) || ((VALUE) == FLASH_CRC_SECTORS) ||\ + ((VALUE) == FLASH_CRC_BANK)) + +#define IS_FLASH_BURST_SIZE_CRC(VALUE) (((VALUE) == FLASH_CRC_BURST_SIZE_4) || ((VALUE) == FLASH_CRC_BURST_SIZE_16) ||\ + ((VALUE) == FLASH_CRC_BURST_SIZE_64) || ((VALUE) == FLASH_CRC_BURST_SIZE_256)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_FLASH_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio.h new file mode 100644 index 0000000..baf2ff4 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio.h @@ -0,0 +1,326 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO 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 STM32H7RSxx_HAL_GPIO_H +#define STM32H7RSxx_HAL_GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 any 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: 0x00WX00YZ + * - W : EXTI trigger detection on 3 bits + * - X : EXTI mode (IT or Event) on 2 bits + * - Y : Output type (Push Pull or Open Drain) on 1 bit + * - Z : GPIO mode (Input, Output, Alternate or Analog) on 2 bits + * @{ + */ +#define GPIO_MODE_INPUT MODE_INPUT /*!< Input Floating Mode */ +#define GPIO_MODE_OUTPUT_PP (MODE_OUTPUT | OUTPUT_PP) /*!< Output Push Pull Mode */ +#define GPIO_MODE_OUTPUT_OD (MODE_OUTPUT | OUTPUT_OD) /*!< Output Open Drain Mode */ +#define GPIO_MODE_AF_PP (MODE_AF | OUTPUT_PP) /*!< Alternate Function Push Pull Mode */ +#define GPIO_MODE_AF_OD (MODE_AF | OUTPUT_OD) /*!< Alternate Function Open Drain Mode */ +#define GPIO_MODE_ANALOG MODE_ANALOG /*!< Analog Mode */ +#define GPIO_MODE_IT_RISING (MODE_INPUT | EXTI_IT | TRIGGER_RISING) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_FALLING (MODE_INPUT | EXTI_IT | TRIGGER_FALLING) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define GPIO_MODE_IT_RISING_FALLING (MODE_INPUT | EXTI_IT | TRIGGER_RISING | TRIGGER_FALLING) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING (MODE_INPUT | EXTI_EVT | TRIGGER_RISING) /*!< External Event Mode with Rising edge trigger detection */ +#define GPIO_MODE_EVT_FALLING (MODE_INPUT | EXTI_EVT | TRIGGER_FALLING) /*!< External Event Mode with Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING_FALLING (MODE_INPUT | EXTI_EVT | TRIGGER_RISING | TRIGGER_FALLING) /*!< External Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @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 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @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__) (EXTI->PR1 & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's 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__) (EXTI->PR1 = (__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__) (EXTI->PR1 & (__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__) (EXTI->PR1 = (__EXTI_LINE__)) + +/** + * @brief Generate a Software interrupt on selected EXTI line(s). + * @param __EXTI_LINE__ specifies the EXTI line to be 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__)) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIO_Private_Constants GPIO Private Constants + * @{ + */ +#define GPIO_MODE_Pos 0U +#define GPIO_MODE (0x3UL << GPIO_MODE_Pos) +#define MODE_INPUT (0x0UL << GPIO_MODE_Pos) +#define MODE_OUTPUT (0x1UL << GPIO_MODE_Pos) +#define MODE_AF (0x2UL << GPIO_MODE_Pos) +#define MODE_ANALOG (0x3UL << GPIO_MODE_Pos) +#define OUTPUT_TYPE_Pos 4U +#define OUTPUT_TYPE (0x1UL << OUTPUT_TYPE_Pos) +#define OUTPUT_PP (0x0UL << OUTPUT_TYPE_Pos) +#define OUTPUT_OD (0x1UL << OUTPUT_TYPE_Pos) +#define EXTI_MODE_Pos 16U +#define EXTI_MODE (0x3UL << EXTI_MODE_Pos) +#define EXTI_IT (0x1UL << EXTI_MODE_Pos) +#define EXTI_EVT (0x2UL << EXTI_MODE_Pos) +#define TRIGGER_MODE_Pos 20U +#define TRIGGER_MODE (0x7UL << TRIGGER_MODE_Pos) +#define TRIGGER_RISING (0x1UL << TRIGGER_MODE_Pos) +#define TRIGGER_FALLING (0x2UL << TRIGGER_MODE_Pos) +/** + * @} + */ + +/** @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)) +/** + * @} + */ + +/* Include GPIO HAL Extended module */ +#include "stm32h7rsxx_hal_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Functions GPIO Exported Functions + * @brief GPIO Exported Functions + * @{ + */ + +/** @defgroup 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 *GPIO_Init); +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); + +/** + * @} + */ + +/** @defgroup 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); +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_Callback(uint16_t GPIO_Pin); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_GPIO_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio_ex.h new file mode 100644 index 0000000..5095b5c --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpio_ex.h @@ -0,0 +1,266 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_gpio_ex.h + * @author MCD Application Team + * @brief Header file of GPIO HAL Extended 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 STM32H7RSxx_HAL_GPIO_EX_H +#define STM32H7RSxx_HAL_GPIO_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup GPIOEx GPIOEx + * @brief GPIO Extended HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ + +/** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants + * @{ + */ + +/** @defgroup GPIOEx_Alternate_function_selection GPIOEx Alternate function selection + * @{ + */ + +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /*!< MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_JTAG ((uint8_t)0x00) /*!< JTAG Alternate Function mapping */ +#define GPIO_AF0_SWD ((uint8_t)0x00) /*!< SWD Alternate Function mapping */ +#define GPIO_AF0_RTC ((uint8_t)0x00) /*!< RCT_OUT Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /*!< TRACE Alternate Function mapping */ +#define GPIO_AF0_PWR ((uint8_t)0x00) /*!< PWR Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_ADF1 ((uint8_t)0x01) /*!< ADF1 Alternate Function mapping */ +#define GPIO_AF1_LPTIM1 ((uint8_t)0x01) /*!< LPTIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /*!< TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /*!< TIM2 Alternate Function mapping */ +#define GPIO_AF1_TIM16 ((uint8_t)0x01) /*!< TIM16 Alternate Function mapping */ +#define GPIO_AF1_TIM17 ((uint8_t)0x01) /*!< TIM17 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_GFXTIM ((uint8_t)0x02) /*!< GFXTIM Alternate Function mapping */ +#define GPIO_AF2_SAI1 ((uint8_t)0x02) /*!< SAI1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02) /*!< TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /*!< TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /*!< TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /*!< TIM5 Alternate Function mapping */ +#define GPIO_AF2_TIM12 ((uint8_t)0x02) /*!< TIM12 Alternate Function mapping */ +#define GPIO_AF2_TIM15 ((uint8_t)0x02) /*!< TIM15 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_ADF1 ((uint8_t)0x03) /*!< ADF1 Alternate Function mapping */ +#define GPIO_AF3_LPTIM2 ((uint8_t)0x03) /*!< LPTIM2 Alternate Function mapping */ +#define GPIO_AF3_LPTIM3 ((uint8_t)0x03) /*!< LPTIM3 Alternate Function mapping */ +#define GPIO_AF3_LPTIM4 ((uint8_t)0x03) /*!< LPTIM4 Alternate Function mapping */ +#define GPIO_AF3_LPTIM5 ((uint8_t)0x03) /*!< LPTIM5 Alternate Function mapping */ +#define GPIO_AF3_LPUART1 ((uint8_t)0x03) /*!< LPUART1 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /*!< TIM9 Alternate Function mapping */ +#define GPIO_AF3_USART3 ((uint8_t)0x03) /*!< USART3 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_CEC ((uint8_t)0x04) /*!< CEC Alternate Function mapping */ +#define GPIO_AF4_DCMIPP ((uint8_t)0x04) /*!< DCMIPP Alternate Function mapping */ +#define GPIO_AF4_ETH ((uint8_t)0x04) /*!< ETH Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /*!< I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /*!< I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /*!< I2C3 Alternate Function mapping */ +#define GPIO_AF4_I3C1 ((uint8_t)0x04) /*!< I3C1 Alternate Function mapping */ +#define GPIO_AF4_TIM15 ((uint8_t)0x04) /*!< TIM15 Alternate Function mapping */ +#define GPIO_AF4_USART1 ((uint8_t)0x04) /*!< USART1 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_CEC ((uint8_t)0x05) /*!< CEC Alternate Function mapping */ +#define GPIO_AF5_DCMIPP ((uint8_t)0x05) /*!< DCMIPP Alternate Function mapping */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /*!< SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /*!< SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /*!< SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /*!< SPI4 Alternate Function mapping */ +#define GPIO_AF5_SPI5 ((uint8_t)0x05) /*!< SPI5 Alternate Function mapping */ +#define GPIO_AF5_SPI6 ((uint8_t)0x05) /*!< SPI6/I2S6 Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_PSSI ((uint8_t)0x06) /*!< PSSI Alternate Function mapping */ +#define GPIO_AF6_SAI1 ((uint8_t)0x06) /*!< SAI1 Alternate Function mapping */ +#define GPIO_AF6_SDMMC1 ((uint8_t)0x06) /*!< SDMMC1 Alternate Function mapping */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /*!< SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_SPI4 ((uint8_t)0x06) /*!< SPI4 Alternate Function mapping */ +#define GPIO_AF6_UART4 ((uint8_t)0x06) /*!< UART4 Alternate Function mapping */ +#define GPIO_AF6_UCPD ((uint8_t)0x06) /*!< UCPD Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_FMC ((uint8_t)0x07) /*!< FMC Alternate Function mapping */ +#define GPIO_AF7_SDMMC1 ((uint8_t)0x07) /*!< SDMMC1 Alternate Function mapping */ +#define GPIO_AF7_SPI2 ((uint8_t)0x07) /*!< SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07) /*!< SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF7_SPI6 ((uint8_t)0x07) /*!< SPI6/I2S6 Alternate Function mapping */ +#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 */ +#define GPIO_AF7_UART7 ((uint8_t)0x07) /*!< UART7 Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_GFXTIM ((uint8_t)0x08) /*!< GFXTIM Alternate Function mapping */ +#define GPIO_AF8_LPUART1 ((uint8_t)0x08) /*!< LPUART1 Alternate Function mapping */ +#define GPIO_AF8_PSSI ((uint8_t)0x08) /*!< PSSI Alternate Function mapping */ +#define GPIO_AF8_SAI2 ((uint8_t)0x08) /*!< SAI2 Alternate Function mapping */ +#define GPIO_AF8_SDMMC1 ((uint8_t)0x08) /*!< SDMMC1 Alternate Function mapping */ +#define GPIO_AF8_SPDIFRX ((uint8_t)0x08) /*!< SPDIFRX Alternate Function mapping */ +#define GPIO_AF8_SPI6 ((uint8_t)0x08) /*!< SPI6/I2S6 Alternate Function mapping */ +#define GPIO_AF8_UART4 ((uint8_t)0x08) /*!< UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08) /*!< UART5 Alternate Function mapping */ +#define GPIO_AF8_UART8 ((uint8_t)0x08) /*!< UART8 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_FDCAN1 ((uint8_t)0x09) /*!< FDCAN1 Alternate Function mapping */ +#define GPIO_AF9_FDCAN2 ((uint8_t)0x09) /*!< FDCAN2 Alternate Function mapping */ +#define GPIO_AF9_FMC ((uint8_t)0x09) /*!< FMC Alternate Function mapping */ +#define GPIO_AF9_XSPIM_P1 ((uint8_t)0x09) /*!< XSPIM Manager Port 1 Alternate Function mapping */ +#define GPIO_AF9_XSPIM_P2 ((uint8_t)0x09) /*!< XSPIM Manager Port 2 Alternate Function mapping */ +#define GPIO_AF9_PSSI ((uint8_t)0x09) /*!< PSSI Alternate Function mapping */ +#define GPIO_AF9_SDMMC2 ((uint8_t)0x09) /*!< SDMMC2 Alternate Function mapping */ +#define GPIO_AF9_SPDIFRX ((uint8_t)0x09) /*!< SPDIFRX Alternate Function mapping */ +#define GPIO_AF9_SPI5 ((uint8_t)0x09) /*!< SPI5 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /*!< TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /*!< TIM14 Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_CRS ((uint8_t)0x0A) /*!< CRS Alternate Function mapping */ +#define GPIO_AF10_FMC ((uint8_t)0x0A) /*!< FMC Alternate Function mapping */ +#define GPIO_AF10_LTDC ((uint8_t)0x0A) /*!< LTDC Alternate Function mapping */ +#define GPIO_AF10_OTG_FS ((uint8_t)0x0A) /*!< OTG FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0x0A) /*!< OTG HS Alternate Function mapping */ +#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /*!< SAI2 Alternate Function mapping */ +#define GPIO_AF10_SDMMC2 ((uint8_t)0x0A) /*!< SDMMC2 Alternate Function mapping */ +#define GPIO_AF10_SPI1 ((uint8_t)0x0A) /*!< SPI1/I2S1 Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_ETH ((uint8_t)0x0B) /*!< ETH Alternate Function mapping */ +#define GPIO_AF11_LTDC ((uint8_t)0x0B) /*!< LTDC Alternate Function mapping */ +#define GPIO_AF11_MDIOS ((uint8_t)0x0B) /*!< MDIOS Alternate Function mapping */ +#define GPIO_AF11_SDMMC1 ((uint8_t)0x0B) /*!< SDMMC1 Alternate Function mapping */ +#define GPIO_AF11_SDMMC2 ((uint8_t)0x0B) /*!< SDMMC2 Alternate Function mapping */ +#define GPIO_AF11_UART7 ((uint8_t)0x0B) /*!< UART7 Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FMC ((uint8_t)0x0C) /*!< FMC Alternate Function mapping */ +#define GPIO_AF12_GFXTIM ((uint8_t)0x0C) /*!< GFXTIM Alternate Function mapping */ +#define GPIO_AF12_LTDC ((uint8_t)0x0C) /*!< TIM1 Alternate Function mapping */ +#define GPIO_AF12_SDMMC1 ((uint8_t)0x0C) /*!< SDMMC1 Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_DCMIPP ((uint8_t)0x0D) /*!< DCMIPP Alternate Function mapping */ +#define GPIO_AF13_GFXTIM ((uint8_t)0x0D) /*!< GFXTIM Alternate Function mapping */ +#define GPIO_AF13_LTDC ((uint8_t)0x0D) /*!< TIM1 Alternate Function mapping */ + +/** + * @brief AF 14 selection + */ +#define GPIO_AF14_FMC ((uint8_t)0x0E) /*!< FMC Alternate Function mapping */ +#define GPIO_AF14_LTDC ((uint8_t)0x0E) /*!< LTDC Alternate Function mapping */ +#define GPIO_AF14_MDIOS ((uint8_t)0x0E) /*!< MDIOS Alternate Function mapping */ +#define GPIO_AF14_PSSI ((uint8_t)0x0E) /*!< PSSI Alternate Function mapping */ +#define GPIO_AF14_TIM1 ((uint8_t)0x0E) /*!< TIM1 Alternate Function mapping */ +#define GPIO_AF14_UART5 ((uint8_t)0x0E) /*!< UART5 Alternate Function mapping */ + +/** + * @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 + * @{ + */ +#define GPIO_GET_INDEX(__GPIOx__) (((uint32_t )(__GPIOx__) & (~GPIOA_BASE)) >> 10) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_GPIO_EX_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpu2d.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpu2d.h new file mode 100644 index 0000000..a039881 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_gpu2d.h @@ -0,0 +1,321 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_gpu2d.h + * @author MCD Application Team + * @brief Header file of GPU2D 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 STM32H7RSxx_HAL_GPU2D_H +#define STM32H7RSxx_HAL_GPU2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +#if defined (GPU2D) + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup GPU2D GPU2D + * @brief GPU2D HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup GPU2D_Exported_Types GPU2D Exported Types + * @{ + */ +/** + * @brief HAL GPU2D State enumeration definition + */ +typedef enum +{ + HAL_GPU2D_STATE_RESET = 0x00U, /*!< GPU2D not yet initialized or disabled */ + HAL_GPU2D_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_GPU2D_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_GPU2D_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_GPU2D_STATE_ERROR = 0x04U +} HAL_GPU2D_StateTypeDef; + +/** + * @brief GPU2D_TypeDef definition + */ +typedef uint32_t GPU2D_TypeDef; + +/** + * @brief GPU2D handle Structure definition + */ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +typedef struct __GPU2D_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ +{ + GPU2D_TypeDef Instance; /*!< GPU2D register base address. */ + + HAL_LockTypeDef Lock; /*!< GPU2D lock. */ + + __IO HAL_GPU2D_StateTypeDef State; /*!< GPU2D transfer state. */ + + __IO uint32_t ErrorCode; /*!< GPU2D error code. */ + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + void (* CommandListCpltCallback)(struct __GPU2D_HandleTypeDef *hgpu2d, uint32_t CmdListID); /*!< GPU2D Command Complete Callback */ + + void (* MspInitCallback)(struct __GPU2D_HandleTypeDef *hgpu2d); /*!< GPU2D Msp Init callback */ + + void (* MspDeInitCallback)(struct __GPU2D_HandleTypeDef *hgpu2d); /*!< GPU2D Msp DeInit callback */ +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ +} GPU2D_HandleTypeDef; + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +/** + * @brief HAL GPU2D Callback ID enumeration definition + */ +typedef enum +{ + HAL_GPU2D_MSPINIT_CB_ID = 0x00U, /*!< GPU2D MspInit callback ID */ + HAL_GPU2D_MSPDEINIT_CB_ID = 0x01U, /*!< GPU2D MspDeInit callback ID */ +} HAL_GPU2D_CallbackIDTypeDef; + +/** @defgroup HAL_GPU2D_Callback_pointer_definition HAL GPU2D Callback pointer definition + * @brief HAL GPU2D Callback pointer definition + * @{ + */ +typedef void (*pGPU2D_CallbackTypeDef)(GPU2D_HandleTypeDef *hgpu2d); /*!< pointer to an GPU2D Callback function */ +typedef void (*pGPU2D_CommandListCpltCallbackTypeDef)(GPU2D_HandleTypeDef *hgpu2d, uint32_t CmdID); /*!< pointer to an GPU2D Command List Complete Callback function */ +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPU2D_Exported_Constants GPU2D Exported Constants + * @{ + */ + +/** @defgroup GPU2D_Error_Code_definition GPU2D Error Code definition + * @brief GPU2D Error Code definition + * @{ + */ +#define HAL_GPU2D_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_GPU2D_ERROR_TIMEOUT (0x00000001U) /*!< Timeout error */ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +#define HAL_GPU2D_ERROR_INVALID_CALLBACK (0x00000002U) /*!< Invalid callback error */ +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ +/** + * @} + */ + +/** @defgroup GPU2D_Interrupt_configuration_definition GPU2D Interrupt configuration definition + * @brief GPU2D Interrupt definition + * @{ + */ +#define GPU2D_IT_CLC 0x00000001U /*!< Command List Complete Interrupt */ +/** + * @} + */ + +/** @defgroup GPU2D_Flag_definition GPU2D Flag definition + * @brief GPU2D Flags definition + * @{ + */ +#define GPU2D_FLAG_CLC 0x00000001U /*!< Command List Complete Interrupt Flag */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup GPU2D_Exported_Macros GPU2D Exported Macros + * @{ + */ + +/** @brief Reset GPU2D handle state + * @param __HANDLE__: specifies the GPU2D handle. + * @retval None + */ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +#define __HAL_GPU2D_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_GPU2D_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + (__HANDLE__)->CommandListCpltCallback = NULL; \ + } while(0) +#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */ +#define __HAL_GPU2D_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_GPU2D_STATE_RESET) +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + +/* Interrupt & Flag management */ +/** + * @brief Get the GPU2D pending flags. + * @param __HANDLE__: GPU2D handle + * @param __FLAG__: flag to check. + * This parameter can be one of the following values: + * @arg GPU2D_FLAG_CLC: Command List Complete interrupt mask + * @retval The state of FLAG. + */ +#define __HAL_GPU2D_GET_FLAG(__HANDLE__, __FLAG__) (READ_REG(*(__IO uint32_t *)((uint32_t)(__HANDLE__)->Instance\ + + GPU2D_ITCTRL)) & (__FLAG__)) + +/** + * @brief Clear the GPU2D pending flags. + * @param __HANDLE__: GPU2D handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg GPU2D_FLAG_CLC: Command List Complete interrupt mask + * @retval None + */ +#define __HAL_GPU2D_CLEAR_FLAG(__HANDLE__, __FLAG__) do { \ + __IO uint32_t *tmpreg = \ + (__IO uint32_t *)((uint32_t)(__HANDLE__)->Instance\ + + GPU2D_ITCTRL); \ + CLEAR_BIT(*tmpreg, __FLAG__); \ + } while(0U) + +/** + * @brief Check whether the specified GPU2D interrupt source is enabled or not. + * @param __HANDLE__: GPU2D handle + * @param __INTERRUPT__: specifies the GPU2D interrupt source to check. + * This parameter can be one of the following values: + * @arg GPU2D_IT_CLC: Command List Complete interrupt mask + * @retval The state of INTERRUPT source. + */ +#define __HAL_GPU2D_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (READ_REG(*(__IO uint32_t *)\ + ((uint32_t)(__HANDLE__)->Instance\ + + GPU2D_ITCTRL)) & (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPU2D_Exported_Functions GPU2D Exported Functions + * @{ + */ + +/** @addtogroup GPU2D_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions *******************************/ +HAL_StatusTypeDef HAL_GPU2D_Init(GPU2D_HandleTypeDef *hgpu2d); +HAL_StatusTypeDef HAL_GPU2D_DeInit(GPU2D_HandleTypeDef *hgpu2d); +void HAL_GPU2D_MspInit(GPU2D_HandleTypeDef *hgpu2d); +void HAL_GPU2D_MspDeInit(GPU2D_HandleTypeDef *hgpu2d); +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_GPU2D_RegisterCallback(GPU2D_HandleTypeDef *hgpu2d, HAL_GPU2D_CallbackIDTypeDef CallbackID, + pGPU2D_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_GPU2D_UnRegisterCallback(GPU2D_HandleTypeDef *hgpu2d, HAL_GPU2D_CallbackIDTypeDef CallbackID); +HAL_StatusTypeDef HAL_GPU2D_RegisterCommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d, + pGPU2D_CommandListCpltCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_GPU2D_UnRegisterCommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d); +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + +/** + * @} + */ + + +/** @addtogroup GPU2D_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *******************************************************/ +uint32_t HAL_GPU2D_ReadRegister(const GPU2D_HandleTypeDef *hgpu2d, uint32_t offset); +HAL_StatusTypeDef HAL_GPU2D_WriteRegister(GPU2D_HandleTypeDef *hgpu2d, uint32_t offset, uint32_t value); +void HAL_GPU2D_IRQHandler(GPU2D_HandleTypeDef *hgpu2d); +void HAL_GPU2D_ER_IRQHandler(GPU2D_HandleTypeDef *hgpu2d); +void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d, uint32_t CmdListID); +void HAL_GPU2D_ErrorCallback(GPU2D_HandleTypeDef *hgpu2d); + +/** + * @} + */ + +/** @addtogroup GPU2D_Exported_Functions_Group3 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State functions ***************************************************/ +HAL_GPU2D_StateTypeDef HAL_GPU2D_GetState(GPU2D_HandleTypeDef const *const hgpu2d); +uint32_t HAL_GPU2D_GetError(GPU2D_HandleTypeDef const *const hgpu2d); + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @addtogroup GPU2D_Private_Constants GPU2D Private Constants + * @{ + */ + +#define GPU2D_ITCTRL (0x0F8U) /*!< GPU2D Interrupt Control Register Offset */ +#define GPU2D_CLID (0x148U) /*!< GPU2D Last Command List Identifier Register Offset */ +#define GPU2D_BREAKPOINT (0x080U) /*!< GPU2D Breakpoint Register Offset */ +#define GPU2D_SYS_INTERRUPT (0xff8U) /*!< GPU2D System Interrupt Register Offset */ + +/** @defgroup GPU2D_Offset GPU2D Last Register Offset + * @{ + */ +#define GPU2D_OFFSET 0x1000U /*!< Last GPU2D Register Offset */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPU2D_Private_Macros GPU2D Private Macros + * @{ + */ +#define IS_GPU2D_OFFSET(OFFSET) ((OFFSET) < GPU2D_OFFSET) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (GPU2D) */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_GPU2D_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c.h new file mode 100644 index 0000000..3c4d4b0 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c.h @@ -0,0 +1,842 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C 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 STM32H7RSxx_HAL_I2C_H +#define STM32H7RSxx_HAL_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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_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 "stm32h7rsxx_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 stm32h7rsxx_hal_i2c.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H7RSxx_HAL_I2C_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c_ex.h new file mode 100644 index 0000000..ca69f5a --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2c_ex.h @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extended 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 STM32H7RSxx_HAL_I2C_EX_H +#define STM32H7RSxx_HAL_I2C_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 stm32h7rsxx_hal_i2c_ex.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_I2C_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s.h new file mode 100644 index 0000000..6fd0d9d --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s.h @@ -0,0 +1,668 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_i2s.h + * @author MCD Application Team + * @brief Header file of I2S 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 STM32H7RSxx_HAL_I2S_H +#define STM32H7RSxx_HAL_I2S_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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); + +/* IO Swap feature */ +HAL_StatusTypeDef HAL_I2S_EnableIOSwap(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DisableIOSwap(I2S_HandleTypeDef *hi2s); +uint32_t HAL_I2S_IsEnabledIOSwap(const 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 /* STM32H7RSxx_HAL_I2S_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s_ex.h new file mode 100644 index 0000000..302b173 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_i2s_ex.h @@ -0,0 +1,26 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_i2s_ex.h + * @author MCD Application Team + * @brief Header file of I2S 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. + * + ****************************************************************************** + */ + +/** + ****************************************************************************** + ===== I2S FULL DUPLEX FEATURE ===== + I2S Full Duplex APIs are available in stm32h7rsxx_hal_i2s.c/.h + ****************************************************************************** + */ + + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_icache.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_icache.h new file mode 100644 index 0000000..e52ab31 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_icache.h @@ -0,0 +1,216 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_icache.h + * @author MCD Application Team + * @brief Header file of ICACHE 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 STM32H7RSxx_HAL_ICACHE_H +#define STM32H7RSxx_HAL_ICACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -----------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +#if defined(ICACHE) +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup ICACHE + * @{ + */ + +/* Exported types -----------------------------------------------------------*/ + +/* Exported constants -------------------------------------------------------*/ +/** @defgroup ICACHE_Exported_Constants ICACHE Exported Constants + * @{ + */ + +/** @defgroup ICACHE_WaysSelection Ways selection + * @{ + */ +#define ICACHE_1WAY 0UL /*!< 1-way cache (direct mapped cache) */ +#define ICACHE_4WAYS ICACHE_CR_WAYSEL /*!< 4-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 */ +/** + * @} + */ + + +/** @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); + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* ICACHE */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_ICACHE_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_jpeg.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_jpeg.h new file mode 100644 index 0000000..b5a40af --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_jpeg.h @@ -0,0 +1,654 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_jpeg.h + * @author MCD Application Team + * @brief Header file of JPEG 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 STM32H7RSxx_HAL_JPEG_H +#define STM32H7RSxx_HAL_JPEG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +#if defined (JPEG) + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup JPEG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup JPEG_Exported_Types JPEG Exported Types + * @{ + */ + +/** @defgroup JPEG_Configuration_Structure_definition JPEG Configuration for encoding Structure definition + * @brief JPEG encoding configuration Structure definition + * @{ + */ +typedef struct +{ + uint32_t ColorSpace; /*!< Image Color space : gray-scale, YCBCR, RGB or CMYK + This parameter can be a value of @ref JPEG_ColorSpace */ + + uint32_t ChromaSubsampling; /*!< Chroma Subsampling in case of YCBCR or CMYK color space, 0-> 4:4:4 , 1-> 4:2:2, 2 -> 4:1:1, 3 -> 4:2:0 + This parameter can be a value of @ref JPEG_ChromaSubsampling */ + + uint32_t ImageHeight; /*!< Image height : number of lines */ + + uint32_t ImageWidth; /*!< Image width : number of pixels per line */ + + uint32_t ImageQuality; /*!< Quality of the JPEG encoding : from 1 to 100 */ + +} JPEG_ConfTypeDef; +/** + * @} + */ + +/** @defgroup HAL_JPEG_state_structure_definition HAL JPEG state structure definition + * @brief HAL JPEG State structure definition + * @{ + */ +typedef enum +{ + HAL_JPEG_STATE_RESET = 0x00U, /*!< JPEG not yet initialized or disabled */ + HAL_JPEG_STATE_READY = 0x01U, /*!< JPEG initialized and ready for use */ + HAL_JPEG_STATE_BUSY = 0x02U, /*!< JPEG internal processing is ongoing */ + HAL_JPEG_STATE_BUSY_ENCODING = 0x03U, /*!< JPEG encoding processing is ongoing */ + HAL_JPEG_STATE_BUSY_DECODING = 0x04U, /*!< JPEG decoding processing is ongoing */ + HAL_JPEG_STATE_TIMEOUT = 0x05U, /*!< JPEG timeout state */ + HAL_JPEG_STATE_ERROR = 0x06U /*!< JPEG error state */ +} HAL_JPEG_STATETypeDef; + +/** + * @} + */ + + +/** @defgroup JPEG_handle_Structure_definition JPEG handle Structure definition + * @brief JPEG handle Structure definition + * @{ + */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) +typedef struct __JPEG_HandleTypeDef +#else +typedef struct +#endif /* (USE_HAL_JPEG_REGISTER_CALLBACKS) */ +{ + JPEG_TypeDef *Instance; /*!< JPEG peripheral register base address */ + + JPEG_ConfTypeDef Conf; /*!< Current JPEG encoding/decoding parameters */ + + uint8_t *pJpegInBuffPtr; /*!< Pointer to JPEG processing (encoding, decoding,...) input buffer */ + + uint8_t *pJpegOutBuffPtr; /*!< Pointer to JPEG processing (encoding, decoding,...) output buffer */ + + __IO uint32_t JpegInCount; /*!< Internal Counter of input data */ + + __IO uint32_t JpegOutCount; /*!< Internal Counter of output data */ + + uint32_t InDataLength; /*!< Input Buffer Length in Bytes */ + + uint32_t OutDataLength; /*!< Output Buffer Length in Bytes */ + + DMA_HandleTypeDef *hdmain; /*!< JPEG In DMA handle parameters */ + + DMA_HandleTypeDef *hdmaout; /*!< JPEG Out DMA handle parameters */ + + uint8_t CustomQuanTable; /*!< If set to 1 specify that user customized quantization tables are used */ + + uint8_t *QuantTable0; /*!< Basic Quantization Table for component 0 */ + + uint8_t *QuantTable1; /*!< Basic Quantization Table for component 1 */ + + uint8_t *QuantTable2; /*!< Basic Quantization Table for component 2 */ + + uint8_t *QuantTable3; /*!< Basic Quantization Table for component 3 */ + + HAL_LockTypeDef Lock; /*!< JPEG locking object */ + + __IO HAL_JPEG_STATETypeDef State; /*!< JPEG peripheral state */ + + __IO uint32_t ErrorCode; /*!< JPEG Error code */ + + __IO uint32_t Context; /*!< JPEG Internal context */ + +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + void (*InfoReadyCallback)(struct __JPEG_HandleTypeDef *hjpeg, + JPEG_ConfTypeDef *pInfo); /*!< JPEG Info ready callback */ + void (*EncodeCpltCallback)(struct __JPEG_HandleTypeDef + *hjpeg); /*!< JPEG Encode complete callback */ + void (*DecodeCpltCallback)(struct __JPEG_HandleTypeDef + *hjpeg); /*!< JPEG Decode complete callback */ + void (*ErrorCallback)(struct __JPEG_HandleTypeDef + *hjpeg); /*!< JPEG Error callback */ + void (*GetDataCallback)(struct __JPEG_HandleTypeDef *hjpeg, + uint32_t NbDecodedData); /*!< JPEG Get Data callback */ + void (*DataReadyCallback)(struct __JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, + uint32_t OutDataLength); /*!< JPEG Data ready callback */ + + void (* MspInitCallback)(struct __JPEG_HandleTypeDef *hjpeg); /*!< JPEG Msp Init callback */ + void (* MspDeInitCallback)(struct __JPEG_HandleTypeDef + *hjpeg); /*!< JPEG Msp DeInit callback */ + + +#endif /* (USE_HAL_JPEG_REGISTER_CALLBACKS) */ + + +} JPEG_HandleTypeDef; +/** + * @} + */ + + +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) +/** @defgroup HAL_JPEG_Callback_ID_enumeration_definition HAL JPEG Callback ID enumeration definition + * @brief HAL JPEG Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_JPEG_ENCODE_CPLT_CB_ID = 0x01U, /*!< JPEG Encode Complete callback ID */ + HAL_JPEG_DECODE_CPLT_CB_ID = 0x02U, /*!< JPEG Decode Complete callback ID */ + HAL_JPEG_ERROR_CB_ID = 0x03U, /*!< JPEG Error callback ID */ + + HAL_JPEG_MSPINIT_CB_ID = 0x04U, /*!< JPEG MspInit callback ID */ + HAL_JPEG_MSPDEINIT_CB_ID = 0x05U /*!< JPEG MspDeInit callback ID */ + +} HAL_JPEG_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup HAL_JPEG_Callback_pointer_definition HAL JPEG Callback pointer definition + * @brief HAL JPEG Callback pointer definition + * @{ + */ +typedef void (*pJPEG_CallbackTypeDef)(JPEG_HandleTypeDef *hjpeg); /*!< pointer to a common JPEG callback function */ +typedef void (*pJPEG_InfoReadyCallbackTypeDef)(JPEG_HandleTypeDef *hjpeg, + JPEG_ConfTypeDef *pInfo); /*!< pointer to an Info ready JPEG callback function */ +typedef void (*pJPEG_GetDataCallbackTypeDef)(JPEG_HandleTypeDef *hjpeg, + uint32_t NbDecodedData); /*!< pointer to a Get data JPEG callback function */ +typedef void (*pJPEG_DataReadyCallbackTypeDef)(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, + uint32_t OutDataLength); /*!< pointer to a Data ready JPEG callback function */ +/** + * @} + */ + +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup JPEG_Exported_Constants JPEG Exported Constants + * @{ + */ + +/** @defgroup JPEG_Error_Code_definition JPEG Error Code definition + * @brief JPEG Error Code definition + * @{ + */ + +#define HAL_JPEG_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */ +#define HAL_JPEG_ERROR_HUFF_TABLE ((uint32_t)0x00000001U) /*!< HUffman Table programming error */ +#define HAL_JPEG_ERROR_QUANT_TABLE ((uint32_t)0x00000002U) /*!< Quantization Table programming error */ +#define HAL_JPEG_ERROR_DMA ((uint32_t)0x00000004U) /*!< DMA transfer error */ +#define HAL_JPEG_ERROR_TIMEOUT ((uint32_t)0x00000008U) /*!< Timeout error */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) +#define HAL_JPEG_ERROR_INVALID_CALLBACK ((uint32_t)0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup JPEG_Quantization_Table_Size JPEG Quantization Table Size + * @brief JPEG Quantization Table Size + * @{ + */ +#define JPEG_QUANT_TABLE_SIZE ((uint32_t)64U) /*!< JPEG Quantization Table Size in bytes */ +/** + * @} + */ + + +/** @defgroup JPEG_ColorSpace JPEG ColorSpace + * @brief JPEG Color Space + * @{ + */ +#define JPEG_GRAYSCALE_COLORSPACE ((uint32_t)0x00000000U) +#define JPEG_YCBCR_COLORSPACE JPEG_CONFR1_COLORSPACE_0 +#define JPEG_CMYK_COLORSPACE JPEG_CONFR1_COLORSPACE + + +/** + * @} + */ + + +/** @defgroup JPEG_ChromaSubsampling JPEG Chrominance Sampling + * @brief JPEG Chrominance Sampling + * @{ + */ +#define JPEG_444_SUBSAMPLING ((uint32_t)0x00000000U) /*!< Chroma Subsampling 4:4:4 */ +#define JPEG_420_SUBSAMPLING ((uint32_t)0x00000001U) /*!< Chroma Subsampling 4:2:0 */ +#define JPEG_422_SUBSAMPLING ((uint32_t)0x00000002U) /*!< Chroma Subsampling 4:2:2 */ + +/** + * @} + */ + +/** @defgroup JPEG_ImageQuality JPEG Image Quality + * @brief JPEG Min and Max Image Quality + * @{ + */ +#define JPEG_IMAGE_QUALITY_MIN ((uint32_t)1U) /*!< Minimum JPEG quality */ +#define JPEG_IMAGE_QUALITY_MAX ((uint32_t)100U) /*!< Maximum JPEG quality */ + +/** + * @} + */ + +/** @defgroup JPEG_Interrupt_configuration_definition JPEG Interrupt configuration definition + * @brief JPEG Interrupt definition + * @{ + */ +#define JPEG_IT_IFT ((uint32_t)JPEG_CR_IFTIE) /*!< Input FIFO Threshold Interrupt */ +#define JPEG_IT_IFNF ((uint32_t)JPEG_CR_IFNFIE) /*!< Input FIFO Not Full Interrupt */ +#define JPEG_IT_OFT ((uint32_t)JPEG_CR_OFTIE) /*!< Output FIFO Threshold Interrupt */ +#define JPEG_IT_OFNE ((uint32_t)JPEG_CR_OFTIE) /*!< Output FIFO Not Empty Interrupt */ +#define JPEG_IT_EOC ((uint32_t)JPEG_CR_EOCIE) /*!< End of Conversion Interrupt */ +#define JPEG_IT_HPD ((uint32_t)JPEG_CR_HPDIE) /*!< Header Parsing Done Interrupt */ +/** + * @} + */ + +/** @defgroup JPEG_Flag_definition JPEG Flag definition + * @brief JPEG Flags definition + * @{ + */ +#define JPEG_FLAG_IFTF ((uint32_t)JPEG_SR_IFTF) /*!< Input FIFO is not full and is below its threshold flag */ +#define JPEG_FLAG_IFNFF ((uint32_t)JPEG_SR_IFNFF) /*!< Input FIFO Not Full Flag, a data can be written */ +#define JPEG_FLAG_OFTF ((uint32_t)JPEG_SR_OFTF) /*!< Output FIFO is not empty and has reach its threshold */ +#define JPEG_FLAG_OFNEF ((uint32_t)JPEG_SR_OFNEF) /*!< Output FIFO is not empty, a data is available */ +#define JPEG_FLAG_EOCF ((uint32_t)JPEG_SR_EOCF) /*!< JPEG Codec core has finished the encoding or the decoding process and than last data has been sent to the output FIFO */ +#define JPEG_FLAG_HPDF ((uint32_t)JPEG_SR_HPDF) /*!< JPEG Codec has finished the parsing of the headers and the internal registers have been updated */ +#define JPEG_FLAG_COF ((uint32_t)JPEG_SR_COF) /*!< JPEG Codec operation on going flag*/ + +#define JPEG_FLAG_ALL ((uint32_t)0x000000FEU) /*!< JPEG Codec All previous flag*/ +/** + * @} + */ + +/** @defgroup JPEG_PROCESS_PAUSE_RESUME_definition JPEG Process Pause Resume definition + * @brief JPEG process pause, resume definition + * @{ + */ +#define JPEG_PAUSE_RESUME_INPUT ((uint32_t)0x00000001U) /*!< Pause/Resume Input FIFO Xfer*/ +#define JPEG_PAUSE_RESUME_OUTPUT ((uint32_t)0x00000002U) /*!< Pause/Resume Output FIFO Xfer*/ +#define JPEG_PAUSE_RESUME_INPUT_OUTPUT ((uint32_t)0x00000003U) /*!< Pause/Resume Input and Output FIFO Xfer*/ +/** + * @} + */ + +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup JPEG_Exported_Macros JPEG Exported Macros + * @{ + */ + +/** @brief Reset JPEG handle state + * @param __HANDLE__ specifies the JPEG handle. + * @retval None + */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) +#define __HAL_JPEG_RESET_HANDLE_STATE(__HANDLE__) do{\ + (__HANDLE__)->State = HAL_JPEG_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL;\ + (__HANDLE__)->MspDeInitCallback = NULL;\ + }while(0) +#else +#define __HAL_JPEG_RESET_HANDLE_STATE(__HANDLE__) ( (__HANDLE__)->State = HAL_JPEG_STATE_RESET) +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + +/** + * @brief Enable the JPEG peripheral. + * @param __HANDLE__ specifies the JPEG handle. + * @retval None + */ +#define __HAL_JPEG_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= JPEG_CR_JCEN) + +/** + * @brief Disable the JPEG peripheral. + * @param __HANDLE__ specifies the JPEG handle. + * @retval None + */ +#define __HAL_JPEG_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~JPEG_CR_JCEN) + + +/** + * @brief Check the specified JPEG status flag. + * @param __HANDLE__ specifies the JPEG handle. + * @param __FLAG__ specifies the flag to check + * This parameter can be one of the following values: + * @arg JPEG_FLAG_IFTF : The input FIFO is not full and is below its threshold flag + * @arg JPEG_FLAG_IFNFF : The input FIFO Not Full Flag, a data can be written + * @arg JPEG_FLAG_OFTF : The output FIFO is not empty and has reach its threshold + * @arg JPEG_FLAG_OFNEF : The output FIFO is not empty, a data is available + * @arg JPEG_FLAG_EOCF : JPEG Codec core has finished the encoding or the decoding process + * and than last data has been sent to the output FIFO + * @arg JPEG_FLAG_HPDF : JPEG Codec has finished the parsing of the headers + * and the internal registers have been updated + * @arg JPEG_FLAG_COF : JPEG Codec operation on going flag + * + * @retval __HAL_JPEG_GET_FLAG : returns The new state of __FLAG__ (TRUE or FALSE) + */ + +#define __HAL_JPEG_GET_FLAG(__HANDLE__,__FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__))) + +/** + * @brief Clear the specified JPEG status flag. + * @param __HANDLE__ specifies the JPEG handle. + * @param __FLAG__ specifies the flag to clear + * This parameter can be one of the following values: + * @arg JPEG_FLAG_EOCF : JPEG Codec core has finished the encoding or the decoding process + * and than last data has been sent to the output FIFO + * @arg JPEG_FLAG_HPDF : JPEG Codec has finished the parsing of the headers + * @retval None + */ + +#define __HAL_JPEG_CLEAR_FLAG(__HANDLE__,__FLAG__) (((__HANDLE__)->Instance->CFR |= ((__FLAG__) &\ + (JPEG_FLAG_EOCF | JPEG_FLAG_HPDF)))) + + +/** + * @brief Enable Interrupt. + * @param __HANDLE__ specifies the JPEG handle. + * @param __INTERRUPT__ specifies the interrupt to enable + * This parameter can be one of the following values: + * @arg JPEG_IT_IFT : Input FIFO Threshold Interrupt + * @arg JPEG_IT_IFNF : Input FIFO Not Full Interrupt + * @arg JPEG_IT_OFT : Output FIFO Threshold Interrupt + * @arg JPEG_IT_OFNE : Output FIFO Not empty Interrupt + * @arg JPEG_IT_EOC : End of Conversion Interrupt + * @arg JPEG_IT_HPD : Header Parsing Done Interrupt + * + * @retval No return + */ +#define __HAL_JPEG_ENABLE_IT(__HANDLE__,__INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__) ) + +/** + * @brief Disable Interrupt. + * @param __HANDLE__ specifies the JPEG handle. + * @param __INTERRUPT__ specifies the interrupt to disable + * This parameter can be one of the following values: + * @arg JPEG_IT_IFT : Input FIFO Threshold Interrupt + * @arg JPEG_IT_IFNF : Input FIFO Not Full Interrupt + * @arg JPEG_IT_OFT : Output FIFO Threshold Interrupt + * @arg JPEG_IT_OFNE : Output FIFO Not empty Interrupt + * @arg JPEG_IT_EOC : End of Conversion Interrupt + * @arg JPEG_IT_HPD : Header Parsing Done Interrupt + * + * @note To disable an IT we must use MODIFY_REG macro to avoid writing "1" to the FIFO flush bits + * located in the same IT enable register (CR register). + * @retval No return + */ +#define __HAL_JPEG_DISABLE_IT(__HANDLE__,__INTERRUPT__) MODIFY_REG((__HANDLE__)->Instance->CR, (__INTERRUPT__), 0UL) + + +/** + * @brief Get Interrupt state. + * @param __HANDLE__ specifies the JPEG handle. + * @param __INTERRUPT__ specifies the interrupt to check + * This parameter can be one of the following values: + * @arg JPEG_IT_IFT : Input FIFO Threshold Interrupt + * @arg JPEG_IT_IFNF : Input FIFO Not Full Interrupt + * @arg JPEG_IT_OFT : Output FIFO Threshold Interrupt + * @arg JPEG_IT_OFNE : Output FIFO Not empty Interrupt + * @arg JPEG_IT_EOC : End of Conversion Interrupt + * @arg JPEG_IT_HPD : Header Parsing Done Interrupt + * + * @retval returns The new state of __INTERRUPT__ (Enabled or disabled) + */ +#define __HAL_JPEG_GET_IT_SOURCE(__HANDLE__,__INTERRUPT__) ((__HANDLE__)->Instance->CR & (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup JPEG_Exported_Functions + * @{ + */ + +/** @addtogroup JPEG_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_JPEG_Init(JPEG_HandleTypeDef *hjpeg); +HAL_StatusTypeDef HAL_JPEG_DeInit(JPEG_HandleTypeDef *hjpeg); +void HAL_JPEG_MspInit(JPEG_HandleTypeDef *hjpeg); +void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef *hjpeg); + +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_JPEG_RegisterCallback(JPEG_HandleTypeDef *hjpeg, HAL_JPEG_CallbackIDTypeDef CallbackID, + pJPEG_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_JPEG_UnRegisterCallback(JPEG_HandleTypeDef *hjpeg, HAL_JPEG_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_JPEG_RegisterInfoReadyCallback(JPEG_HandleTypeDef *hjpeg, + pJPEG_InfoReadyCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_JPEG_UnRegisterInfoReadyCallback(JPEG_HandleTypeDef *hjpeg); + +HAL_StatusTypeDef HAL_JPEG_RegisterGetDataCallback(JPEG_HandleTypeDef *hjpeg, pJPEG_GetDataCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_JPEG_UnRegisterGetDataCallback(JPEG_HandleTypeDef *hjpeg); + +HAL_StatusTypeDef HAL_JPEG_RegisterDataReadyCallback(JPEG_HandleTypeDef *hjpeg, + pJPEG_DataReadyCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_JPEG_UnRegisterDataReadyCallback(JPEG_HandleTypeDef *hjpeg); + +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup JPEG_Exported_Functions_Group2 + * @{ + */ +/* Encoding/Decoding Configuration functions ********************************/ +HAL_StatusTypeDef HAL_JPEG_ConfigEncoding(JPEG_HandleTypeDef *hjpeg, const JPEG_ConfTypeDef *pConf); +HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo); +HAL_StatusTypeDef HAL_JPEG_EnableHeaderParsing(JPEG_HandleTypeDef *hjpeg); +HAL_StatusTypeDef HAL_JPEG_DisableHeaderParsing(JPEG_HandleTypeDef *hjpeg); +HAL_StatusTypeDef HAL_JPEG_SetUserQuantTables(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable0, uint8_t *QTable1, + uint8_t *QTable2, uint8_t *QTable3); + +/** + * @} + */ + +/** @addtogroup JPEG_Exported_Functions_Group3 + * @{ + */ +/* JPEG processing functions **************************************/ +HAL_StatusTypeDef HAL_JPEG_Encode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, + uint8_t *pDataOut, uint32_t OutDataLength, uint32_t Timeout); +HAL_StatusTypeDef HAL_JPEG_Decode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, + uint8_t *pDataOutMCU, uint32_t OutDataLength, uint32_t Timeout); +HAL_StatusTypeDef HAL_JPEG_Encode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, + uint8_t *pDataOut, uint32_t OutDataLength); +HAL_StatusTypeDef HAL_JPEG_Decode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, + uint8_t *pDataOutMCU, uint32_t OutDataLength); +HAL_StatusTypeDef HAL_JPEG_Encode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, + uint8_t *pDataOut, uint32_t OutDataLength); +HAL_StatusTypeDef HAL_JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, + uint8_t *pDataOutMCU, uint32_t OutDataLength); +HAL_StatusTypeDef HAL_JPEG_Pause(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection); +HAL_StatusTypeDef HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection); +void HAL_JPEG_ConfigInputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewInputBuffer, uint32_t InDataLength); +void HAL_JPEG_ConfigOutputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewOutputBuffer, uint32_t OutDataLength); +HAL_StatusTypeDef HAL_JPEG_Abort(JPEG_HandleTypeDef *hjpeg); + +/** + * @} + */ + +/** @addtogroup JPEG_Exported_Functions_Group4 + * @{ + */ +/* JPEG Decode/Encode callback functions ********************************************************/ +void HAL_JPEG_InfoReadyCallback(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo); +void HAL_JPEG_EncodeCpltCallback(JPEG_HandleTypeDef *hjpeg); +void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef *hjpeg); +void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef *hjpeg); +void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef *hjpeg, uint32_t NbDecodedData); +void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, uint32_t OutDataLength); + +/** + * @} + */ + +/** @addtogroup JPEG_Exported_Functions_Group5 + * @{ + */ +/* JPEG IRQ handler management ******************************************************/ +void HAL_JPEG_IRQHandler(JPEG_HandleTypeDef *hjpeg); + +/** + * @} + */ + +/** @addtogroup JPEG_Exported_Functions_Group6 + * @{ + */ +/* Peripheral State and Error functions ************************************************/ +HAL_JPEG_STATETypeDef HAL_JPEG_GetState(const JPEG_HandleTypeDef *hjpeg); +uint32_t HAL_JPEG_GetError(const JPEG_HandleTypeDef *hjpeg); + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup JPEG_Private_Types JPEG Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @defgroup JPEG_Private_Defines JPEG Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup JPEG_Private_Variables JPEG Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup JPEG_Private_Constants JPEG Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup JPEG_Private_Macros JPEG Private Macros + * @{ + */ + +#define IS_JPEG_CHROMASUBSAMPLING(SUBSAMPLING) (((SUBSAMPLING) == JPEG_444_SUBSAMPLING) || \ + ((SUBSAMPLING) == JPEG_420_SUBSAMPLING) || \ + ((SUBSAMPLING) == JPEG_422_SUBSAMPLING)) + +#define IS_JPEG_IMAGE_QUALITY(NUMBER) (((NUMBER) >= JPEG_IMAGE_QUALITY_MIN) && ((NUMBER) <= JPEG_IMAGE_QUALITY_MAX)) + +#define IS_JPEG_COLORSPACE(COLORSPACE) (((COLORSPACE) == JPEG_GRAYSCALE_COLORSPACE) || \ + ((COLORSPACE) == JPEG_YCBCR_COLORSPACE) || \ + ((COLORSPACE) == JPEG_CMYK_COLORSPACE)) + +#define IS_JPEG_PAUSE_RESUME_STATE(VALUE) (((VALUE) == JPEG_PAUSE_RESUME_INPUT) || \ + ((VALUE) == JPEG_PAUSE_RESUME_OUTPUT)|| \ + ((VALUE) == JPEG_PAUSE_RESUME_INPUT_OUTPUT)) + +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup JPEG_Private_Functions_Prototypes JPEG Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup JPEG_Private_Functions JPEG Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* JPEG */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_JPEG_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc.h new file mode 100644 index 0000000..14cdcac --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc.h @@ -0,0 +1,720 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_ltdc.h + * @author MCD Application Team + * @brief Header file of LTDC 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 STM32H7RSxx_HAL_LTDC_H +#define STM32H7RSxx_HAL_LTDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +#if defined (LTDC) + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup LTDC LTDC + * @brief LTDC HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup LTDC_Exported_Types LTDC Exported Types + * @{ + */ +#define MAX_LAYER 2U + +/** + * @brief LTDC color structure definition + */ +typedef struct +{ + uint8_t Blue; /*!< Configures the blue value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint8_t Green; /*!< Configures the green value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint8_t Red; /*!< Configures the red value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint8_t Reserved; /*!< Reserved 0xFF */ +} LTDC_ColorTypeDef; + +/** + * @brief LTDC Init structure definition + */ +typedef struct +{ + uint32_t HSPolarity; /*!< configures the horizontal synchronization polarity. + This parameter can be one value of @ref LTDC_HS_POLARITY */ + + uint32_t VSPolarity; /*!< configures the vertical synchronization polarity. + This parameter can be one value of @ref LTDC_VS_POLARITY */ + + uint32_t DEPolarity; /*!< configures the data enable polarity. + This parameter can be one of value of @ref LTDC_DE_POLARITY */ + + uint32_t PCPolarity; /*!< configures the pixel clock polarity. + This parameter can be one of value of @ref LTDC_PC_POLARITY */ + + uint32_t HorizontalSync; /*!< configures the number of Horizontal synchronization width. + This parameter must be a number between + Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t VerticalSync; /*!< configures the number of Vertical synchronization height. + This parameter must be a number between + Min_Data = 0x000 and Max_Data = 0x7FF. */ + + uint32_t AccumulatedHBP; /*!< configures the accumulated horizontal back porch width. + This parameter must be a number between + Min_Data = LTDC_HorizontalSync and Max_Data = 0xFFF. */ + + uint32_t AccumulatedVBP; /*!< configures the accumulated vertical back porch height. + This parameter must be a number between + Min_Data = LTDC_VerticalSync and Max_Data = 0x7FF. */ + + uint32_t AccumulatedActiveW; /*!< configures the accumulated active width. + This parameter must be a number between + Min_Data = LTDC_AccumulatedHBP and Max_Data = 0xFFF. */ + + uint32_t AccumulatedActiveH; /*!< configures the accumulated active height. + This parameter must be a number between + Min_Data = LTDC_AccumulatedVBP and Max_Data = 0x7FF. */ + + uint32_t TotalWidth; /*!< configures the total width. + This parameter must be a number between + Min_Data = LTDC_AccumulatedActiveW and Max_Data = 0xFFF. */ + + uint32_t TotalHeigh; /*!< configures the total height. + This parameter must be a number between + Min_Data = LTDC_AccumulatedActiveH and Max_Data = 0x7FF. */ + + LTDC_ColorTypeDef Backcolor; /*!< Configures the background color. */ +} LTDC_InitTypeDef; + +/** + * @brief LTDC Layer structure definition + */ +typedef struct +{ + uint32_t WindowX0; /*!< Configures the Window Horizontal Start Position. + This parameter must be a number between + Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t WindowX1; /*!< Configures the Window Horizontal Stop Position. + This parameter must be a number between + Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t WindowY0; /*!< Configures the Window vertical Start Position. + This parameter must be a number between + Min_Data = 0x000 and Max_Data = 0x7FF. */ + + uint32_t WindowY1; /*!< Configures the Window vertical Stop Position. + This parameter must be a number between + Min_Data = 0x0000 and Max_Data = 0x7FF. */ + + uint32_t PixelFormat; /*!< Specifies the pixel format. + This parameter can be one of value of @ref LTDC_Pixelformat */ + + uint32_t Alpha; /*!< Specifies the constant alpha used for blending. + This parameter must be a number between + Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint32_t Alpha0; /*!< Configures the default alpha value. + This parameter must be a number between + Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint32_t BlendingFactor1; /*!< Select the blending factor 1. + This parameter can be one of value of @ref LTDC_BlendingFactor1 */ + + uint32_t BlendingFactor2; /*!< Select the blending factor 2. + This parameter can be one of value of @ref LTDC_BlendingFactor2 */ + + uint32_t FBStartAdress; /*!< Configures the color frame buffer address */ + + uint32_t ImageWidth; /*!< Configures the color frame buffer line length. + This parameter must be a number between + Min_Data = 0x0000 and Max_Data = 0x1FFF. */ + + uint32_t ImageHeight; /*!< Specifies the number of line in frame buffer. + This parameter must be a number between + Min_Data = 0x000 and Max_Data = 0x7FF. */ + + LTDC_ColorTypeDef Backcolor; /*!< Configures the layer background color. */ +} LTDC_LayerCfgTypeDef; + +/** + * @brief HAL LTDC State structures definition + */ +typedef enum +{ + HAL_LTDC_STATE_RESET = 0x00U, /*!< LTDC not yet initialized or disabled */ + HAL_LTDC_STATE_READY = 0x01U, /*!< LTDC initialized and ready for use */ + HAL_LTDC_STATE_BUSY = 0x02U, /*!< LTDC internal process is ongoing */ + HAL_LTDC_STATE_TIMEOUT = 0x03U, /*!< LTDC Timeout state */ + HAL_LTDC_STATE_ERROR = 0x04U /*!< LTDC state error */ +} HAL_LTDC_StateTypeDef; + +/** + * @brief LTDC handle Structure definition + */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +typedef struct __LTDC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ +{ + LTDC_TypeDef *Instance; /*!< LTDC Register base address */ + + LTDC_InitTypeDef Init; /*!< LTDC parameters */ + + LTDC_LayerCfgTypeDef LayerCfg[MAX_LAYER]; /*!< LTDC Layers parameters */ + + HAL_LockTypeDef Lock; /*!< LTDC Lock */ + + __IO HAL_LTDC_StateTypeDef State; /*!< LTDC state */ + + __IO uint32_t ErrorCode; /*!< LTDC Error code */ + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + void (* LineEventCallback)(struct __LTDC_HandleTypeDef *hltdc); /*!< LTDC Line Event Callback */ + void (* ReloadEventCallback)(struct __LTDC_HandleTypeDef *hltdc); /*!< LTDC Reload Event Callback */ + void (* ErrorCallback)(struct __LTDC_HandleTypeDef *hltdc); /*!< LTDC Error Callback */ + + void (* MspInitCallback)(struct __LTDC_HandleTypeDef *hltdc); /*!< LTDC Msp Init callback */ + void (* MspDeInitCallback)(struct __LTDC_HandleTypeDef *hltdc); /*!< LTDC Msp DeInit callback */ + +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + + +} LTDC_HandleTypeDef; + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL LTDC Callback ID enumeration definition + */ +typedef enum +{ + HAL_LTDC_MSPINIT_CB_ID = 0x00U, /*!< LTDC MspInit callback ID */ + HAL_LTDC_MSPDEINIT_CB_ID = 0x01U, /*!< LTDC MspDeInit callback ID */ + + HAL_LTDC_LINE_EVENT_CB_ID = 0x02U, /*!< LTDC Line Event Callback ID */ + HAL_LTDC_RELOAD_EVENT_CB_ID = 0x03U, /*!< LTDC Reload Callback ID */ + HAL_LTDC_ERROR_CB_ID = 0x04U /*!< LTDC Error Callback ID */ + +} HAL_LTDC_CallbackIDTypeDef; + +/** + * @brief HAL LTDC Callback pointer definition + */ +typedef void (*pLTDC_CallbackTypeDef)(LTDC_HandleTypeDef *hltdc); /*!< pointer to an LTDC callback function */ + +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LTDC_Exported_Constants LTDC Exported Constants + * @{ + */ + +/** @defgroup LTDC_Error_Code LTDC Error Code + * @{ + */ +#define HAL_LTDC_ERROR_NONE 0x00000000U /*!< LTDC No error */ +#define HAL_LTDC_ERROR_TE 0x00000001U /*!< LTDC Transfer error */ +#define HAL_LTDC_ERROR_FU 0x00000002U /*!< LTDC FIFO Underrun */ +#define HAL_LTDC_ERROR_TIMEOUT 0x00000020U /*!< LTDC Timeout error */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +#define HAL_LTDC_ERROR_INVALID_CALLBACK 0x00000040U /*!< LTDC Invalid Callback error */ +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup LTDC_Layer LTDC Layer + * @{ + */ +#define LTDC_LAYER_1 0x00000000U /*!< LTDC Layer 1 */ +#define LTDC_LAYER_2 0x00000001U /*!< LTDC Layer 2 */ +/** + * @} + */ + +/** @defgroup LTDC_HS_POLARITY LTDC HS POLARITY + * @{ + */ +#define LTDC_HSPOLARITY_AL 0x00000000U /*!< Horizontal Synchronization is active low. */ +#define LTDC_HSPOLARITY_AH LTDC_GCR_HSPOL /*!< Horizontal Synchronization is active high. */ +/** + * @} + */ + +/** @defgroup LTDC_VS_POLARITY LTDC VS POLARITY + * @{ + */ +#define LTDC_VSPOLARITY_AL 0x00000000U /*!< Vertical Synchronization is active low. */ +#define LTDC_VSPOLARITY_AH LTDC_GCR_VSPOL /*!< Vertical Synchronization is active high. */ +/** + * @} + */ + +/** @defgroup LTDC_DE_POLARITY LTDC DE POLARITY + * @{ + */ +#define LTDC_DEPOLARITY_AL 0x00000000U /*!< Data Enable, is active low. */ +#define LTDC_DEPOLARITY_AH LTDC_GCR_DEPOL /*!< Data Enable, is active high. */ +/** + * @} + */ + +/** @defgroup LTDC_PC_POLARITY LTDC PC POLARITY + * @{ + */ +#define LTDC_PCPOLARITY_IPC 0x00000000U /*!< input pixel clock. */ +#define LTDC_PCPOLARITY_IIPC LTDC_GCR_PCPOL /*!< inverted input pixel clock. */ +/** + * @} + */ + +/** @defgroup LTDC_SYNC LTDC SYNC + * @{ + */ +#define LTDC_HORIZONTALSYNC (LTDC_SSCR_HSW >> 16U) /*!< Horizontal synchronization width. */ +#define LTDC_VERTICALSYNC LTDC_SSCR_VSH /*!< Vertical synchronization height. */ +/** + * @} + */ + +/** @defgroup LTDC_BACK_COLOR LTDC BACK COLOR + * @{ + */ +#define LTDC_COLOR 0x000000FFU /*!< Color mask */ +/** + * @} + */ + +/** @defgroup LTDC_BlendingFactor1 LTDC Blending Factor1 + * @{ + */ +#define LTDC_BLENDING_FACTOR1_CA 0x00000400U /*!< Blending factor : Cte Alpha */ +#define LTDC_BLENDING_FACTOR1_PAxCA 0x00000600U /*!< Blending factor : Cte Alpha x Pixel Alpha*/ +/** + * @} + */ + +/** @defgroup LTDC_BlendingFactor2 LTDC Blending Factor2 + * @{ + */ +#define LTDC_BLENDING_FACTOR2_CA 0x00000005U /*!< Blending factor : Cte Alpha */ +#define LTDC_BLENDING_FACTOR2_PAxCA 0x00000007U /*!< Blending factor : Cte Alpha x Pixel Alpha*/ +/** + * @} + */ + +/** @defgroup LTDC_Pixelformat LTDC Pixel format + * @{ + */ +#define LTDC_PIXEL_FORMAT_ARGB8888 0x00000000U /*!< ARGB8888 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_RGB888 0x00000001U /*!< RGB888 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_RGB565 0x00000002U /*!< RGB565 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_ARGB1555 0x00000003U /*!< ARGB1555 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_ARGB4444 0x00000004U /*!< ARGB4444 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_L8 0x00000005U /*!< L8 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_AL44 0x00000006U /*!< AL44 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_AL88 0x00000007U /*!< AL88 LTDC pixel format */ +/** + * @} + */ + +/** @defgroup LTDC_Alpha LTDC Alpha + * @{ + */ +#define LTDC_ALPHA LTDC_LxCACR_CONSTA /*!< LTDC Constant Alpha mask */ +/** + * @} + */ + +/** @defgroup LTDC_LAYER_Config LTDC LAYER Config + * @{ + */ +#define LTDC_STOPPOSITION (LTDC_LxWHPCR_WHSPPOS >> 16U) /*!< LTDC Layer stop position */ +#define LTDC_STARTPOSITION LTDC_LxWHPCR_WHSTPOS /*!< LTDC Layer start position */ + +#define LTDC_COLOR_FRAME_BUFFER LTDC_LxCFBLR_CFBLL /*!< LTDC Layer Line length */ +#define LTDC_LINE_NUMBER LTDC_LxCFBLNR_CFBLNBR /*!< LTDC Layer Line number */ +/** + * @} + */ + +/** @defgroup LTDC_Interrupts LTDC Interrupts + * @{ + */ +#define LTDC_IT_LI LTDC_IER_LIE /*!< LTDC Line Interrupt */ +#define LTDC_IT_FU LTDC_IER_FUIE /*!< LTDC FIFO Underrun Interrupt */ +#define LTDC_IT_TE LTDC_IER_TERRIE /*!< LTDC Transfer Error Interrupt */ +#define LTDC_IT_RR LTDC_IER_RRIE /*!< LTDC Register Reload Interrupt */ +/** + * @} + */ + +/** @defgroup LTDC_Flags LTDC Flags + * @{ + */ +#define LTDC_FLAG_LI LTDC_ISR_LIF /*!< LTDC Line Interrupt Flag */ +#define LTDC_FLAG_FU LTDC_ISR_FUIF /*!< LTDC FIFO Underrun interrupt Flag */ +#define LTDC_FLAG_TE LTDC_ISR_TERRIF /*!< LTDC Transfer Error interrupt Flag */ +#define LTDC_FLAG_RR LTDC_ISR_RRIF /*!< LTDC Register Reload interrupt Flag */ +/** + * @} + */ + +/** @defgroup LTDC_Reload_Type LTDC Reload Type + * @{ + */ +#define LTDC_RELOAD_IMMEDIATE LTDC_SRCR_IMR /*!< Immediate Reload */ +#define LTDC_RELOAD_VERTICAL_BLANKING LTDC_SRCR_VBR /*!< Vertical Blanking Reload */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup LTDC_Exported_Macros LTDC Exported Macros + * @{ + */ + +/** @brief Reset LTDC handle state. + * @param __HANDLE__ LTDC handle + * @retval None + */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +#define __HAL_LTDC_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_LTDC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_LTDC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_LTDC_STATE_RESET) +#endif /*USE_HAL_LTDC_REGISTER_CALLBACKS */ + +/** + * @brief Enable the LTDC. + * @param __HANDLE__ LTDC handle + * @retval None. + */ +#define __HAL_LTDC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->GCR |= LTDC_GCR_LTDCEN) + +/** + * @brief Disable the LTDC. + * @param __HANDLE__ LTDC handle + * @retval None. + */ +#define __HAL_LTDC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->GCR &= ~(LTDC_GCR_LTDCEN)) + +/** + * @brief Enable the LTDC Layer. + * @param __HANDLE__ LTDC handle + * @param __LAYER__ Specify the layer to be enabled. + * This parameter can be LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1). + * @retval None. + */ +#define __HAL_LTDC_LAYER_ENABLE(__HANDLE__, __LAYER__) ((LTDC_LAYER((__HANDLE__), (__LAYER__)))->CR\ + |= (uint32_t)LTDC_LxCR_LEN) + +/** + * @brief Disable the LTDC Layer. + * @param __HANDLE__ LTDC handle + * @param __LAYER__ Specify the layer to be disabled. + * This parameter can be LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1). + * @retval None. + */ +#define __HAL_LTDC_LAYER_DISABLE(__HANDLE__, __LAYER__) ((LTDC_LAYER((__HANDLE__), (__LAYER__)))->CR\ + &= ~(uint32_t)LTDC_LxCR_LEN) + +/** + * @brief Reload immediately all LTDC Layers. + * @param __HANDLE__ LTDC handle + * @retval None. + */ +#define __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(__HANDLE__) ((__HANDLE__)->Instance->SRCR |= LTDC_SRCR_IMR) + +/** + * @brief Reload during vertical blanking period all LTDC Layers. + * @param __HANDLE__ LTDC handle + * @retval None. + */ +#define __HAL_LTDC_VERTICAL_BLANKING_RELOAD_CONFIG(__HANDLE__) ((__HANDLE__)->Instance->SRCR |= LTDC_SRCR_VBR) + +/* Interrupt & Flag management */ +/** + * @brief Get the LTDC pending flags. + * @param __HANDLE__ LTDC handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg LTDC_FLAG_LI: Line Interrupt flag + * @arg LTDC_FLAG_FU: FIFO Underrun Interrupt flag + * @arg LTDC_FLAG_TE: Transfer Error interrupt flag + * @arg LTDC_FLAG_RR: Register Reload Interrupt Flag + * @retval The state of FLAG (SET or RESET). + */ +#define __HAL_LTDC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR & (__FLAG__)) + +/** + * @brief Clears the LTDC pending flags. + * @param __HANDLE__ LTDC handle + * @param __FLAG__ Specify the flag to clear. + * This parameter can be any combination of the following values: + * @arg LTDC_FLAG_LI: Line Interrupt flag + * @arg LTDC_FLAG_FU: FIFO Underrun Interrupt flag + * @arg LTDC_FLAG_TE: Transfer Error interrupt flag + * @arg LTDC_FLAG_RR: Register Reload Interrupt Flag + * @retval None + */ +#define __HAL_LTDC_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enables the specified LTDC interrupts. + * @param __HANDLE__ LTDC handle + * @param __INTERRUPT__ Specify the LTDC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg LTDC_IT_LI: Line Interrupt flag + * @arg LTDC_IT_FU: FIFO Underrun Interrupt flag + * @arg LTDC_IT_TE: Transfer Error interrupt flag + * @arg LTDC_IT_RR: Register Reload Interrupt Flag + * @retval None + */ +#define __HAL_LTDC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disables the specified LTDC interrupts. + * @param __HANDLE__ LTDC handle + * @param __INTERRUPT__ Specify the LTDC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg LTDC_IT_LI: Line Interrupt flag + * @arg LTDC_IT_FU: FIFO Underrun Interrupt flag + * @arg LTDC_IT_TE: Transfer Error interrupt flag + * @arg LTDC_IT_RR: Register Reload Interrupt Flag + * @retval None + */ +#define __HAL_LTDC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified LTDC interrupt has occurred or not. + * @param __HANDLE__ LTDC handle + * @param __INTERRUPT__ Specify the LTDC interrupt source to check. + * This parameter can be one of the following values: + * @arg LTDC_IT_LI: Line Interrupt flag + * @arg LTDC_IT_FU: FIFO Underrun Interrupt flag + * @arg LTDC_IT_TE: Transfer Error interrupt flag + * @arg LTDC_IT_RR: Register Reload Interrupt Flag + * @retval The state of INTERRUPT (SET or RESET). + */ +#define __HAL_LTDC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER & (__INTERRUPT__)) +/** + * @} + */ + +/* Include LTDC HAL Extension module */ +#include "stm32h7rsxx_hal_ltdc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup LTDC_Exported_Functions + * @{ + */ +/** @addtogroup LTDC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_LTDC_Init(LTDC_HandleTypeDef *hltdc); +HAL_StatusTypeDef HAL_LTDC_DeInit(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_MspInit(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_LTDC_RegisterCallback(LTDC_HandleTypeDef *hltdc, HAL_LTDC_CallbackIDTypeDef CallbackID, + pLTDC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_LTDC_UnRegisterCallback(LTDC_HandleTypeDef *hltdc, HAL_LTDC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup LTDC_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +void HAL_LTDC_IRQHandler(LTDC_HandleTypeDef *hltdc); +/** + * @} + */ + +/** @addtogroup LTDC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetWindowSize(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetWindowPosition(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetPixelFormat(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetAlpha(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetAddress(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetPitch(LTDC_HandleTypeDef *hltdc, uint32_t LinePitchInPixels, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ConfigCLUT(LTDC_HandleTypeDef *hltdc, const uint32_t *pCLUT, uint32_t CLUTSize, + uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_EnableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_DisableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_EnableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_DisableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ProgramLineEvent(LTDC_HandleTypeDef *hltdc, uint32_t Line); +HAL_StatusTypeDef HAL_LTDC_EnableDither(LTDC_HandleTypeDef *hltdc); +HAL_StatusTypeDef HAL_LTDC_DisableDither(LTDC_HandleTypeDef *hltdc); +HAL_StatusTypeDef HAL_LTDC_Reload(LTDC_HandleTypeDef *hltdc, uint32_t ReloadType); +HAL_StatusTypeDef HAL_LTDC_ConfigLayer_NoReload(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, + uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetWindowSize_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, + uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetWindowPosition_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, + uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetPixelFormat_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetAlpha_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetAddress_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetPitch_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LinePitchInPixels, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_EnableColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_DisableColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_EnableCLUT_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_DisableCLUT_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); + +/** + * @} + */ + +/** @addtogroup LTDC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_LTDC_StateTypeDef HAL_LTDC_GetState(const LTDC_HandleTypeDef *hltdc); +uint32_t HAL_LTDC_GetError(const LTDC_HandleTypeDef *hltdc); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup LTDC_Private_Macros LTDC Private Macros + * @{ + */ +#define LTDC_LAYER(__HANDLE__, __LAYER__) ((LTDC_Layer_TypeDef *)((uint32_t)(\ + ((uint32_t)((__HANDLE__)->Instance))\ + + 0x84U + (0x80U*(__LAYER__))))) +#define IS_LTDC_LAYER(__LAYER__) ((__LAYER__) < MAX_LAYER) +#define IS_LTDC_HSPOL(__HSPOL__) (((__HSPOL__) == LTDC_HSPOLARITY_AL)\ + || ((__HSPOL__) == LTDC_HSPOLARITY_AH)) +#define IS_LTDC_VSPOL(__VSPOL__) (((__VSPOL__) == LTDC_VSPOLARITY_AL)\ + || ((__VSPOL__) == LTDC_VSPOLARITY_AH)) +#define IS_LTDC_DEPOL(__DEPOL__) (((__DEPOL__) == LTDC_DEPOLARITY_AL)\ + || ((__DEPOL__) == LTDC_DEPOLARITY_AH)) +#define IS_LTDC_PCPOL(__PCPOL__) (((__PCPOL__) == LTDC_PCPOLARITY_IPC)\ + || ((__PCPOL__) == LTDC_PCPOLARITY_IIPC)) +#define IS_LTDC_HSYNC(__HSYNC__) ((__HSYNC__) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_VSYNC(__VSYNC__) ((__VSYNC__) <= LTDC_VERTICALSYNC) +#define IS_LTDC_AHBP(__AHBP__) ((__AHBP__) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_AVBP(__AVBP__) ((__AVBP__) <= LTDC_VERTICALSYNC) +#define IS_LTDC_AAW(__AAW__) ((__AAW__) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_AAH(__AAH__) ((__AAH__) <= LTDC_VERTICALSYNC) +#define IS_LTDC_TOTALW(__TOTALW__) ((__TOTALW__) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_TOTALH(__TOTALH__) ((__TOTALH__) <= LTDC_VERTICALSYNC) +#define IS_LTDC_BLUEVALUE(__BBLUE__) ((__BBLUE__) <= LTDC_COLOR) +#define IS_LTDC_GREENVALUE(__BGREEN__) ((__BGREEN__) <= LTDC_COLOR) +#define IS_LTDC_REDVALUE(__BRED__) ((__BRED__) <= LTDC_COLOR) +#define IS_LTDC_BLENDING_FACTOR1(__BLENDING_FACTOR1__) (((__BLENDING_FACTOR1__) == LTDC_BLENDING_FACTOR1_CA) || \ + ((__BLENDING_FACTOR1__) == LTDC_BLENDING_FACTOR1_PAxCA)) +#define IS_LTDC_BLENDING_FACTOR2(__BLENDING_FACTOR1__) (((__BLENDING_FACTOR1__) == LTDC_BLENDING_FACTOR2_CA) || \ + ((__BLENDING_FACTOR1__) == LTDC_BLENDING_FACTOR2_PAxCA)) +#define IS_LTDC_PIXEL_FORMAT(__PIXEL_FORMAT__) (((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_ARGB8888) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_RGB888) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_RGB565) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_ARGB1555) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_ARGB4444) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_L8) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_AL44) || \ + ((__PIXEL_FORMAT__) == LTDC_PIXEL_FORMAT_AL88)) +#define IS_LTDC_ALPHA(__ALPHA__) ((__ALPHA__) <= LTDC_ALPHA) +#define IS_LTDC_HCONFIGST(__HCONFIGST__) ((__HCONFIGST__) <= LTDC_STARTPOSITION) +#define IS_LTDC_HCONFIGSP(__HCONFIGSP__) ((__HCONFIGSP__) <= LTDC_STOPPOSITION) +#define IS_LTDC_VCONFIGST(__VCONFIGST__) ((__VCONFIGST__) <= LTDC_STARTPOSITION) +#define IS_LTDC_VCONFIGSP(__VCONFIGSP__) ((__VCONFIGSP__) <= LTDC_STOPPOSITION) +#define IS_LTDC_CFBP(__CFBP__) ((__CFBP__) <= LTDC_COLOR_FRAME_BUFFER) +#define IS_LTDC_CFBLL(__CFBLL__) ((__CFBLL__) <= LTDC_COLOR_FRAME_BUFFER) +#define IS_LTDC_CFBLNBR(__CFBLNBR__) ((__CFBLNBR__) <= LTDC_LINE_NUMBER) +#define IS_LTDC_LIPOS(__LIPOS__) ((__LIPOS__) <= 0x7FFU) +#define IS_LTDC_RELOAD(__RELOADTYPE__) (((__RELOADTYPE__) == LTDC_RELOAD_IMMEDIATE) || \ + ((__RELOADTYPE__) == LTDC_RELOAD_VERTICAL_BLANKING)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup LTDC_Private_Functions LTDC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* LTDC */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_LTDC_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc_ex.h new file mode 100644 index 0000000..e13ac63 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_ltdc_ex.h @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_ltdc_ex.h + * @author MCD Application Team + * @brief Header file of LTDC HAL Extension 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 STM32H7RSxx_HAL_LTDC_EX_H +#define STM32H7RSxx_HAL_LTDC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +#if defined(HAL_LTDC_MODULE_ENABLED) && defined(HAL_DSI_MODULE_ENABLED) + +#if defined (LTDC) && defined (DSI) + +#include "stm32h7rsxx_hal_dsi.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup LTDCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup LTDCEx_Exported_Functions + * @{ + */ + +/** @addtogroup LTDCEx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_LTDCEx_StructInitFromVideoConfig(LTDC_HandleTypeDef *hltdc, DSI_VidCfgTypeDef *VidCfg); +HAL_StatusTypeDef HAL_LTDCEx_StructInitFromAdaptedCommandConfig(LTDC_HandleTypeDef *hltdc, DSI_CmdCfgTypeDef *CmdCfg); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* LTDC && DSI */ + +#endif /* HAL_LTCD_MODULE_ENABLED && HAL_DSI_MODULE_ENABLED */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_LTDC_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_mdf.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_mdf.h new file mode 100644 index 0000000..b741ae0 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_mdf.h @@ -0,0 +1,781 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_mdf.h + * @author MCD Application Team + * @brief Header file of MDF 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 STM32H7RSxx_HAL_MDF_H +#define STM32H7RSxx_HAL_MDF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup MDF + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup MDF_Exported_Types MDF Exported Types + * @{ + */ + +/** + * @brief HAL MDF states definition + */ +typedef enum +{ + HAL_MDF_STATE_RESET = 0x00U, /*!< MDF not initialized */ + HAL_MDF_STATE_READY = 0x01U, /*!< MDF initialized and ready for use */ + HAL_MDF_STATE_ACQUISITION = 0x02U, /*!< MDF acquisition in progress */ + HAL_MDF_STATE_ERROR = 0xFFU /*!< MDF state error */ +} HAL_MDF_StateTypeDef; + +/** + * @brief MDF clock trigger structure definition + */ +typedef struct +{ + FunctionalState Activation; /*!< Output clock trigger enable/disable */ + uint32_t Source; /*!< Output clock trigger source. + This parameter can be a value of @ref MDF_ClockTriggerSource */ + uint32_t Edge; /*!< Output clock trigger edge. + This parameter can be a value of @ref MDF_ClockTriggerEdge */ +} MDF_ClockTriggerTypeDef; + +/** + * @brief MDF output clock structure definition + */ +typedef struct +{ + FunctionalState Activation; /*!< Output clock enable/disable */ + uint32_t Pins; /*!< Output clock pins. + This parameter can be a value of @ref MDF_OuputClockPins */ + uint32_t Divider; /*!< Output clock divider. + This parameter must be a number between Min_Data = 1 and Max_Data = 16 */ + MDF_ClockTriggerTypeDef Trigger; /*!< Output clock trigger parameters */ +} MDF_OutputClockTypeDef; + +/** + * @brief MDF common parameters structure definition + */ +typedef struct +{ + uint32_t ProcClockDivider; /*!< Processing clock divider. + This parameter must be a number between Min_Data = 1 + and Max_Data = 128 */ + MDF_OutputClockTypeDef OutputClock; /*!< Output clock parameters */ +} MDF_CommonParamTypeDef; + +/** + * @brief MDF serial interface structure definition + */ +typedef struct +{ + FunctionalState Activation; /*!< Serial interface enable/disable */ + uint32_t Mode; /*!< Serial interface mode. + This parameter can be a value of @ref MDF_SitfMode */ + uint32_t ClockSource; /*!< Serial interface clock source. + This parameter can be a value of @ref MDF_SitfClockSource */ + uint32_t Threshold; /*!< SPI threshold for clock absence detection or Manchester symbol threshold. + This parameter must be a number between Min_Data = 4 and Max_Data = 31 */ +} MDF_SerialInterfaceTypeDef; + +/** + * @brief MDF init structure definition + */ +typedef struct +{ + MDF_CommonParamTypeDef CommonParam; /*!< MDF common parameters */ + MDF_SerialInterfaceTypeDef SerialInterface; /*!< MDF serial interface parameters */ + uint32_t FilterBistream; /*!< MDF filter bitstream selection. + This parameter can be a value of @ref MDF_FilterBitstream */ +} MDF_InitTypeDef; + +/** + * @brief MDF handle structure definition + */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +typedef struct __MDF_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +{ + MDF_Filter_TypeDef *Instance; /*!< MDF instance */ + MDF_InitTypeDef Init; /*!< MDF init parameters */ + DMA_HandleTypeDef *hdma; /*!< Pointer on DMA handler for acquisitions */ + __IO HAL_MDF_StateTypeDef State; /*!< MDF state */ + __IO uint32_t ErrorCode; /*!< MDF error code */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + void (*AcqCpltCallback)(struct __MDF_HandleTypeDef *hmdf); /*!< MDF acquisition complete callback */ + void (*AcqHalfCpltCallback)(struct __MDF_HandleTypeDef *hmdf); /*!< MDF acquisition half complete callback */ + void (*SndLvCallback)(struct __MDF_HandleTypeDef *hmdf, + uint32_t SoundLevel, + uint32_t AmbientNoise); /*!< MDF sound level callback */ + void (*SadCallback)(struct __MDF_HandleTypeDef *hmdf); /*!< MDF sound activity detector callback */ + void (*ErrorCallback)(struct __MDF_HandleTypeDef *hmdf); /*!< MDF error callback */ + void (*MspInitCallback)(struct __MDF_HandleTypeDef *hmdf); /*!< MDF MSP init callback */ + void (*MspDeInitCallback)(struct __MDF_HandleTypeDef *hmdf); /*!< MDF MSP de-init callback */ +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +} MDF_HandleTypeDef; + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +/** + * @brief MDF callback ID enumeration definition + */ +typedef enum +{ + HAL_MDF_ACQ_COMPLETE_CB_ID = 0x01U, /*!< MDF acquisition complete callback ID */ + HAL_MDF_ACQ_HALFCOMPLETE_CB_ID = 0x02U, /*!< MDF acquisition half complete callback ID */ + HAL_MDF_SNDLVL_CB_ID = 0x03U, /*!< MDF sound level callback ID */ + HAL_MDF_SAD_CB_ID = 0x04U, /*!< MDF sound activity detector callback ID */ + HAL_MDF_ERROR_CB_ID = 0x05U, /*!< MDF error callback ID */ + HAL_MDF_MSPINIT_CB_ID = 0x06U, /*!< MDF MSP init callback ID */ + HAL_MDF_MSPDEINIT_CB_ID = 0x07U /*!< MDF MSP de-init callback ID */ +} HAL_MDF_CallbackIDTypeDef; + +/** + * @brief MDF callback pointers definition + */ +typedef void (*pMDF_CallbackTypeDef)(MDF_HandleTypeDef *hmdf); +typedef void (*pMDF_SndLvlCallbackTypeDef)(MDF_HandleTypeDef *hmdf, uint32_t SoundLevel, uint32_t AmbientNoise); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + +/** + * @brief MDF reshape filter structure definition + */ +typedef struct +{ + FunctionalState Activation; /*!< Reshape filter enable/disable */ + uint32_t DecimationRatio; /*!< Reshape filter decimation ratio. + This parameter can be a value of @ref MDF_ReshapeDecimationRatio */ +} MDF_ReshapeFilterTypeDef; + +/** + * @brief MDF high pass filter structure definition + */ +typedef struct +{ + FunctionalState Activation; /*!< High pass filter enable/disable */ + uint32_t CutOffFrequency; /*!< High pass filter cut-off frequency. + This parameter can be a value of @ref MDF_HighPassCutOffFreq */ +} MDF_HighPassFilterTypeDef; + +/** + * @brief MDF sound activity structure definition + */ +typedef struct +{ + FunctionalState Activation; /*!< Sound activity detector enable/disable */ + uint32_t Mode; /*!< Sound activity detector mode. + This parameter can be a value of @ref MDF_SadMode */ + uint32_t FrameSize; /*!< Size of one frame to compute short-term signal level. + This parameter can be a value of @ref MDF_SadFrameSize */ + FunctionalState Hysteresis; /*!< Hysteresis enable/disable. + @note This parameter is not used if Mode is set + to MDF_SAD_AMBIENT_NOISE_ESTIMATOR */ + uint32_t SoundTriggerEvent; /*!< Sound trigger event configuration. + This parameter can be a value of @ref MDF_SadSoundTriggerEvent */ + uint32_t DataMemoryTransfer; /*!< Data memory transfer mode. + This parameter can be a value of @ref MDF_SadDataMemoryTransfer */ + uint32_t MinNoiseLevel; /*!< Minimum noise level. + This parameter must be a number between Min_Data = 0 + and Max_Data = 8191 */ + uint32_t HangoverWindow; /*!< Hangover time window in frames. + This parameter can be a value of @ref MDF_SadHangoverWindow */ + uint32_t LearningFrames; /*!< Number of learning frames for the first estimation of noise level. + This parameter can be a value of @ref MDF_SadLearningFrames */ + uint32_t AmbientNoiseSlope; /*!< Ambient noise slope control. + This parameter must be a number between Min_Data = 0 and Max_Data = 7. + @note This parameter is not used if Mode is set + to MDF_SAD_SOUND_DETECTOR */ + uint32_t SignalNoiseThreshold; /*!< Signal to noise threshold. + This parameter can be a value of @ref MDF_SadSignalNoiseThreshold */ + FunctionalState SoundLevelInterrupt; /*!< Sound level interrupt enable/disable. + @note This interrupt is mainly used for debug purpose */ +} MDF_SoundActivityTypeDef; + +/** + * @brief MDF filter trigger structure definition + */ +typedef struct +{ + uint32_t Source; /*!< Filter trigger source. + This parameter can be a value of @ref MDF_FilterTriggerSource */ + uint32_t Edge; /*!< Filter trigger edge. + This parameter can be a value of @ref MDF_FilterTriggerEdge */ +} MDF_FilterTriggerTypeDef; + +/** + * @brief MDF filter configuration structure definition + */ +typedef struct +{ + uint32_t DataSource; /*!< Filter data source. + This parameter can be a value of @ref MDF_DataSource */ + uint32_t Delay; /*!< Delay to apply on data source in number of samples. + This parameter must be a number between Min_Data = 0 + and Max_Data = 127 */ + uint32_t CicMode; /*!< CIC filter mode. + This parameter can be a value of @ref MDF_CicMode */ + uint32_t DecimationRatio; /*!< Filter decimation ratio. + This parameter must be a number between Min_Data = 2 + and Max_Data = 512 */ + int32_t Gain; /*!< Filter gain in step of around 3db (from -48db to 72dB). + This parameter must be a number between Min_Data = -16 + and Max_Data = 24 */ + MDF_ReshapeFilterTypeDef ReshapeFilter; /*!< Reshape filter configuration */ + MDF_HighPassFilterTypeDef HighPassFilter; /*!< High pass filter configuration */ + MDF_SoundActivityTypeDef SoundActivity; /*!< Sound activity detector configuration */ + uint32_t AcquisitionMode; /*!< Filter acquisition mode. + This parameter can be a value of @ref MDF_AcquisitionMode */ + uint32_t FifoThreshold; /*!< Filter RXFIFO threshold. + This parameter can be a value of @ref MDF_FifoThreshold */ + uint32_t DiscardSamples; /*!< Number of samples to discard after filter enable. + This parameter must be a number between Min_Data = 0 + and Max_Data = 255 */ + MDF_FilterTriggerTypeDef Trigger; /*!< Filter trigger configuration. + @note This parameter is not used if AcquisitionMode is set + to MDF_MODE_ASYNC_CONT or MDF_MODE_ASYNC_SINGLE */ +} MDF_FilterConfigTypeDef; + +/** + * @brief MDF DMA configuration structure definition + */ +typedef struct +{ + uint32_t Address; /*!< DMA destination address */ + uint32_t DataLength; /*!< Length of data to transfer in bytes */ + FunctionalState MsbOnly; /*!< Transfer only the 16MSB of the acquistion data */ +} MDF_DmaConfigTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup MDF_Exported_Constants MDF Exported Constants + * @{ + */ + +/** @defgroup MDF_ErrorCode MDF error code + * @{ + */ +#define MDF_ERROR_NONE 0x00000000U /*!< No error */ +#define MDF_ERROR_ACQUISITION_OVERFLOW 0x00000001U /*!< Overflow occurs during acquisition */ +#define MDF_ERROR_RSF_OVERRUN 0x00000002U /*!< Overrun occurs on reshape filter */ +#define MDF_ERROR_CLOCK_ABSENCE 0x00000004U /*!< Clock absence detection occurs */ +#define MDF_ERROR_SATURATION 0x00000010U /*!< Saturation detection occurs */ +#define MDF_ERROR_DMA 0x00000040U /*!< DMA error occurs */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +#define MDF_ERROR_INVALID_CALLBACK 0x00000080U /*!< Invalid callback error occurs */ +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup MDF_ClockTriggerSource MDF output clock trigger source + * @{ + */ +#define MDF_CLOCK_TRIG_TRGO 0x00000000U +#define MDF_CLOCK_TRIG_EXTI15 MDF_CKGCR_TRGSRC_1 +/** + * @} + */ + +/** @defgroup MDF_ClockTriggerEdge MDF output clock trigger edge + * @{ + */ +#define MDF_CLOCK_TRIG_RISING_EDGE 0x00000000U /*!< Rising edge */ +#define MDF_CLOCK_TRIG_FALLING_EDGE MDF_CKGCR_TRGSENS /*!< Falling edge */ +/** + * @} + */ + +/** @defgroup MDF_OuputClockPins MDF output clock pins + * @{ + */ +#define MDF_OUTPUT_CLOCK_0 MDF_CKGCR_CCK0DIR /*!< MDF_CCK0 is used as output clock */ +#define MDF_OUTPUT_CLOCK_1 MDF_CKGCR_CCK1DIR /*!< MDF_CCK1 is used as output clock */ +#define MDF_OUTPUT_CLOCK_ALL (MDF_CKGCR_CCK0DIR | \ + MDF_CKGCR_CCK1DIR) /*!< MDF_CCK0 and MDF_CCK1 are used as output clock */ +/** + * @} + */ + +/** @defgroup MDF_SitfMode MDF serial interface mode + * @{ + */ +#define MDF_SITF_LF_MASTER_SPI_MODE 0x00000000U /*!< Low frequency master SPI mode */ +#define MDF_SITF_NORMAL_SPI_MODE MDF_SITFCR_SITFMOD_0 /*!< Normal SPI mode */ +#define MDF_SITF_MANCHESTER_FALLING_MODE MDF_SITFCR_SITFMOD_1 /*!< Manchester mode rising edge logic 0 + and falling edge logic 1 */ +#define MDF_SITF_MANCHESTER_RISING_MODE MDF_SITFCR_SITFMOD /*!< Manchester mode rising edge logic 1 + and falling edge logic 0 */ +/** + * @} + */ + +/** @defgroup MDF_SitfClockSource MDF serial interface clock source + * @{ + */ +#define MDF_SITF_CCK0_SOURCE 0x00000000U /*!< Common clock 0 source */ +#define MDF_SITF_CCK1_SOURCE MDF_SITFCR_SCKSRC_0 /*!< Common clock 1 source */ +/** + * @} + */ + +/** @defgroup MDF_FilterBitstream MDF filter bitstream + * @{ + */ +#define MDF_BITSTREAM0_RISING 0x00000000U +#define MDF_BITSTREAM0_FALLING MDF_BSMXCR_BSSEL_0 +/** + * @} + */ + +/** @defgroup MDF_ReshapeDecimationRatio MDF reshape filter decimation ratio + * @{ + */ +#define MDF_RSF_DECIMATION_RATIO_4 0x00000000U /*!< Reshape filter decimation ratio is 4 */ +#define MDF_RSF_DECIMATION_RATIO_1 MDF_DFLTRSFR_RSFLTD /*!< Reshape filter decimation ratio is 1 */ +/** + * @} + */ + +/** @defgroup MDF_HighPassCutOffFreq MDF high pass filter cut-off frequency + * @{ + */ +#define MDF_HPF_CUTOFF_0_000625FPCM 0x00000000U /*!< Cut-off frequency of 0.000625xFpcm */ +#define MDF_HPF_CUTOFF_0_00125FPCM MDF_DFLTRSFR_HPFC_0 /*!< Cut-off frequency of 0.00125xFpcm */ +#define MDF_HPF_CUTOFF_0_0025FPCM MDF_DFLTRSFR_HPFC_1 /*!< Cut-off frequency of 0.0025xFpcm */ +#define MDF_HPF_CUTOFF_0_0095FPCM MDF_DFLTRSFR_HPFC /*!< Cut-off frequency of 0.0095xFpcm */ +/** + * @} + */ + +/** @defgroup MDF_SadMode MDF sound activity detector mode + * @{ + */ +#define MDF_SAD_VOICE_ACTIVITY_DETECTOR 0x00000000U /*!< Voice activity detector */ +#define MDF_SAD_SOUND_DETECTOR MDF_SADCR_SADMOD_0 /*!< Sound detector */ +#define MDF_SAD_AMBIENT_NOISE_DETECTOR MDF_SADCR_SADMOD /*!< Ambient noise detector */ +/** + * @} + */ + +/** @defgroup MDF_SadFrameSize MDF sound activity detector frame size + * @{ + */ +#define MDF_SAD_8_PCM_SAMPLES 0x00000000U /*!< Frame size of 8 PCM samples */ +#define MDF_SAD_16_PCM_SAMPLES MDF_SADCR_FRSIZE_0 /*!< Frame size of 16 PCM samples */ +#define MDF_SAD_32_PCM_SAMPLES MDF_SADCR_FRSIZE_1 /*!< Frame size of 32 PCM samples */ +#define MDF_SAD_64_PCM_SAMPLES (MDF_SADCR_FRSIZE_0 | MDF_SADCR_FRSIZE_1) /*!< Frame size of 64 PCM samples */ +#define MDF_SAD_128_PCM_SAMPLES MDF_SADCR_FRSIZE_2 /*!< Frame size of 128 PCM samples */ +#define MDF_SAD_256_PCM_SAMPLES (MDF_SADCR_FRSIZE_0 | MDF_SADCR_FRSIZE_2) /*!< Frame size of 256 PCM samples */ +#define MDF_SAD_512_PCM_SAMPLES MDF_SADCR_FRSIZE /*!< Frame size of 512 PCM samples */ +/** + * @} + */ + +/** @defgroup MDF_SadSoundTriggerEvent MDF sound activity detector trigger event + * @{ + */ +#define MDF_SAD_ENTER_DETECT 0x00000000U /*!< Event when SAD enters in detect state */ +#define MDF_SAD_ENTER_EXIT_DETECT MDF_SADCR_DETCFG /*!< Event when SAD enters or exits from detect state */ +/** + * @} + */ + +/** @defgroup MDF_SadDataMemoryTransfer MDF sound activity detector data memory transfer mode + * @{ + */ +#define MDF_SAD_NO_MEMORY_TRANSFER 0x00000000U /*!< No memory transfer */ +#define MDF_SAD_MEMORY_TRANSFER_IN_DETECT MDF_SADCR_DATCAP_0 /*!< Memory transfer only in detect state */ +#define MDF_SAD_MEMORY_TRANSFER_ALWAYS MDF_SADCR_DATCAP /*!< Memory transfer always */ +/** + * @} + */ + +/** @defgroup MDF_SadHangoverWindow MDF sound activity detector data hangover time window + * @{ + */ +#define MDF_SAD_HANGOVER_4_FRAMES 0x00000000U /*!< Hangover window of 4 frames */ +#define MDF_SAD_HANGOVER_8_FRAMES MDF_SADCFGR_HGOVR_0 /*!< Hangover window of 8 frames */ +#define MDF_SAD_HANGOVER_16_FRAMES MDF_SADCFGR_HGOVR_1 /*!< Hangover window of 16 frames */ +#define MDF_SAD_HANGOVER_32_FRAMES (MDF_SADCFGR_HGOVR_0 | \ + MDF_SADCFGR_HGOVR_1) /*!< Hangover window of 32 frames */ +#define MDF_SAD_HANGOVER_64_FRAMES MDF_SADCFGR_HGOVR_2 /*!< Hangover window of 64 frames */ +#define MDF_SAD_HANGOVER_128_FRAMES (MDF_SADCFGR_HGOVR_0 | \ + MDF_SADCFGR_HGOVR_2) /*!< Hangover window of 128 frames */ +#define MDF_SAD_HANGOVER_256_FRAMES (MDF_SADCFGR_HGOVR_1 | \ + MDF_SADCFGR_HGOVR_2) /*!< Hangover window of 256 frames */ +#define MDF_SAD_HANGOVER_512_FRAMES (MDF_SADCFGR_HGOVR_0 | \ + MDF_SADCFGR_HGOVR_1 | \ + MDF_SADCFGR_HGOVR_2) /*!< Hangover window of 512 frames */ +/** + * @} + */ + +/** @defgroup MDF_SadLearningFrames MDF sound activity detector data learning frames + * @{ + */ +#define MDF_SAD_LEARNING_2_FRAMES 0x00000000U /*!< 2 learning frames */ +#define MDF_SAD_LEARNING_4_FRAMES MDF_SADCFGR_LFRNB_0 /*!< 4 learning frames */ +#define MDF_SAD_LEARNING_8_FRAMES MDF_SADCFGR_LFRNB_1 /*!< 8 learning frames */ +#define MDF_SAD_LEARNING_16_FRAMES (MDF_SADCFGR_LFRNB_0 | MDF_SADCFGR_LFRNB_1) /*!< 16 learning frames */ +#define MDF_SAD_LEARNING_32_FRAMES MDF_SADCFGR_LFRNB /*!< 32 learning frames */ +/** + * @} + */ + +/** @defgroup MDF_SadSignalNoiseThreshold MDF sound activity detector data signal to noise threshold + * @{ + */ +#define MDF_SAD_SIGNAL_NOISE_3_5DB 0x00000000U /*!< Signal to noise threshold is 3.5dB */ +#define MDF_SAD_SIGNAL_NOISE_6DB MDF_SADCFGR_SNTHR_0 /*!< Signal to noise threshold is 6dB */ +#define MDF_SAD_SIGNAL_NOISE_9_5DB MDF_SADCFGR_SNTHR_1 /*!< Signal to noise threshold is 9.5dB */ +#define MDF_SAD_SIGNAL_NOISE_12DB (MDF_SADCFGR_SNTHR_0 | \ + MDF_SADCFGR_SNTHR_1) /*!< Signal to noise threshold is 12dB */ +#define MDF_SAD_SIGNAL_NOISE_15_6DB MDF_SADCFGR_SNTHR_2 /*!< Signal to noise threshold is 15.6dB */ +#define MDF_SAD_SIGNAL_NOISE_18DB (MDF_SADCFGR_SNTHR_0 | \ + MDF_SADCFGR_SNTHR_2) /*!< Signal to noise threshold is 18dB */ +#define MDF_SAD_SIGNAL_NOISE_21_6DB (MDF_SADCFGR_SNTHR_1 | \ + MDF_SADCFGR_SNTHR_2) /*!< Signal to noise threshold is 21.6dB */ +#define MDF_SAD_SIGNAL_NOISE_24_1DB (MDF_SADCFGR_SNTHR_0 | \ + MDF_SADCFGR_SNTHR_1 | \ + MDF_SADCFGR_SNTHR_2) /*!< Signal to noise threshold is 24.1dB */ +#define MDF_SAD_SIGNAL_NOISE_27_6DB MDF_SADCFGR_SNTHR_3 /*!< Signal to noise threshold is 27.6dB */ +#define MDF_SAD_SIGNAL_NOISE_30_1DB (MDF_SADCFGR_SNTHR_0 | \ + MDF_SADCFGR_SNTHR_3) /*!< Signal to noise threshold is 30.1dB */ +/** + * @} + */ + +/** @defgroup MDF_FilterTriggerSource MDF filter trigger source + * @{ + */ +#define MDF_FILTER_TRIG_TRGO 0x00000000U +#define MDF_FILTER_TRIG_EXTI15 MDF_DFLTCR_TRGSRC_1 +/** + * @} + */ + +/** @defgroup MDF_FilterTriggerEdge MDF filter trigger edge + * @{ + */ +#define MDF_FILTER_TRIG_RISING_EDGE 0x00000000U /*!< Rising edge */ +#define MDF_FILTER_TRIG_FALLING_EDGE MDF_DFLTCR_TRGSENS /*!< Falling edge */ +/** + * @} + */ + +/** @defgroup MDF_DataSource MDF data source + * @{ + */ +#define MDF_DATA_SOURCE_BSMX 0x00000000U /*!< Data from bitstream matrix */ +#define MDF_DATA_SOURCE_ADCITF1 MDF_DFLTCICR_DATSRC_1 /*!< Data from ADC interface 1 */ +#define MDF_DATA_SOURCE_ADCITF2 MDF_DFLTCICR_DATSRC /*!< Data from ADC interface 2 */ +/** + * @} + */ + +/** @defgroup MDF_CicMode MDF CIC mode + * @{ + */ +#define MDF_ONE_FILTER_SINC4 MDF_DFLTCICR_CICMOD_2 /*!< One filter in Sinc4 order */ +#define MDF_ONE_FILTER_SINC5 (MDF_DFLTCICR_CICMOD_0 | \ + MDF_DFLTCICR_CICMOD_2) /*!< One filter in Sinc5 order */ +/** + * @} + */ + +/** @defgroup MDF_AcquisitionMode MDF acquisition mode + * @{ + */ +#define MDF_MODE_ASYNC_CONT 0x00000000U /*!< Asynchronous, continuous acquisition mode */ +#define MDF_MODE_ASYNC_SINGLE MDF_DFLTCR_ACQMOD_0 /*!< Asynchronous, single-shot acquisition mode. + @note Not available with SAD usage */ +#define MDF_MODE_SYNC_CONT MDF_DFLTCR_ACQMOD_1 /*!< Synchronous, continuous acquisition mode */ +#define MDF_MODE_SYNC_SINGLE (MDF_DFLTCR_ACQMOD_0 | \ + MDF_DFLTCR_ACQMOD_1) /*!< Synchronous, single-shot acquisition mode. + @note Not available with SAD usage */ +#define MDF_MODE_WINDOW_CONT MDF_DFLTCR_ACQMOD_2 /*!< Window, continuous acquisition mode. + @note Not available with SAD usage */ +/** + * @} + */ + +/** @defgroup MDF_FifoThreshold MDF RXFIFO threshold + * @{ + */ +#define MDF_FIFO_THRESHOLD_NOT_EMPTY 0x00000000U /*!< Event generated when RXFIFO is not empty */ +#define MDF_FIFO_THRESHOLD_HALF_FULL MDF_DFLTCR_FTH /*!< Event generated when RXFIFO is half_full */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup MDF_Exported_Macros MDF Exported Macros + * @{ + */ + +/** @brief Reset MDF handle state. + * @param __HANDLE__ MDF handle. + * @retval None + */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +#define __HAL_MDF_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_MDF_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ +#define __HAL_MDF_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_MDF_STATE_RESET) +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup MDF_Exported_Functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +/** @addtogroup MDF_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_MDF_Init(MDF_HandleTypeDef *hmdf); +HAL_StatusTypeDef HAL_MDF_DeInit(MDF_HandleTypeDef *hmdf); +void HAL_MDF_MspInit(MDF_HandleTypeDef *hmdf); +void HAL_MDF_MspDeInit(MDF_HandleTypeDef *hmdf); +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_MDF_RegisterCallback(MDF_HandleTypeDef *hmdf, + HAL_MDF_CallbackIDTypeDef CallbackID, + pMDF_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_MDF_UnRegisterCallback(MDF_HandleTypeDef *hmdf, + HAL_MDF_CallbackIDTypeDef CallbackID); +HAL_StatusTypeDef HAL_MDF_RegisterSndLvlCallback(MDF_HandleTypeDef *hmdf, + pMDF_SndLvlCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_MDF_UnRegisterSndLvlCallback(MDF_HandleTypeDef *hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Acquisition functions *****************************************************/ +/** @addtogroup MDF_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_MDF_AcqStart(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig); +HAL_StatusTypeDef HAL_MDF_PollForAcq(MDF_HandleTypeDef *hmdf, uint32_t Timeout); +HAL_StatusTypeDef HAL_MDF_GetAcqValue(const MDF_HandleTypeDef *hmdf, int32_t *pValue); +HAL_StatusTypeDef HAL_MDF_AcqStop(MDF_HandleTypeDef *hmdf); +HAL_StatusTypeDef HAL_MDF_AcqStart_IT(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig); +HAL_StatusTypeDef HAL_MDF_AcqStop_IT(MDF_HandleTypeDef *hmdf); +HAL_StatusTypeDef HAL_MDF_AcqStart_DMA(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig, + const MDF_DmaConfigTypeDef *pDmaConfig); +HAL_StatusTypeDef HAL_MDF_AcqStop_DMA(MDF_HandleTypeDef *hmdf); +HAL_StatusTypeDef HAL_MDF_GenerateTrgo(const MDF_HandleTypeDef *hmdf); +HAL_StatusTypeDef HAL_MDF_SetDelay(MDF_HandleTypeDef *hmdf, uint32_t Delay); +HAL_StatusTypeDef HAL_MDF_GetDelay(const MDF_HandleTypeDef *hmdf, uint32_t *pDelay); +HAL_StatusTypeDef HAL_MDF_SetGain(MDF_HandleTypeDef *hmdf, int32_t Gain); +HAL_StatusTypeDef HAL_MDF_GetGain(const MDF_HandleTypeDef *hmdf, int32_t *pGain); +HAL_StatusTypeDef HAL_MDF_PollForSndLvl(MDF_HandleTypeDef *hmdf, uint32_t Timeout, uint32_t *pSoundLevel, + uint32_t *pAmbientNoise); +HAL_StatusTypeDef HAL_MDF_PollForSad(MDF_HandleTypeDef *hmdf, uint32_t Timeout); +void HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf); +void HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf); +void HAL_MDF_SndLvlCallback(MDF_HandleTypeDef *hmdf, uint32_t SoundLevel, uint32_t AmbientNoise); +void HAL_MDF_SadCallback(MDF_HandleTypeDef *hmdf); +/** + * @} + */ + +/* Clock absence detection functions *****************************************/ +/** @addtogroup MDF_Exported_Functions_Group3 + * @{ + */ +HAL_StatusTypeDef HAL_MDF_PollForCkab(MDF_HandleTypeDef *hmdf, uint32_t Timeout); +HAL_StatusTypeDef HAL_MDF_CkabStart_IT(MDF_HandleTypeDef *hmdf); +HAL_StatusTypeDef HAL_MDF_CkabStop_IT(MDF_HandleTypeDef *hmdf); +/** + * @} + */ + +/* Generic functions *********************************************************/ +/** @addtogroup MDF_Exported_Functions_Group4 + * @{ + */ +void HAL_MDF_IRQHandler(MDF_HandleTypeDef *hmdf); +void HAL_MDF_ErrorCallback(MDF_HandleTypeDef *hmdf); +HAL_MDF_StateTypeDef HAL_MDF_GetState(const MDF_HandleTypeDef *hmdf); +uint32_t HAL_MDF_GetError(const MDF_HandleTypeDef *hmdf); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup MDF_Private_Macros MDF Private Macros + * @{ + */ +#define IS_MDF_FILTER_BITSTREAM(PARAM) (((PARAM) == MDF_BITSTREAM0_RISING) || \ + ((PARAM) == MDF_BITSTREAM0_FALLING)) + +#define IS_MDF_PROC_CLOCK_DIVIDER(PARAM) ((1U <= (PARAM)) && ((PARAM) <= 128U)) + +#define IS_MDF_OUTPUT_CLOCK_PINS(PARAM) (((PARAM) == MDF_OUTPUT_CLOCK_0) || \ + ((PARAM) == MDF_OUTPUT_CLOCK_1) || \ + ((PARAM) == MDF_OUTPUT_CLOCK_ALL)) + +#define IS_MDF_OUTPUT_CLOCK_DIVIDER(PARAM) ((1U <= (PARAM)) && ((PARAM) <= 16U)) + +#define IS_MDF_OUTPUT_CLOCK_TRIGGER_SOURCE(PARAM) (((PARAM) == MDF_CLOCK_TRIG_TRGO) || \ + ((PARAM) == MDF_CLOCK_TRIG_EXTI15)) + +#define IS_MDF_OUTPUT_CLOCK_TRIGGER_EDGE(PARAM) (((PARAM) == MDF_CLOCK_TRIG_RISING_EDGE) || \ + ((PARAM) == MDF_CLOCK_TRIG_FALLING_EDGE)) + +#define IS_MDF_SITF_MODE(PARAM) (((PARAM) == MDF_SITF_LF_MASTER_SPI_MODE) || \ + ((PARAM) == MDF_SITF_NORMAL_SPI_MODE) || \ + ((PARAM) == MDF_SITF_MANCHESTER_FALLING_MODE) || \ + ((PARAM) == MDF_SITF_MANCHESTER_RISING_MODE)) + +#define IS_MDF_SITF_CLOCK_SOURCE(PARAM) (((PARAM) == MDF_SITF_CCK0_SOURCE) || \ + ((PARAM) == MDF_SITF_CCK1_SOURCE)) + +#define IS_MDF_SITF_THRESHOLD(PARAM) ((4U <= (PARAM)) && ((PARAM) <= 31U)) + +#define IS_MDF_CIC_MODE(PARAM) (((PARAM) == MDF_ONE_FILTER_SINC4) || \ + ((PARAM) == MDF_ONE_FILTER_SINC5)) + +#define IS_MDF_ACQUISITION_MODE(PARAM) (((PARAM) == MDF_MODE_ASYNC_CONT) || \ + ((PARAM) == MDF_MODE_ASYNC_SINGLE) || \ + ((PARAM) == MDF_MODE_SYNC_CONT) || \ + ((PARAM) == MDF_MODE_SYNC_SINGLE) || \ + ((PARAM) == MDF_MODE_WINDOW_CONT)) + +#define IS_MDF_DISCARD_SAMPLES(PARAM) ((PARAM) <= 255U) + +#define IS_MDF_FIFO_THRESHOLD(PARAM) (((PARAM) == MDF_FIFO_THRESHOLD_NOT_EMPTY) || \ + ((PARAM) == MDF_FIFO_THRESHOLD_HALF_FULL)) + +#define IS_MDF_TRIGGER_SOURCE(PARAM) (((PARAM) == MDF_FILTER_TRIG_TRGO) || \ + ((PARAM) == MDF_FILTER_TRIG_EXTI15)) + +#define IS_MDF_TRIGGER_EDGE(PARAM) (((PARAM) == MDF_FILTER_TRIG_RISING_EDGE) || \ + ((PARAM) == MDF_FILTER_TRIG_FALLING_EDGE)) + +#define IS_MDF_DATA_SOURCE(PARAM) (((PARAM) == MDF_DATA_SOURCE_BSMX) || \ + ((PARAM) == MDF_DATA_SOURCE_ADCITF1) || \ + ((PARAM) == MDF_DATA_SOURCE_ADCITF2)) + +#define IS_MDF_DECIMATION_RATIO(PARAM) ((2U <= (PARAM)) && ((PARAM) <= 512U)) + +#define IS_MDF_GAIN(PARAM) ((-16 <= (PARAM)) && ((PARAM) <= 24)) + +#define IS_MDF_DELAY(PARAM) ((PARAM) <= 127U) + +#define IS_MDF_RSF_DECIMATION_RATIO(PARAM) (((PARAM) == MDF_RSF_DECIMATION_RATIO_4) || \ + ((PARAM) == MDF_RSF_DECIMATION_RATIO_1)) + +#define IS_MDF_HPF_CUTOFF_FREQ(PARAM) (((PARAM) == MDF_HPF_CUTOFF_0_000625FPCM) || \ + ((PARAM) == MDF_HPF_CUTOFF_0_00125FPCM) || \ + ((PARAM) == MDF_HPF_CUTOFF_0_0025FPCM) || \ + ((PARAM) == MDF_HPF_CUTOFF_0_0095FPCM)) + +#define IS_MDF_SAD_MODE(PARAM) (((PARAM) == MDF_SAD_VOICE_ACTIVITY_DETECTOR) || \ + ((PARAM) == MDF_SAD_SOUND_DETECTOR) || \ + ((PARAM) == MDF_SAD_AMBIENT_NOISE_DETECTOR)) + +#define IS_MDF_SAD_FRAME_SIZE(PARAM) (((PARAM) == MDF_SAD_8_PCM_SAMPLES) || \ + ((PARAM) == MDF_SAD_16_PCM_SAMPLES) || \ + ((PARAM) == MDF_SAD_32_PCM_SAMPLES) || \ + ((PARAM) == MDF_SAD_64_PCM_SAMPLES) || \ + ((PARAM) == MDF_SAD_128_PCM_SAMPLES) || \ + ((PARAM) == MDF_SAD_256_PCM_SAMPLES) || \ + ((PARAM) == MDF_SAD_512_PCM_SAMPLES)) + +#define IS_MDF_SAD_SOUND_TRIGGER(PARAM) (((PARAM) == MDF_SAD_ENTER_DETECT) || \ + ((PARAM) == MDF_SAD_ENTER_EXIT_DETECT)) + +#define IS_MDF_SAD_DATA_MEMORY_TRANSFER(PARAM) (((PARAM) == MDF_SAD_NO_MEMORY_TRANSFER) || \ + ((PARAM) == MDF_SAD_MEMORY_TRANSFER_IN_DETECT) || \ + ((PARAM) == MDF_SAD_MEMORY_TRANSFER_ALWAYS)) + +#define IS_MDF_SAD_MIN_NOISE_LEVEL(PARAM) ((PARAM) <= 8191U) + +#define IS_MDF_SAD_HANGOVER_WINDOW(PARAM) (((PARAM) == MDF_SAD_HANGOVER_4_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_8_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_16_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_32_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_64_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_128_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_256_FRAMES) || \ + ((PARAM) == MDF_SAD_HANGOVER_512_FRAMES)) + +#define IS_MDF_SAD_LEARNING_FRAMES(PARAM) (((PARAM) == MDF_SAD_LEARNING_2_FRAMES) || \ + ((PARAM) == MDF_SAD_LEARNING_4_FRAMES) || \ + ((PARAM) == MDF_SAD_LEARNING_8_FRAMES) || \ + ((PARAM) == MDF_SAD_LEARNING_16_FRAMES) || \ + ((PARAM) == MDF_SAD_LEARNING_32_FRAMES)) + +#define IS_MDF_SAD_AMBIENT_NOISE_SLOPE(PARAM) ((PARAM) <= 7U) + +#define IS_MDF_SAD_SIGNAL_NOISE_THRESHOLD(PARAM) (((PARAM) == MDF_SAD_SIGNAL_NOISE_3_5DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_6DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_9_5DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_12DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_15_6DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_18DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_21_6DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_24_1DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_27_6DB) || \ + ((PARAM) == MDF_SAD_SIGNAL_NOISE_30_1DB)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_MDF_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr.h new file mode 100644 index 0000000..3125820 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr.h @@ -0,0 +1,589 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_pwr.h + * @author MCD Application Team + * @brief Header file of PWR 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 STM32H7RSxx_HAL_PWR_H +#define STM32H7RSxx_HAL_PWR_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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_WakeUp_Pins PWR Wake-Up Pins + * @{ + */ +/* High level and No pull (default configuration) */ +#define PWR_WAKEUP_PIN4 PWR_WKUPEPR_WKUPEN4 /*!< Wakeup pin 4 (with high level polarity) */ +#define PWR_WAKEUP_PIN3 PWR_WKUPEPR_WKUPEN3 /*!< Wakeup pin 3 (with high level polarity) */ +#define PWR_WAKEUP_PIN2 PWR_WKUPEPR_WKUPEN2 /*!< Wakeup pin 2 (with high level polarity) */ +#define PWR_WAKEUP_PIN1 PWR_WKUPEPR_WKUPEN1 /*!< Wakeup pin 1 (with high level polarity) */ + +/* High level and No pull */ +#define PWR_WAKEUP_PIN4_HIGH PWR_WKUPEPR_WKUPEN4 /*!< Wakeup pin 4 (with high level polarity) */ +#define PWR_WAKEUP_PIN3_HIGH PWR_WKUPEPR_WKUPEN3 /*!< Wakeup pin 3 (with high level polarity) */ +#define PWR_WAKEUP_PIN2_HIGH PWR_WKUPEPR_WKUPEN2 /*!< Wakeup pin 2 (with high level polarity) */ +#define PWR_WAKEUP_PIN1_HIGH PWR_WKUPEPR_WKUPEN1 /*!< Wakeup pin 1 (with high level polarity) */ + +/* Low level and No pull */ +#define PWR_WAKEUP_PIN4_LOW (PWR_WKUPEPR_WKUPP4 | PWR_WKUPEPR_WKUPEN4) /*!< Wakeup pin 4 (with low level polarity) */ +#define PWR_WAKEUP_PIN3_LOW (PWR_WKUPEPR_WKUPP3 | PWR_WKUPEPR_WKUPEN3) /*!< Wakeup pin 3 (with low level polarity) */ +#define PWR_WAKEUP_PIN2_LOW (PWR_WKUPEPR_WKUPP2 | PWR_WKUPEPR_WKUPEN2) /*!< Wakeup pin 2 (with low level polarity) */ +#define PWR_WAKEUP_PIN1_LOW (PWR_WKUPEPR_WKUPP1 | PWR_WKUPEPR_WKUPEN1) /*!< Wakeup pin 1 (with low level polarity) */ +/** + * @} + */ + +/** @defgroup PWR_PVD_Detection_Level PWR PVD detection level + * @{ + */ +#define PWR_PVDLEVEL_1 (0x00000000U) /*!< Programmable voltage detector level 1 selection : 1V95 */ +#define PWR_PVDLEVEL_2 PWR_CR1_PLS_0 /*!< Programmable voltage detector level 2 selection : 2V1 */ +#define PWR_PVDLEVEL_3 PWR_CR1_PLS_1 /*!< Programmable voltage detector level 3 selection : 2V25 */ +#define PWR_PVDLEVEL_4 (PWR_CR1_PLS_1 | PWR_CR1_PLS_0) /*!< Programmable voltage detector level 4 selection : 2V4 */ +#define PWR_PVDLEVEL_5 PWR_CR1_PLS_2 /*!< Programmable voltage detector level 5 selection : 2V55 */ +#define PWR_PVDLEVEL_6 (PWR_CR1_PLS_2 | PWR_CR1_PLS_0) /*!< Programmable voltage detector level 6 selection : 2V7 */ +#define PWR_PVDLEVEL_7 (PWR_CR1_PLS_2 | PWR_CR1_PLS_1) /*!< Programmable voltage detector level 7 selection : 2V85 */ +#define PWR_PVDLEVEL_EXT_VOL (PWR_CR1_PLS_2 | PWR_CR1_PLS_1 | PWR_CR1_PLS_0) /*!< External input analog voltage (Compare internally to VREF) */ +/** + * @} + */ + +/** @defgroup PWR_PVD_Mode PWR PVD Mode + * @{ + */ +#define PWR_PVD_MODE_NORMAL (0x00000000U) /*!< Basic mode is used */ +#define PWR_PVD_MODE_IT_RISING (0x00010001U) /*!< Interrupt Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_IT_FALLING (0x00010002U) /*!< Interrupt Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_IT_RISING_FALLING (0x00010003U) /*!< Interrupt Mode with Rising/Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING (0x00020001U) /*!< Event Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_EVENT_FALLING (0x00020002U) /*!< Event Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING_FALLING (0x00020003U) /*!< Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @defgroup PWR_Regulator_state_in_LP_mode PWR Regulator state in SLEEP/STOP mode + * @{ + */ +/* define for interface compatibility purpose */ +#define PWR_MAINREGULATOR_ON (0x0U) + +/** + * @} + */ + +/** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry + * @{ + */ +#define PWR_SLEEPENTRY_WFI (0x01U) +#define PWR_SLEEPENTRY_WFE (0x02U) +#define PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR (0x03U) +/** + * @} + */ + +/** @defgroup PWR_STOP_mode_entry PWR STOP mode entry + * @{ + */ +#define PWR_STOPENTRY_WFI (0x01U) +#define PWR_STOPENTRY_WFE (0x02U) +#define PWR_STOPENTRY_WFE_NO_EVT_CLEAR (0x03U) +/** + * @} + */ + +/** @defgroup PWR_Regulator_Voltage_Scale PWR Regulator Voltage Scale + * @{ + */ +#define PWR_REGULATOR_VOLTAGE_SCALE0 PWR_CSR4_VOS /*!< Voltage scaling range 0 (highest frequency) */ +#define PWR_REGULATOR_VOLTAGE_SCALE1 (0U) /*!< Voltage scaling range 1 (lowest power) */ + +/** + * @} + */ + +/** @defgroup PWR_Flag PWR Status Flags + * Elements values convention: 0000 0XXX XXXY YYYYb + * - Y YYYY : Flag position in the XXX register (5 bits) + * - XXX XXX : Status register (6 bits) + * - 000001: SR1 register + * - 000010: CSR1 register + * - 000100: CSR2 register + * - 001000: CSR3 register + * - 010000: CSR4 register + * - 100000: WKUPCR register + * The only exception is PWR_FLAG_WU, encompassing all + * wake-up flags and set to PWR_SR1_WUF. + * @{ + */ +/* SR1 */ +#define PWR_FLAG_AVDO (0x002DU) /*!< Analog voltage detector output on VDDA */ +#define PWR_FLAG_PVDO (0x0024U) /*!< Programmable voltage detect output */ +#define PWR_FLAG_ACTVOSRDY (0x0021U) /*!< Voltage levels ready bit for currently used ACTVOS and SDHILEVEL */ +#define PWR_FLAG_ACTVOS (0x0020U) /*!< Programmable voltage detect output */ + +/* CSR1 */ +#define PWR_FLAG_TEMPH (0x0057U) /*!< Temperature level monitoring versus high threshold */ +#define PWR_FLAG_TEMPL (0x0056U) /*!< Temperature level monitoring versus low threshold */ +#define PWR_FLAG_VBATH (0x0055U) /*!< VBAT level monitoring versus high threshold */ +#define PWR_FLAG_VBATL (0x0054U) /*!< VBAT level monitoring versus low threshold */ +#define PWR_FLAG_BRRDY (0x0050U) /*!< Backup regulator ready */ + +/* CSR2 */ +#define PWR_FLAG_USB33RDY (0x009AU) /*!< USB supply ready */ +#define PWR_FLAG_SDEXTRDY (0x0090U) /*!< SMPS step-down converter external supply ready */ + +/* CSR3 */ +#define PWR_FLAG_SBF (0x0109U) /*!< System Standby flag */ +#define PWR_FLAG_STOPF (0x0108U) /*!< System Stop flag */ + +/* CSR4 */ +#define PWR_FLAG_VOSRDY (0x0201U) /*!< VOS Ready bit for VCORE voltage scaling output selection */ + +/* WKUPCR & WKUPFR */ +#define PWR_FLAG_WUF1 (0x0400U) /*!< Wakeup event on wakeup pin 1 */ +#define PWR_FLAG_WUF2 (0x0401U) /*!< Wakeup event on wakeup pin 2 */ +#define PWR_FLAG_WUF3 (0x0402U) /*!< Wakeup event on wakeup pin 3 */ +#define PWR_FLAG_WUF4 (0x0403U) /*!< Wakeup event on wakeup pin 4 */ +#define PWR_FLAG_WUF_ALL (0x0404U) /*!< Wakeup flag all */ +/** + * @} + */ + +/** @defgroup PWR_ENABLE_WUP_Mask PWR Enable WUP Mask + * @{ + */ +#define PWR_EWUP_MASK (0x00FF0F0FU) +/** + * @} + */ + +/** @defgroup PWR_Flag_WUP PWR Flag WakeUp + * @{ + */ +#define PWR_FLAG_WKUP1 PWR_WKUPCR_WKUPC1 +#define PWR_FLAG_WKUP2 PWR_WKUPCR_WKUPC2 +#define PWR_FLAG_WKUP3 PWR_WKUPCR_WKUPC3 +#define PWR_FLAG_WKUP4 PWR_WKUPCR_WKUPC4 +#define PWR_FLAG_WKUP PWR_WKUPCR_WKUPC +/** + * @} + */ + +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWR_Exported_Macro PWR Exported Macro + * @{ + */ + +/** @brief Check whether or not a specific PWR flag is set. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_ACTVOS: This flag indicates that the regulator voltage + * scaling output selection is ready. + * @arg PWR_FLAG_ACTVOSRDY: This flag indicates that the regulator voltage + * scaling output selection is ready. + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD + * is enabled by the HAL_PWR_EnablePVD()function. + * The PVD is stopped by STANDBY mode. For this reason, + * this bit is equal to 0 after STANDBY or reset until the + * PVDE bit is set. + * @arg PWR_FLAG_AVDO: AVD Output. This flag is valid only if AVD is enabled + * by the HAL_PWREx_EnableAVD() function. The AVD is stopped by Standby mode. + * For this reason, this bit is equal to 0 after Standby or reset + * until the AVDE bit is set. + * @arg PWR_FLAG_BRRDY : Backup regulator ready flag. This bit is not reset + * when the device wakes up from Standby mode or by a system reset + * or power reset. + * @arg PWR_FLAG_VBATL: This flag indicates if the VBAT level is above + * the low monitoring threshold. + * @arg PWR_FLAG_VBATH: This flag indicates if the VBAT level is above + * the high monitoring threshold. + * @arg PWR_FLAG_TEMPL This flag indicates if the temperature level is above + * the low monitoring threshold. + * @arg PWR_FLAG_TEMPH: This flag indicates if the temperature level is above + * the high monitoring threshold. + * @arg PWR_FLAG_SDEXTRDY: This flag indicates if the external supply + * from the SMPS step-down converter is ready. + * @arg PWR_FLAG_USB33RDY: This flag indicates if the USB supply is ready. + * @arg PWR_FLAG_STOPF: STOP mode flag + * @arg PWR_FLAG_SBF: Standby mode flag + * @arg PWR_FLAG_VOSRDY When an internal regulator is used, this bit indicates + * that all the features allowed by the selected VOS can be used. + * @arg PWR_FLAG_WUF1: This flag indicates a wakeup event was + * received from WKUP1 pin. + * @arg PWR_FLAG_WUF2: This flag indicates a wakeup event was + * received from WKUP2 pin. + * @arg PWR_FLAG_WUF3: This flag indicates a wakeup event was + * received from WKUP3 pin. + * @arg PWR_FLAG_WUF4: This flag indicates a wakeup event was + * received from WKUP4 pin. + * @retval The (__FLAG__) state (TRUE or FALSE). + */ +#define __HAL_PWR_GET_FLAG(__FLAG__) ( \ + ((__FLAG__) == PWR_FLAG_ACTVOS) ? ((PWR->SR1 & PWR_SR1_ACTVOS) == PWR_SR1_ACTVOS) : \ + ((__FLAG__) == PWR_FLAG_ACTVOSRDY)? ((PWR->SR1 & PWR_SR1_ACTVOSRDY) == PWR_SR1_ACTVOSRDY) : \ + ((__FLAG__) == PWR_FLAG_PVDO) ? ((PWR->SR1 & PWR_SR1_PVDO) == PWR_SR1_PVDO) : \ + ((__FLAG__) == PWR_FLAG_AVDO) ? ((PWR->SR1 & PWR_SR1_AVDO) == PWR_SR1_AVDO) : \ + ((__FLAG__) == PWR_FLAG_BRRDY) ? ((PWR->CSR1 & PWR_CSR1_BRRDY) == PWR_CSR1_BRRDY) : \ + ((__FLAG__) == PWR_FLAG_VBATL) ? ((PWR->CSR1 & PWR_CSR1_VBATL) == PWR_CSR1_VBATL) : \ + ((__FLAG__) == PWR_FLAG_VBATH) ? ((PWR->CSR1 & PWR_CSR1_VBATH) == PWR_CSR1_VBATH) : \ + ((__FLAG__) == PWR_FLAG_TEMPL) ? ((PWR->CSR1 & PWR_CSR1_TEMPL) == PWR_CSR1_TEMPL) : \ + ((__FLAG__) == PWR_FLAG_TEMPH) ? ((PWR->CSR1 & PWR_CSR1_TEMPH) == PWR_CSR1_TEMPH) : \ + ((__FLAG__) == PWR_FLAG_SDEXTRDY) ? ((PWR->CSR2 & PWR_CSR2_SDEXTRDY) == PWR_CSR2_SDEXTRDY) : \ + ((__FLAG__) == PWR_FLAG_USB33RDY) ? ((PWR->CSR2 & PWR_CSR2_USB33RDY) == PWR_CSR2_USB33RDY) : \ + ((__FLAG__) == PWR_FLAG_STOPF) ? ((PWR->CSR3 & PWR_CSR3_STOPF) == PWR_CSR3_STOPF) : \ + ((__FLAG__) == PWR_FLAG_SBF) ? ((PWR->CSR3 & PWR_CSR3_SBF) == PWR_CSR3_SBF) : \ + ((__FLAG__) == PWR_FLAG_VOSRDY) ? ((PWR->CSR4 & PWR_CSR4_VOSRDY) == PWR_CSR4_VOSRDY) : \ + ((__FLAG__) == PWR_FLAG_WUF1) ? ((PWR->WKUPFR & PWR_WKUPFR_WKUPF1) == PWR_WKUPFR_WKUPF1) : \ + ((__FLAG__) == PWR_FLAG_WUF2) ? ((PWR->WKUPFR & PWR_WKUPFR_WKUPF2) == PWR_WKUPFR_WKUPF2) : \ + ((__FLAG__) == PWR_FLAG_WUF3) ? ((PWR->WKUPFR & PWR_WKUPFR_WKUPF3) == PWR_WKUPFR_WKUPF3) : \ + ((PWR->WKUPFR & PWR_WKUPFR_WKUPF4) == PWR_WKUPFR_WKUPF4)) + +/** @brief Clear PWR flags. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_STOPF : Stop flag. + * Indicates that the device was resumed from Stop mode. + * @arg PWR_FLAG_SBF : Standby flag. + * Indicates that the device was resumed from Standby mode. + * @arg PWR_FLAG_WUF1 : Wakeup flag 1. + * Indicates that a wakeup event was received from the WKUP line 1. + * @arg PWR_FLAG_WUF2 : Wakeup flag 2. + * Indicates that a wakeup event was received from the WKUP line 2. + * @arg PWR_FLAG_WUF3 : Wakeup flag 3. + * Indicates that a wakeup event was received from the WKUP line 3. + * @arg PWR_FLAG_WUF4 : Wakeup flag 4. + * Indicates that a wakeup event was received from the WKUP line 4. + * @arg PWR_FLAG_WUF_ALL: All Wakeup flags. + * @retval None. + */ +#define __HAL_PWR_CLEAR_FLAG(__FLAG__) ( \ + ((__FLAG__) == PWR_FLAG_STOPF) ? (SET_BIT(PWR->CSR3, PWR_CSR3_CSSF)) : \ + ((__FLAG__) == PWR_FLAG_SBF) ? (SET_BIT(PWR->CSR3, PWR_CSR3_CSSF)) : \ + ((__FLAG__) == PWR_FLAG_WUF1) ? (SET_BIT(PWR->WKUPCR, PWR_WKUPCR_WKUPC1)) : \ + ((__FLAG__) == PWR_FLAG_WUF2) ? (SET_BIT(PWR->WKUPCR, PWR_WKUPCR_WKUPC2)) : \ + ((__FLAG__) == PWR_FLAG_WUF3) ? (SET_BIT(PWR->WKUPCR, PWR_WKUPCR_WKUPC3)) : \ + ((__FLAG__) == PWR_FLAG_WUF4) ? (SET_BIT(PWR->WKUPCR, PWR_WKUPCR_WKUPC4)) : \ + (SET_BIT(PWR->WKUPCR, PWR_WKUPCR_WKUPC))) + +/** @brief Check PWR wake up flags are set or not. + * @param __FLAG__: specifies the wake up flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WKUP1 : This parameter gets Wake up line 1 flag. + * @arg PWR_FLAG_WKUP2 : This parameter gets Wake up line 2 flag. + * @arg PWR_FLAG_WKUP3 : This parameter gets Wake up line 3 flag. + * @arg PWR_FLAG_WKUP4 : This parameter gets Wake up line 4 flag. + * @arg PWR_FLAG_WKUP : This parameter gets Wake up lines 1 to 4 flags. + * @retval The (__FLAG__) state (TRUE or FALSE). + */ +#define __HAL_PWR_GET_WAKEUPFLAG(__FLAG__) ((PWR->WKUPFR & (__FLAG__)) ? 0 : 1) + +/** @brief Clear CPU PWR wake up flags. + * @param __FLAG__ : Specifies the wake up flag to be cleared. + * This parameter can be one of the following values : + * @arg PWR_FLAG_WKUP1 : This parameter clears Wake up line 1 flag. + * @arg PWR_FLAG_WKUP2 : This parameter clears Wake up line 2 flag. + * @arg PWR_FLAG_WKUP3 : This parameter clears Wake up line 3 flag. + * @arg PWR_FLAG_WKUP4 : This parameter clears Wake up line 4 flag. + * @arg PWR_FLAG_WKUP : This parameter clears Wake up lines 1 to 4 flags. + * @retval None. + */ +#define __HAL_PWR_CLEAR_WAKEUPFLAG(__FLAG__) SET_BIT(PWR->WKUPCR, (__FLAG__)) + +/** + * @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 Check whether the specified PVD EXTI interrupt flag is set or not. + * @retval EXTI PVD Line Status. + */ +#define __HAL_PWR_PVD_EXTI_GET_FLAG() ((READ_BIT(EXTI->PR1, PWR_EXTI_LINE_PVD) == PWR_EXTI_LINE_PVD) ? 1UL : 0UL) + +/** + * @brief Clear the PVD EXTI flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() WRITE_REG(EXTI->PR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Generates a Software interrupt on PVD EXTI line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER1, PWR_EXTI_LINE_PVD) +/** + * @} + */ + +/* Include PWR HAL Extension module */ +#include "stm32h7rsxx_hal_pwr_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @addtogroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions + * @{ + */ +/* 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 Peripheral Control Functions + * @{ + */ +/* Peripheral Control Functions **********************************************/ +/* PVD configuration */ +void HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD); +void HAL_PWR_EnablePVD(void); +void HAL_PWR_DisablePVD(void); + +/* WakeUp pins configuration */ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity); +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx); + +/* Low Power modes entry */ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry); +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry); +void HAL_PWR_EnterSTANDBYMode(void); + +/* Cortex System Control functions *******************************************/ +void HAL_PWR_EnableSleepOnExit(void); +void HAL_PWR_DisableSleepOnExit(void); +void HAL_PWR_EnableSEVOnPend(void); +void HAL_PWR_DisableSEVOnPend(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PWR_Private_Constants PWR Private Constants + * @{ + */ + +/** @defgroup PWR_PVD_EXTI_Line PWR PVD EXTI Line + * @{ + */ +#define PWR_EXTI_LINE_PVD EXTI_IMR1_IM16 /*!< External interrupt line 16 connected to the PVD EXTI Line */ +/** + * @} + */ + +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PWR_Private_Macros PWR Private Macros + * @{ + */ + +/** @defgroup PWR_IS_PWR_Definitions PWR Private macros to check input parameters + * @{ + */ +/* Check PVD level parameter */ +#define IS_PWR_PVD_LEVEL(LEVEL) (((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) ||\ + ((LEVEL) == PWR_PVDLEVEL_EXT_VOL)) + +/* Check PVD mode parameter */ +#define IS_PWR_PVD_MODE(MODE) (((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) ||\ + ((MODE) == PWR_PVD_MODE_NORMAL)) + +/* Check low power regulator parameter */ +#define IS_PWR_REGULATOR(REGULATOR) ((REGULATOR) == PWR_MAINREGULATOR_ON) + +/* Check low power mode entry parameter */ +#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) ||\ + ((ENTRY) == PWR_SLEEPENTRY_WFE) ||\ + ((ENTRY) == PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR)) + +/* Check low power mode entry parameter */ +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) ||\ + ((ENTRY) == PWR_STOPENTRY_WFE) ||\ + ((ENTRY) == PWR_STOPENTRY_WFE_NO_EVT_CLEAR)) + +/* Check voltage scale level parameter */ +#define IS_PWR_REGULATOR_VOLTAGE(VOLTAGE) (((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE0) || \ + ((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE1)) + + +/* 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_PIN1_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN2_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN3_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN4_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN1_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN2_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN3_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN4_LOW)) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H7RSxx_HAL_PWR_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr_ex.h new file mode 100644 index 0000000..743652c --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_pwr_ex.h @@ -0,0 +1,610 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_pwr_ex.h + * @author MCD Application Team + * @brief Header file of PWR HAL Extension 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 STM32H7RSxx_HAL_PWR_EX_H +#define STM32H7RSxx_HAL_PWR_EX_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup PWREx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PWREx_Exported_Types PWREx Exported Types + * @{ + */ +/** + * @brief PWREx AVD configuration structure definition + */ +typedef struct +{ + uint32_t AVDLevel; /*!< Specifies the AVD detection level. + This parameter can be a value of @ref PWREx_AVD_detection_level */ + + uint32_t 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; /*!< Specifies the Wake-Up pin to be enabled. + This parameter can be a value of @ref PWR_WakeUp_Pins */ + + uint32_t PinPolarity; /*!< Specifies the Wake-Up pin polarity. + This parameter can be a value of @ref PWREx_PIN_Polarity */ + + uint32_t 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 PWREx Exported Constants + * @{ + */ + +/** @defgroup PWREx_PIN_Polarity PWREx Pin Polarity configuration + * @{ + */ +#define PWR_PIN_POLARITY_HIGH (0x0U) +#define PWR_PIN_POLARITY_LOW (0x1U) +/** + * @} + */ + +/** @defgroup PWREx_PIN_Pull PWREx Pin Pull configuration + * @{ + */ +#define PWR_PIN_NO_PULL (0x0U) +#define PWR_PIN_PULL_UP (0x1U) +#define PWR_PIN_PULL_DOWN (0x2U) +/** + * @} + */ + +/** @defgroup PWREx_Wakeup_Pins_Flags PWREx Wakeup Pins Flags. + * @{ + */ +#define PWR_WAKEUP_FLAG1 PWR_WKUPFR_WKUPF1 /*!< Wakeup flag on PA0 */ +#define PWR_WAKEUP_FLAG2 PWR_WKUPFR_WKUPF2 /*!< Wakeup flag on PA2 */ +#define PWR_WAKEUP_FLAG3 PWR_WKUPFR_WKUPF3 /*!< Wakeup flag on PC13 */ +#define PWR_WAKEUP_FLAG4 PWR_WKUPFR_WKUPF4 /*!< Wakeup flag on PC1 */ + +#define PWR_WAKEUP_FLAG_ALL (PWR_WKUPFR_WKUPF1 | PWR_WKUPFR_WKUPF2 |\ + PWR_WKUPFR_WKUPF3 | PWR_WKUPFR_WKUPF4) +/** + * @} + */ + +/** @defgroup PWREx_Supply_configuration PWREx Supply configuration + * @{ + */ +#define PWR_LDO_SUPPLY PWR_CSR2_LDOEN /*!< Core domains are supplied from the LDO */ +#define PWR_EXTERNAL_SOURCE_SUPPLY PWR_CSR2_BYPASS /*!< The SMPS disabled and the LDO Bypass. The Core domains are supplied from an external source */ +#define PWR_DIRECT_SMPS_SUPPLY PWR_CSR2_SDEN /*!< Core domains are supplied from the SMPS only */ + +#define PWR_SMPS_1V8_SUPPLIES_LDO (PWR_CSR2_SDHILEVEL | PWR_CSR2_SDEN | PWR_CSR2_LDOEN) /*!< The SMPS 1.8V output supplies the LDO which supplies the Core domains */ +#define PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | PWR_CSR2_SDEN | PWR_CSR2_LDOEN) /*!< The SMPS 1.8V output supplies external circuits and the LDO. The Core domains are supplied from the LDO */ +#define PWR_SMPS_1V8_SUPPLIES_EXT (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | PWR_CSR2_SDEN | PWR_CSR2_BYPASS) /*!< The SMPS 1.8V output supplies external source which supplies the Core domains */ + +#define PWR_SUPPLY_CONFIG_MASK (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | \ + PWR_CSR2_SDEN | PWR_CSR2_LDOEN | PWR_CSR2_BYPASS) + +/** + * @} + */ + + +/** @defgroup PWREx_AVD_detection_level PWREx AVD detection level + * @{ + */ +#define PWR_AVDLEVEL_1 (0x0U) /*!< Analog voltage detector level 1 : 1V7 */ +#define PWR_AVDLEVEL_2 PWR_CR1_ALS_0 /*!< Analog voltage detector level 2 : 2V1 */ +#define PWR_AVDLEVEL_3 PWR_CR1_ALS_1 /*!< Analog voltage detector level 3 : 2V5 */ +#define PWR_AVDLEVEL_4 (PWR_CR1_ALS_1 | PWR_CR1_ALS_0) /*!< Analog voltage detector level 4 : 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_STOP_VOLTAGE_SCALE3 PWR_CR1_SVOS /*!< System Stop mode voltage scaling range 3 (highest frequency) */ +#define PWR_REGULATOR_STOP_VOLTAGE_SCALE5 (0x0U) /*!< System Stop mode voltage scaling range 5 (lowest power) */ + +/** + * @} + */ + +/** @defgroup PWREx_VBAT_Battery_Charging_Resistor PWR battery charging resistor selection + * @{ + */ +#define PWR_BATTERY_CHARGING_RESISTOR_5 (0x0U) /*!< VBAT charging through a 5 kOhms resistor */ +#define PWR_BATTERY_CHARGING_RESISTOR_1_5 PWR_CSR2_VBRS /*!< VBAT charging through a 1.5 kOhms resistor */ +/** + * @} + */ + +/** @defgroup PWREx_VBAT_Thresholds PWREx VBAT Thresholds + * @{ + */ +#define PWR_VBAT_BETWEEN_HIGH_LOW_THRESHOLD (0x0U) +#define PWR_VBAT_BELOW_LOW_THRESHOLD PWR_CSR1_VBATL +#define PWR_VBAT_ABOVE_HIGH_THRESHOLD PWR_CSR1_VBATH +/** + * @} + */ + +/** @defgroup PWREx_TEMP_Thresholds PWREx Temperature Thresholds + * @{ + */ +#define PWR_TEMP_BETWEEN_HIGH_LOW_THRESHOLD (0x00000000U) +#define PWR_TEMP_BELOW_LOW_THRESHOLD PWR_CSR1_TEMPL +#define PWR_TEMP_ABOVE_HIGH_THRESHOLD PWR_CSR1_TEMPH +/** + * @} + */ + +/** @defgroup PWREx_CAPACITOR_Port PWREx Capacitor Port + * @{ + */ +#define PWR_CAPACITOR_PORT1 PWR_CSR2_XSPICAP1 +#define PWR_CAPACITOR_PORT2 PWR_CSR2_XSPICAP2 +/** + * @} + */ + +/** @defgroup PWREx_CAPACITOR_Value PWREx Capacitor Value + * @{ + */ +#define PWR_CAPACITOR_OFF (0x0U) +#define PWR_CAPACITOR_ONE_THIRD_CAPACITANCE PWR_CSR2_XSPICAP1_0 +#define PWR_CAPACITOR_TWO_THIRD_CAPACITANCE PWR_CSR2_XSPICAP1_1 +#define PWR_CAPACITOR_FULL_CAPACITANCE PWR_CSR2_XSPICAP1 +/** + * @} + */ + +/** @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 */ +/** + * @} + */ + +/** @defgroup PWREx_GPIO_PullUp_Port PWR Extended GPIO Pull-Up Port + * @{ + */ +#define PWR_GPIO_PULLUP_PORT_N (0x00U) /*!< GPIO port N */ +#define PWR_GPIO_PULLUP_PORT_O (0x01U) /*!< GPIO port O */ +/** + * @} + */ + +/** @defgroup PWREx_GPIO_PullDown_Port PWR Extended GPIO Pull-Down Port + * @{ + */ +#define PWR_GPIO_PULLDOWN_PORT_N (0x00U) /*!< GPIO port N */ +#define PWR_GPIO_PULLDOWN_PORT_O (0x01U) /*!< GPIO port O */ +#define PWR_GPIO_PULLDOWN_PORT_P (0x02U) /*!< GPIO port P */ +/** + * @} + */ + +/** @defgroup PWREx_GPIO_PullUp_Pin_Mask PWR Extended GPIO Pull-Up Pin Mask + * @{ + */ +#define PWR_GPIO_N_PULLUP_PIN_1 (0x0002U) /*!< GPIO N pin 1 */ +#define PWR_GPIO_N_PULLUP_PIN_6 (0x0040U) /*!< GPIO N pin 6 */ +#define PWR_GPIO_N_PULLUP_PIN_12 (0x1000U) /*!< GPIO N pin 12 */ + +#define PWR_GPIO_O_PULLUP_PIN_0 (0x0001U) /*!< GPIO O pin 0 */ +#define PWR_GPIO_O_PULLUP_PIN_1 (0x0002U) /*!< GPIO O pin 1 */ +#define PWR_GPIO_O_PULLUP_PIN_4 (0x0010U) /*!< GPIO O pin 4 */ +/** + * @} + */ + +/** @defgroup PWREx_GPIO_PullDown_Pin_Mask PWR Extended GPIO Pull-Down Pin Mask + * @{ + */ +#define PWR_GPIO_N_PULLDOWN_PIN_0 (0x0001U) /*!< GPIO N pin 0 */ +#define PWR_GPIO_N_PULLDOWN_PIN_1 (0x0002U) /*!< GPIO N pin 1 */ +#define PWR_GPIO_N_PULLDOWN_PIN_2_5 (0x0004U) /*!< GPIO N pin 2 to 5 */ +#define PWR_GPIO_N_PULLDOWN_PIN_6 (0x0040U) /*!< GPIO N pin 6 */ +#define PWR_GPIO_N_PULLDOWN_PIN_8_11 (0x0100U) /*!< GPIO N pin 8 to 11 */ +#define PWR_GPIO_N_PULLDOWN_PIN_12 (0x1000U) /*!< GPIO N pin 12 */ + +#define PWR_GPIO_O_PULLDOWN_PIN_0 (0x0001U) /*!< GPIO O pin 0 */ +#define PWR_GPIO_O_PULLDOWN_PIN_1 (0x0002U) /*!< GPIO O pin 1 */ +#define PWR_GPIO_O_PULLDOWN_PIN_2 (0x0004U) /*!< GPIO O pin 2 */ +#define PWR_GPIO_O_PULLDOWN_PIN_3 (0x0008U) /*!< GPIO O pin 3 */ +#define PWR_GPIO_O_PULLDOWN_PIN_4 (0x0010U) /*!< GPIO O pin 4 */ + +#define PWR_GPIO_P_PULLDOWN_PIN_0_3 (0x0001U) /*!< GPIO P pin 0 to 3 */ +#define PWR_GPIO_P_PULLDOWN_PIN_4_7 (0x0010U) /*!< GPIO P pin 4 to 7 */ +#define PWR_GPIO_P_PULLDOWN_PIN_8_11 (0x0100U) /*!< GPIO P pin 8 to 11 */ +#define PWR_GPIO_P_PULLDOWN_PIN_12_15 (0x1000U) /*!< GPIO P pin 12 to 15 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Macro PWREx Exported Macro + * @{ + */ + +/** + * @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 interrupt flag is set or not. + * @retval EXTI AVD Line Status. + */ +#define __HAL_PWR_AVD_EXTI_GET_FLAG() ((READ_BIT(EXTI->PR1, PWR_EXTI_LINE_AVD) == PWR_EXTI_LINE_AVD) ? 1UL : 0UL) + +/** + * @brief Clear the AVD EXTI flag. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_CLEAR_FLAG() WRITE_REG(EXTI->PR1, PWR_EXTI_LINE_AVD) + +/** + * @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) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @addtogroup PWREx_Exported_Functions_Group1 Power Supply Control Functions + * @{ + */ +/* Power supply control functions */ +HAL_StatusTypeDef HAL_PWREx_ConfigSupply(uint32_t SupplySource); +uint32_t HAL_PWREx_GetSupplyConfig(void); + +/* Power voltage scaling functions */ +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 Low Power Control Functions + * @{ + */ +/* Flash low power control functions */ +void HAL_PWREx_EnableFlashPowerDown(void); +void HAL_PWREx_DisableFlashPowerDown(void); + +/* Wakeup Pins control functions */ +void HAL_PWREx_EnableWakeUpPin(const PWREx_WakeupPinTypeDef *sPinParams); +void HAL_PWREx_DisableWakeUpPin(uint32_t WakeUpPin); +uint32_t HAL_PWREx_GetWakeupFlag(uint32_t WakeUpFlag); +HAL_StatusTypeDef HAL_PWREx_ClearWakeupFlag(uint32_t WakeUpFlag); + +/* Power Wakeup PIN IRQ Handler */ +void HAL_PWREx_WAKEUP_PIN_IRQHandler(void); +void HAL_PWREx_WKUP1_Callback(void); +void HAL_PWREx_WKUP2_Callback(void); +void HAL_PWREx_WKUP3_Callback(void); +void HAL_PWREx_WKUP4_Callback(void); +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group3 Peripherals Control Functions + * @{ + */ +/* Backup regulator control functions */ +HAL_StatusTypeDef HAL_PWREx_EnableBkUpReg(void); +HAL_StatusTypeDef HAL_PWREx_DisableBkUpReg(void); + +/* USB regulator control functions */ +void HAL_PWREx_EnableUSBReg(void); +void HAL_PWREx_DisableUSBReg(void); +HAL_StatusTypeDef HAL_PWREx_EnableUSBVoltageDetector(void); +HAL_StatusTypeDef HAL_PWREx_DisableUSBVoltageDetector(void); +void HAL_PWREx_EnableUSBHSregulator(void); +void HAL_PWREx_DisableUSBHSregulator(void); + +/* USB regulator control functions */ +void HAL_PWREx_EnableUCPDStandbyMode(void); +void HAL_PWREx_DisableUCPDStandbyMode(void); +void HAL_PWREx_EnableUCPDDeadBattery(void); +void HAL_PWREx_DisableUCPDDeadBattery(void); + +/* Battery control functions */ +void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorValue); +void HAL_PWREx_DisableBatteryCharging(void); + +/* Analog Booster functions */ +void HAL_PWREx_EnableAnalogBooster(void); +void HAL_PWREx_DisableAnalogBooster(void); + +/* XSPIM_P1 functions */ +void HAL_PWREx_EnableXSPIM1(void); +void HAL_PWREx_DisableXSPIM1(void); + +/* XSPIM_P2 functions */ +void HAL_PWREx_EnableXSPIM2(void); +void HAL_PWREx_DisableXSPIM2(void); + +/* PORT capacitor control functions */ +void HAL_PWREx_ConfigXSPIPortCap(uint32_t PortCapacitor, uint32_t PortCapacitorSetting); +uint32_t HAL_PWREx_GetConfigXSPIPortCap(uint32_t PortCapacitor); + +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group4 Power Monitoring functions + * @{ + */ +/* Power VBAT/Temperature monitoring functions */ +void HAL_PWREx_EnableMonitoring(void); +void HAL_PWREx_DisableMonitoring(void); +uint32_t HAL_PWREx_GetTemperatureLevel(void); +uint32_t HAL_PWREx_GetVBATLevel(void); + +/* Power AVD configuration functions */ +void HAL_PWREx_ConfigAVD(const PWREx_AVDTypeDef *sConfigAVD); +void HAL_PWREx_EnableAVD(void); +void HAL_PWREx_DisableAVD(void); + +/* Power PVD/AVD IRQ Handler */ +void HAL_PWREx_PVD_AVD_IRQHandler(void); +void HAL_PWREx_PVD_AVD_Callback(void); +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group5 I/O Pull-Up Pull-Down Configuration Functions + * @{ + */ +/* GPIO Pull-up Pull-down configuration functions */ +void HAL_PWREx_EnablePullUpPullDownConfig(void); +void HAL_PWREx_DisablePullUpPullDownConfig(void); + +/* GPIO Pull control functions */ +HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO_Port, uint32_t GPIO_Pin); +HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO_Port, uint32_t GPIO_Pin); +HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO_Port, uint32_t GPIO_Pin); +HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO_Port, uint32_t GPIO_Pin); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PWREx_Private_Macros PWREx Private Macros + * @{ + */ + +/** @defgroup PWREx_IS_PWR_Definitions PWREx Private macros to check input parameters + * @{ + */ +/* Check PWR regulator configuration parameter */ +#define IS_PWR_SUPPLY(PWR_SOURCE) (((PWR_SOURCE) == PWR_LDO_SUPPLY) ||\ + ((PWR_SOURCE) == PWR_DIRECT_SMPS_SUPPLY) ||\ + ((PWR_SOURCE) == PWR_SMPS_1V8_SUPPLIES_LDO) ||\ + ((PWR_SOURCE) == PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO) ||\ + ((PWR_SOURCE) == PWR_SMPS_1V8_SUPPLIES_EXT) ||\ + ((PWR_SOURCE) == PWR_EXTERNAL_SOURCE_SUPPLY)) + +/* Check PWR regulator configuration in STOP mode parameter */ +#define IS_PWR_STOP_MODE_REGULATOR_VOLTAGE(VOLTAGE) (((VOLTAGE) == PWR_REGULATOR_STOP_VOLTAGE_SCALE3) ||\ + ((VOLTAGE) == PWR_REGULATOR_STOP_VOLTAGE_SCALE5)) + +/* 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_FLAG_ALL)) + +/* Check wake up flag parameter */ +#define IS_PWR_AVD_LEVEL(LEVEL) (((LEVEL) == PWR_AVDLEVEL_1) ||\ + ((LEVEL) == PWR_AVDLEVEL_2) ||\ + ((LEVEL) == PWR_AVDLEVEL_3) ||\ + ((LEVEL) == PWR_AVDLEVEL_4)) + +/* 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)) + +/* Check resistor battery parameter */ +#define IS_PWR_BATTERY_RESISTOR_SELECT(RESISTOR) (((RESISTOR) == PWR_BATTERY_CHARGING_RESISTOR_5) ||\ + ((RESISTOR) == PWR_BATTERY_CHARGING_RESISTOR_1_5)) + +/* Check the capacitor port parameter */ +#define IS_PWR_CAPACITOR(PORT) (((PORT) == PWR_CAPACITOR_PORT1) || \ + ((PORT) == PWR_CAPACITOR_PORT2)) + +/* Check the capacitor port setting parameter */ +#define IS_PWR_CAPACITOR_SETTING(SETTING) (((SETTING) == PWR_CAPACITOR_OFF) || \ + ((SETTING) == PWR_CAPACITOR_ONE_THIRD_CAPACITANCE) || \ + ((SETTING) == PWR_CAPACITOR_TWO_THIRD_CAPACITANCE) || \ + ((SETTING) == PWR_CAPACITOR_FULL_CAPACITANCE)) + +/* Check GPIO Pull-Up Port parameter */ +#define IS_PWR_GPIO_PULLPUP_PORT(GPIO_PORT) (((GPIO_PORT) == PWR_GPIO_PULLUP_PORT_N) ||\ + ((GPIO_PORT) == PWR_GPIO_PULLUP_PORT_O)) + +/* Check GPIO Pull-Down Port parameter */ +#define IS_PWR_GPIO_PULLDOWN_PORT(GPIO_PORT) (((GPIO_PORT) == PWR_GPIO_PULLDOWN_PORT_N) ||\ + ((GPIO_PORT) == PWR_GPIO_PULLDOWN_PORT_O) ||\ + ((GPIO_PORT) == PWR_GPIO_PULLDOWN_PORT_P)) + +/* GPIO pin mask check macro */ +#define IS_PWR_GPIO_PIN_MASK(BIT_MASK) ((((BIT_MASK) & GPIO_PIN_MASK) != 0U) && ((BIT_MASK) <= GPIO_PIN_MASK)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* STM32H7RSxx_HAL_PWR_EX_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc.h new file mode 100644 index 0000000..5a1306c --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc.h @@ -0,0 +1,4814 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_rcc.h + * @author MCD Application Team + * @brief Header file of RCC 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 STM32H7RSxx_HAL_RCC_H +#define STM32H7RSxx_HAL_RCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" +#include "stm32h7rsxx_ll_rcc.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Types RCC Exported Types + * @{ + */ + +/** + * @brief RCC PLL configuration structure definition + */ +typedef struct +{ + uint32_t PLLState; /*!< The new state of the PLL. + This parameter can be a value of @ref RCC_PLL_Config */ + + uint32_t PLLSource; /*!< PLL entry clock source. + This parameter must be a value of @ref RCC_PLL_Clock_Source */ + + uint32_t PLLM; /*!< Division factor for PLL VCO input clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 63 */ + + uint32_t PLLN; /*!< Multiplication factor for PLL VCO output clock. + This parameter must be a number between Min_Data = 8 and Max_Data = 420 */ + + uint32_t PLLP; /*!< Division factor for system clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 + Odd division factors (except for 1) are not allowed */ + + uint32_t PLLQ; /*!< Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t PLLR; /*!< Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t PLLS; /*!< Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 8 */ + + uint32_t PLLT; /*!< Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 8 */ + + uint32_t PLLFractional; /*!< Fractional Part of the Multiplication Factor for PLL VCO. + This parameter must be a number 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_Divider */ + + uint32_t HSICalibrationValue; /*!< The calibration trimming value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7F */ + + uint32_t LSIState; /*!< The new state of the LSI. + This parameter can be a value of @ref RCC_LSI_Config */ + + uint32_t HSI48State; /*!< The new state of the HSI48. + This parameter can be a value of @ref RCC_HSI48_Config */ + + uint32_t CSIState; /*!< The new state of the CSI. + This parameter can be a value of @ref RCC_CSI_Config */ + + RCC_PLLInitTypeDef PLL1; /*!< Main PLL1 structure parameters */ + + RCC_PLLInitTypeDef PLL2; /*!< PLL2 structure parameters */ + + RCC_PLLInitTypeDef PLL3; /*!< PLL3 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 SYSCLKDivider; /*!< The system clock divider for CPU clock and all bus matrix clocks. + This parameter can be a value of @ref RCC_System_Clock_Divider */ + + uint32_t AHBCLKDivider; /*!< The AHB/AXI clock divider for HCLK. + This clock is derived from the system clock divided by the system clock divider. + This parameter can be a value of @ref RCC_HCLK_Clock_Source */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock divider for PCLK1. + This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_Clock_Source */ + + uint32_t APB2CLKDivider; /*!< The APB2 clock divider for PCLK2. + This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB2_Clock_Source */ + + uint32_t APB4CLKDivider; /*!< The APB4 clock divider for PCLK4. + This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB4_Clock_Source */ + + uint32_t APB5CLKDivider; /*!< The APB5 clock divider for PCLK5. + This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB5_Clock_Source */ + +} RCC_ClkInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Constants RCC Exported Constants + * @{ + */ + +/** @defgroup RCC_Oscillator_Type Oscillator Type + * @{ + */ +#define RCC_OSCILLATORTYPE_NONE 0x00000000U /*!< Oscillator configuration unchanged */ +#define RCC_OSCILLATORTYPE_HSE 0x00000001U /*!< HSE selected */ +#define RCC_OSCILLATORTYPE_HSI 0x00000002U /*!< HSI selected */ +#define RCC_OSCILLATORTYPE_LSE 0x00000004U /*!< LSE selected */ +#define RCC_OSCILLATORTYPE_LSI 0x00000008U /*!< LSI selected */ +#define RCC_OSCILLATORTYPE_CSI 0x00000010U /*!< CSI selected */ +#define RCC_OSCILLATORTYPE_HSI48 0x00000020U /*!< HSI48 selected */ +/** + * @} + */ + +/** @defgroup RCC_HSE_Config HSE Config + * @{ + */ +#define RCC_HSE_OFF 0U /*!< HSE clock deactivation */ +#define RCC_HSE_ON RCC_CR_HSEON /*!< HSE clock activation */ +#define RCC_HSE_BYPASS (RCC_CR_HSEBYP | RCC_CR_HSEON) /*!< HSE bypass analog clock activation */ +#define RCC_HSE_BYPASS_DIGITAL (RCC_CR_HSEEXT | RCC_CR_HSEBYP | RCC_CR_HSEON) /*!< HSE bypass digital clock activation */ +/** + * @} + */ + +/** @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 (RCC_BDCR_LSEBYP | RCC_BDCR_LSEON) /*!< LSE bypass analog clock activation */ +#define RCC_LSE_BYPASS_DIGITAL (RCC_BDCR_LSEEXT | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON) /*!< LSE bypass digital clock activation */ +/** + * @} + */ + +/** @defgroup RCC_HSI_Config HSI Config + * @{ + */ +#define RCC_HSI_OFF 0U /*!< HSI clock deactivation */ +#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation with divider 1 = 64MHz */ +/** + * @} + */ + +/** @defgroup RCC_HSI_Calibration_Default HSI Calibration default + * @{ + */ +#define RCC_HSICALIBRATION_DEFAULT 0x40U /*!< Default HSI calibration trimming value */ +/** + * @} + */ + +/** @defgroup RCC_HSI_Divider HSI Divider + * @{ + */ +#define RCC_HSI_DIV1 0U /*!< HSI clock activation with divider 1 = 64MHz */ +#define RCC_HSI_DIV2 RCC_CR_HSIDIV_0 /*!< HSI clock activation with divider 2 = 32MHz */ +#define RCC_HSI_DIV4 RCC_CR_HSIDIV_1 /*!< HSI clock activation with divider 4 = 16MHz */ +#define RCC_HSI_DIV8 RCC_CR_HSIDIV /*!< HSI clock activation with divider 8 = 8MHz */ +/** + * @} + */ + +/** @defgroup RCC_HSI48_Config HSI48 Config + * @{ + */ +#define RCC_HSI48_OFF 0U /*!< HSI48 clock deactivation */ +#define RCC_HSI48_ON RCC_CR_HSI48ON /*!< HSI48 clock activation */ +/** + * @} + */ + +/** @defgroup RCC_LSI_Config LSI Config + * @{ + */ +#define RCC_LSI_OFF 0U /*!< LSI clock deactivation */ +#define RCC_LSI_ON RCC_CSR_LSION /*!< LSI clock activation */ +/** + * @} + */ + +/** @defgroup RCC_CSI_Config CSI Config + * @{ + */ +#define RCC_CSI_OFF 0U /*!< CSI clock deactivation */ +#define RCC_CSI_ON RCC_CR_CSION /*!< CSI clock activation */ +/** + * @} + */ + +/** @defgroup RCC_CSI_Calibration_Default CSI Calibration default + * @{ + */ +#define RCC_CSICALIBRATION_DEFAULT 0x20U /*!< Default CSI calibration trimming value */ +/** + * @} + */ + +/** @defgroup RCC_PLL_Config PLL Config + * @{ + */ +#define RCC_PLL_NONE 0U /*!< PLL configuration unchanged */ +#define RCC_PLL_OFF 1U /*!< PLL deactivation */ +#define RCC_PLL_ON 2U /*!< PLL activation */ +/** + * @} + */ + +/** @defgroup RCC_PLL_Clock_Source PLL Clock Source + * @{ + */ +#define RCC_PLLSOURCE_HSI 0U /*!< HSI clock selected as PLL entry clock source */ +#define RCC_PLLSOURCE_CSI RCC_PLLCKSELR_PLLSRC_0 /*!< CSI clock selected as PLL entry clock source */ +#define RCC_PLLSOURCE_HSE RCC_PLLCKSELR_PLLSRC_1 /*!< HSE clock selected as PLL entry clock source */ +#define RCC_PLLSOURCE_NONE RCC_PLLCKSELR_PLLSRC /*!< No clock selected as PLL entry clock source */ +/** + * @} + */ + +/** @defgroup RCC_PLL_Clock_Output PLL Clock Output + * @{ + */ +#define RCC_PLL_PCLK RCC_PLLCFGR_PLL1PEN /*!< PLL DIVP divider output enable */ +#define RCC_PLL_QCLK RCC_PLLCFGR_PLL1QEN /*!< PLL DIVQ divider output enable */ +#define RCC_PLL_RCLK RCC_PLLCFGR_PLL1REN /*!< PLL DIVR divider output enable */ +#define RCC_PLL_SCLK RCC_PLLCFGR_PLL1SEN /*!< PLL DIVS divider output enable */ +#define RCC_PLL_TCLK 0x00000200U /*!< PLL DIVT divider output enable, hardcoded because no definition in CMSIS */ +/** + * @} + */ + +/** @defgroup RCC_PLL_VCI_Range PLL VCI Range + * @{ + */ +#define RCC_PLL_VCOINPUT_RANGE0 0U /*!< Clock range frequency for PLL between 1 and 2 MHz (reset) */ +#define RCC_PLL_VCOINPUT_RANGE1 RCC_PLLCFGR_PLL1RGE_0 /*!< Clock range frequency for PLL between 2 and 4 MHz */ +#define RCC_PLL_VCOINPUT_RANGE2 RCC_PLLCFGR_PLL1RGE_1 /*!< Clock range frequency for PLL between 4 and 8 MHz */ +#define RCC_PLL_VCOINPUT_RANGE3 RCC_PLLCFGR_PLL1RGE /*!< Clock range frequency for PLL between 8 and 16 MHz */ +/** + * @} + */ + +/** @defgroup RCC_PLL_VCO_Range PLL VCO Range + * @{ + */ +#define RCC_PLL_VCO_HIGH 0U /*!< Wide PLL VCO output range between 400 and 1600 MHz (reset) */ +#define RCC_PLL_VCO_LOW RCC_PLLCFGR_PLL1VCOSEL /*!< Low PLL VCO output range between 150 and 420 MHz */ +/** + * @} + */ + +/** @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_PCLK4 0x00000010U /*!< PCLK4 to configure */ +#define RCC_CLOCKTYPE_PCLK5 0x00000020U /*!< PCLK5 to configure */ +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source System Clock Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI 0U /*!< HSI selection as system clock */ +#define RCC_SYSCLKSOURCE_CSI RCC_CFGR_SW_0 /*!< CSI selection as system clock */ +#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_1 /*!< HSE selection as system clock */ +#define RCC_SYSCLKSOURCE_PLLCLK (RCC_CFGR_SW_1 | RCC_CFGR_SW_0) /*!< PLL1 selection as system clock */ +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI 0U /*!< HSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_CSI RCC_CFGR_SWS_0 /*!< CSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_1 /*!< HSE used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLCLK (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0) /*!< PLL1 used as system clock */ +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Divider System Clock Divider + * @{ + */ +#define RCC_SYSCLK_DIV1 0U /*!< SYSCLK not divided */ +#define RCC_SYSCLK_DIV2 RCC_CDCFGR_CPRE_3 /*!< SYSCLK divided by 2 */ +#define RCC_SYSCLK_DIV4 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_0) /*!< SYSCLK divided by 4 */ +#define RCC_SYSCLK_DIV8 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_1) /*!< SYSCLK divided by 8 */ +#define RCC_SYSCLK_DIV16 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_1 | RCC_CDCFGR_CPRE_0) /*!< SYSCLK divided by 16 */ +#define RCC_SYSCLK_DIV64 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2) /*!< SYSCLK divided by 64 */ +#define RCC_SYSCLK_DIV128 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2 | RCC_CDCFGR_CPRE_0) /*!< SYSCLK divided by 128 */ +#define RCC_SYSCLK_DIV256 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2 | RCC_CDCFGR_CPRE_1) /*!< SYSCLK divided by 256 */ +#define RCC_SYSCLK_DIV512 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2 | RCC_CDCFGR_CPRE_1 | RCC_CDCFGR_CPRE_0) /*!< SYSCLK divided by 512 */ +/** + * @} + */ + + +/** @defgroup RCC_HCLK_Clock_Source HCLK Clock Source + * @{ + */ +#define RCC_HCLK_DIV1 0U /*!< HCLK not divided */ +#define RCC_HCLK_DIV2 RCC_BMCFGR_BMPRE_3 /*!< HCLK divided by 2 */ +#define RCC_HCLK_DIV4 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_0) /*!< HCLK divided by 4 */ +#define RCC_HCLK_DIV8 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_1) /*!< HCLK divided by 8 */ +#define RCC_HCLK_DIV16 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_1 | RCC_BMCFGR_BMPRE_0) /*!< HCLK divided by 16 */ +#define RCC_HCLK_DIV64 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2) /*!< HCLK divided by 64 */ +#define RCC_HCLK_DIV128 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2 | RCC_BMCFGR_BMPRE_0) /*!< HCLK divided by 128 */ +#define RCC_HCLK_DIV256 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2 | RCC_BMCFGR_BMPRE_1) /*!< HCLK divided by 256 */ +#define RCC_HCLK_DIV512 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2 | RCC_BMCFGR_BMPRE_1 | RCC_BMCFGR_BMPRE_0) /*!< HCLK divided by 512 */ +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Source APB1 Clock Source + * @{ + */ +#define RCC_APB1_DIV1 0U /*!< APB1 not divided */ +#define RCC_APB1_DIV2 RCC_APBCFGR_PPRE1_2 /*!< APB1 divided by 2 */ +#define RCC_APB1_DIV4 (RCC_APBCFGR_PPRE1_2 | RCC_APBCFGR_PPRE1_0) /*!< APB1 divided by 4 */ +#define RCC_APB1_DIV8 (RCC_APBCFGR_PPRE1_2 | RCC_APBCFGR_PPRE1_1) /*!< APB1 divided by 8 */ +#define RCC_APB1_DIV16 RCC_APBCFGR_PPRE1 /*!< APB1 divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_APB2_Clock_Source APB2 Clock Source + * @{ + */ +#define RCC_APB2_DIV1 0U /*!< APB2 not divided */ +#define RCC_APB2_DIV2 RCC_APBCFGR_PPRE2_2 /*!< APB2 divided by 2 */ +#define RCC_APB2_DIV4 (RCC_APBCFGR_PPRE2_2 | RCC_APBCFGR_PPRE2_0) /*!< APB2 divided by 4 */ +#define RCC_APB2_DIV8 (RCC_APBCFGR_PPRE2_2 | RCC_APBCFGR_PPRE2_1) /*!< APB2 divided by 8 */ +#define RCC_APB2_DIV16 RCC_APBCFGR_PPRE2 /*!< APB2 divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_APB4_Clock_Source APB4 Clock Source + * @{ + */ +#define RCC_APB4_DIV1 0U /*!< APB4 not divided */ +#define RCC_APB4_DIV2 RCC_APBCFGR_PPRE4_2 /*!< APB4 divided by 2 */ +#define RCC_APB4_DIV4 (RCC_APBCFGR_PPRE4_2 | RCC_APBCFGR_PPRE4_0) /*!< APB4 divided by 4 */ +#define RCC_APB4_DIV8 (RCC_APBCFGR_PPRE4_2 | RCC_APBCFGR_PPRE4_1) /*!< APB4 divided by 8 */ +#define RCC_APB4_DIV16 RCC_APBCFGR_PPRE4 /*!< APB4 divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_APB5_Clock_Source APB5 Clock Source + * @{ + */ +#define RCC_APB5_DIV1 0U /*!< APB5 not divided */ +#define RCC_APB5_DIV2 RCC_APBCFGR_PPRE5_2 /*!< APB5 divided by 2 */ +#define RCC_APB5_DIV4 (RCC_APBCFGR_PPRE5_2 | RCC_APBCFGR_PPRE5_0) /*!< APB5 divided by 4 */ +#define RCC_APB5_DIV8 (RCC_APBCFGR_PPRE5_2 | RCC_APBCFGR_PPRE5_1) /*!< APB5 divided by 8 */ +#define RCC_APB5_DIV16 RCC_APBCFGR_PPRE5 /*!< APB5 divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source RTC Clock Source + * @{ + */ +#define RCC_RTCCLKSOURCE_DISABLE 0U /*!< RTC clock is disabled */ +#define RCC_RTCCLKSOURCE_LSE RCC_BDCR_RTCSEL_0 /*!< LSE oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_LSI RCC_BDCR_RTCSEL_1 /*!< LSI oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV2 ((0x02UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 2 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV3 ((0x03UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 3 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV4 ((0x04UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 4 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV5 ((0x05UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 5 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV6 ((0x06UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 6 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV7 ((0x07UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 7 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV8 ((0x08UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 8 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV9 ((0x09UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 9 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV10 ((0x0AUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 10 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV11 ((0x0BUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 11 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV12 ((0x0CUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 12 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV13 ((0x0DUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 13 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV14 ((0x0EUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 14 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV15 ((0x0FUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 15 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV16 ((0x10UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 16 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV17 ((0x11UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 17 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV18 ((0x12UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 18 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV19 ((0x13UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 19 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV20 ((0x14UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 20 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV21 ((0x15UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 21 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV22 ((0x16UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 22 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV23 ((0x17UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 23 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV24 ((0x18UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 24 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV25 ((0x19UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 25 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV26 ((0x1AUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 26 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV27 ((0x1BUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 27 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV28 ((0x1CUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 28 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV29 ((0x1DUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 29 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV30 ((0x1EUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 30 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV31 ((0x1FUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 31 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV32 ((0x20UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 32 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV33 ((0x21UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 33 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV34 ((0x22UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 34 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV35 ((0x23UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 35 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV36 ((0x24UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 36 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV37 ((0x25UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 37 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV38 ((0x26UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 38 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV39 ((0x27UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 39 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV40 ((0x28UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 40 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV41 ((0x29UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 41 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV42 ((0x2AUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 42 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV43 ((0x2BUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 43 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV44 ((0x2CUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 44 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV45 ((0x2DUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 45 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV46 ((0x2EUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 46 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV47 ((0x2FUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 47 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV48 ((0x30UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 48 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV49 ((0x31UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 49 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV50 ((0x32UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 50 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV51 ((0x33UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 51 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV52 ((0x34UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 52 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV53 ((0x35UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 53 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV54 ((0x36UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 54 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV55 ((0x37UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 55 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV56 ((0x38UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 56 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV57 ((0x39UL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 57 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV58 ((0x3AUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 58 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV59 ((0x3BUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 59 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV60 ((0x3CUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 60 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV61 ((0x3DUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 61 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV62 ((0x3EUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 62 used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV63 ((0x3FUL << 12U) | RCC_BDCR_RTCSEL) /*!< HSE oscillator clock divided by 63 used as RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_MCOx_Index MCOx Index + * @{ + */ + +/* @cond */ +/* 32 28 20 16 0 + -------------------------------- + | MCO | GPIO | GPIO | GPIO | + | Index | AF | Port | Pin | + -------------------------------*/ + +#define RCC_MCO_GPIOPORT_POS 16U +#define RCC_MCO_GPIOPORT_MASK (0xFUL << RCC_MCO_GPIOPORT_POS) +#define RCC_MCO_GPIOAF_POS 20U +#define RCC_MCO_GPIOAF_MASK (0xFFUL << RCC_MCO_GPIOAF_POS) +#define RCC_MCO_INDEX_POS 28U +#define RCC_MCO_INDEX_MASK (0x1UL << RCC_MCO_INDEX_POS) + +#define RCC_MCO1_INDEX (0x0UL << RCC_MCO_INDEX_POS) /*!< MCO1 index */ +#define RCC_MCO2_INDEX (0x1UL << RCC_MCO_INDEX_POS) /*!< MCO2 index */ +/* @endcond */ + +#define RCC_MCO1_PA8 (RCC_MCO1_INDEX |\ + (GPIO_AF0_MCO << RCC_MCO_GPIOAF_POS) | (GPIO_GET_INDEX(GPIOA) << RCC_MCO_GPIOPORT_POS) | GPIO_PIN_8) +#define RCC_MCO1 RCC_MCO1_PA8 /*!< Alias for compatibility */ + +#define RCC_MCO2_PC9 (RCC_MCO2_INDEX |\ + (GPIO_AF0_MCO << RCC_MCO_GPIOAF_POS) | (GPIO_GET_INDEX(GPIOC) << RCC_MCO_GPIOPORT_POS) | GPIO_PIN_9) +#define RCC_MCO2 RCC_MCO2_PC9 /*!< Alias for compatibility */ + +#define RCC_MCO RCC_MCO1 /*!< MCO1 to be compliant with other families with 1 MCO*/ +/** + * @} + */ + +/** @defgroup RCC_MCO1_Clock_Source MCO1 Clock Source + * @{ + */ +#define RCC_MCO1SOURCE_HSI 0U /*!< HSI clock selected as MCO1 source (reset) */ +#define RCC_MCO1SOURCE_LSE RCC_CFGR_MCO1SEL_0 /*!< LSE clock selected as MCO1 source */ +#define RCC_MCO1SOURCE_HSE RCC_CFGR_MCO1SEL_1 /*!< HSE clock selected as MCO1 source */ +#define RCC_MCO1SOURCE_PLL1Q (RCC_CFGR_MCO1SEL_1 | RCC_CFGR_MCO1SEL_0) /*!< PLL1Q clock selected as MCO1 source */ +#define RCC_MCO1SOURCE_HSI48 RCC_CFGR_MCO1SEL_2 /*!< HSI48 clock selected as MCO1 source */ +/** + * @} + */ + +/** @defgroup RCC_MCO2_Clock_Source MCO2 Clock Source + * @{ + */ +#define RCC_MCO2SOURCE_SYSCLK 0U /*!< System clock selected as MCO2 source (reset) */ +#define RCC_MCO2SOURCE_PLL2P RCC_CFGR_MCO2SEL_0 /*!< PLL2P clock selected as MCO2 source */ +#define RCC_MCO2SOURCE_HSE RCC_CFGR_MCO2SEL_1 /*!< HSE clock selected as MCO2 source */ +#define RCC_MCO2SOURCE_PLL1P (RCC_CFGR_MCO2SEL_1 | RCC_CFGR_MCO2SEL_0) /*!< PLL1P clock selected as MCO2 source */ +#define RCC_MCO2SOURCE_CSI RCC_CFGR_MCO2SEL_2 /*!< CSI clock selected as MCO2 source */ +#define RCC_MCO2SOURCE_LSI (RCC_CFGR_MCO2SEL_2 | RCC_CFGR_MCO2SEL_0) /*!< LSI clock selected as MCO2 source */ +/** + * @} + */ + +/** @defgroup RCC_MCOx_Clock_Prescaler MCOx Clock Prescaler + * @{ + */ +#define RCC_MCODIV_NONE 0U /*!< No MCO prescaler (reset) */ +#define RCC_MCODIV_1 RCC_CFGR_MCO1PRE_0 /*!< MCO divided by 1 */ +#define RCC_MCODIV_2 RCC_CFGR_MCO1PRE_1 /*!< MCO divided by 2 */ +#define RCC_MCODIV_3 (RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_0) /*!< MCO divided by 3 */ +#define RCC_MCODIV_4 RCC_CFGR_MCO1PRE_2 /*!< MCO divided by 4 */ +#define RCC_MCODIV_5 (RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_0) /*!< MCO divided by 5 */ +#define RCC_MCODIV_6 (RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_1) /*!< MCO divided by 6 */ +#define RCC_MCODIV_7 (RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_0) /*!< MCO divided by 7 */ +#define RCC_MCODIV_8 RCC_CFGR_MCO1PRE_3 /*!< MCO divided by 8 */ +#define RCC_MCODIV_9 (RCC_CFGR_MCO1PRE_3 | RCC_CFGR_MCO1PRE_0) /*!< MCO divided by 9 */ +#define RCC_MCODIV_10 (RCC_CFGR_MCO1PRE_3 | RCC_CFGR_MCO1PRE_1) /*!< MCO divided by 10 */ +#define RCC_MCODIV_11 (RCC_CFGR_MCO1PRE_3 | RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_0) /*!< MCO divided by 11 */ +#define RCC_MCODIV_12 (RCC_CFGR_MCO1PRE_3 | RCC_CFGR_MCO1PRE_2) /*!< MCO divided by 12 */ +#define RCC_MCODIV_13 (RCC_CFGR_MCO1PRE_3 | RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_0) /*!< MCO divided by 13 */ +#define RCC_MCODIV_14 (RCC_CFGR_MCO1PRE_3 | RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_1) /*!< MCO divided by 14 */ +#define RCC_MCODIV_15 RCC_CFGR_MCO1PRE /*!< MCO divided by 15 */ +/** + * @} + */ + +/** @defgroup RCC_Interrupt Interrupt + * @{ + */ +#define RCC_IT_LSIRDY RCC_CIFR_LSIRDYF /*!< LSI Ready Interrupt */ +#define RCC_IT_LSERDY RCC_CIFR_LSERDYF /*!< LSE Ready Interrupt */ +#define RCC_IT_HSIRDY RCC_CIFR_HSIRDYF /*!< HSI Ready Interrupt */ +#define RCC_IT_HSERDY RCC_CIFR_HSERDYF /*!< HSE Ready Interrupt */ +#define RCC_IT_CSIRDY RCC_CIFR_CSIRDYF /*!< CSI Ready Interrupt */ +#define RCC_IT_HSI48RDY RCC_CIFR_HSI48RDYF /*!< HSI48 Ready Interrupt */ +#define RCC_IT_PLL1RDY RCC_CIFR_PLL1RDYF /*!< PLL1 Ready Interrupt */ +#define RCC_IT_PLL2RDY RCC_CIFR_PLL2RDYF /*!< PLL2 Ready Interrupt */ +#define RCC_IT_PLL3RDY RCC_CIFR_PLL3RDYF /*!< PLL3 Ready Interrupt */ +#define RCC_IT_LSECSS RCC_CIFR_LSECSSF /*!< LSE Clock Security System Interrupt */ +#define RCC_IT_HSECSS RCC_CIFR_HSECSSF /*!< HSE Clock Security System Interrupt (flag only) */ +/** + * @} + */ + +/** @defgroup RCC_Flag Flag + * Elements values convention: XXXYYYYYb + * - YYYYY : Flag position in the register + * - XXX : Register index + * - 001: CR register + * - 010: BDCR register + * - 011: CSR register + * - 100: RSR register + * @{ + */ +#define RCC_FLAG_HSIRDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSIRDY_Pos) /*!< HSI Ready flag */ +#define RCC_FLAG_HSIDIV ((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSIDIVF_Pos) /*!< HSIDIV Ready flag */ +#define RCC_FLAG_CSIRDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_CSIRDY_Pos) /*!< CSI Ready flag */ +#define RCC_FLAG_HSI48RDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSI48RDY_Pos) /*!< HSI48 Ready flag */ +#define RCC_FLAG_HSERDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSERDY_Pos) /*!< HSE Ready flag */ +#define RCC_FLAG_PLL1RDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_PLL1RDY_Pos) /*!< PLL1 Ready flag */ +#define RCC_FLAG_PLL2RDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_PLL2RDY_Pos) /*!< PLL2 Ready flag */ +#define RCC_FLAG_PLL3RDY ((RCC_CR_REG_INDEX << 5U) | RCC_CR_PLL3RDY_Pos) /*!< PLL3 Ready flag */ + +/* Flags in the BDCR register */ +#define RCC_FLAG_LSERDY ((RCC_BDCR_REG_INDEX << 5U) | RCC_BDCR_LSERDY_Pos) /*!< LSE Ready flag */ +#define RCC_FLAG_LSECSSD ((RCC_BDCR_REG_INDEX << 5U) | RCC_BDCR_LSECSSD_Pos) /*!< LSE Clock Security System failure detection flag */ + +/* Flags in the CSR register */ +#define RCC_FLAG_LSIRDY ((RCC_CSR_REG_INDEX << 5U) | RCC_CSR_LSIRDY_Pos) /*!< LSI Ready flag */ + +/* Flags in the RSR register */ +#define RCC_FLAG_BORRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_BORRSTF_Pos) /*!< BOR reset flag */ +#define RCC_FLAG_PINRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_PINRSTF_Pos) /*!< PIN reset flag */ +#define RCC_FLAG_PORRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_PORRSTF_Pos) /*!< Power-on reset flag */ +#define RCC_FLAG_SFTRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_SFTRSTF_Pos) /*!< Software Reset flag */ +#define RCC_FLAG_IWDGRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_IWDGRSTF_Pos) /*!< Independent Watchdog reset flag */ +#define RCC_FLAG_WWDGRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_WWDGRSTF_Pos) /*!< Window watchdog reset flag */ +#define RCC_FLAG_LPWRRST ((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_LPWRRSTF_Pos) /*!< Low-Power reset flag */ +/** + * @} + */ + +/** @defgroup RCC_LSEDrive_Config LSE Drive Config + * @{ + */ +#define RCC_LSEDRIVE_LOW 0U /*!< 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_Reset_Flag Reset Flag + * @{ + */ +#define RCC_RESET_FLAG_OBL RCC_RSR_OBLRSTF /*!< Option Byte Loader 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_OBL | 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_Stop_WakeUpClock Stop WakeUp Clock + * @{ + */ +#define RCC_STOP_WAKEUPCLOCK_HSI 0U /*!< HSI selected as wake up system clock from system Stop (default after reset) */ +#define RCC_STOP_WAKEUPCLOCK_CSI RCC_CFGR_STOPWUCK /*!< CSI selected as wake up system clock from system Stop */ +/** + * @} + */ + +/** @defgroup RCC_Stop_KernelWakeUpClock Stop Kernel WakeUp Clock + * @{ + */ +#define RCC_STOP_KERWAKEUPCLOCK_HSI 0U /*!< HSI selected as wake up kernel clock from system Stop (default after reset) */ +#define RCC_STOP_KERWAKEUPCLOCK_CSI RCC_CFGR_STOPKERWUCK /*!< CSI selected as wake up kernel clock from system Stop */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_AXI_Clock_Gating_Enable_Disable AXI Interconnect, Master and Slave Clock Gating Enable Disable + * @brief Enable or disable the clock gating. + * @note The dynamic power consumption can be optimized by enabling the functional clock gating. + * After reset, the clock gating is enabled (except for JTAG if a JTAG connection has been detected). + * @{ + */ + +#define __HAL_RCC_AXI_INTERCONNECT_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AXICKG) + +#define __HAL_RCC_AXI_MASTER_AHB_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AHBCKG) + +#define __HAL_RCC_AXI_MASTER_SDMMC1_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_SDMMCCKG) + +#define __HAL_RCC_AXI_MASTER_HPDMA1_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_HPDMA1CKG) + +#define __HAL_RCC_AXI_MASTER_CPU_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_CPUCKG) + +#define __HAL_RCC_AXI_MASTER_GPU2D_0_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_GPU2DS0CKG) + +#define __HAL_RCC_AXI_MASTER_GPU2D_1_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_GPU2DS1CKG) + +#define __HAL_RCC_AXI_MASTER_GPU2D_CACHE_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_GPU2DCKG) + +#define __HAL_RCC_AXI_MASTER_DCMIPP_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_DCMIPPCKG) + +#define __HAL_RCC_AXI_MASTER_DMA2D_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_DMA2DCKG) + +#define __HAL_RCC_AXI_MASTER_LTDC_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_LTDCCKG) + +#define __HAL_RCC_AXI_MASTER_GFXMMU_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_GFXMMUMCKG) + +#define __HAL_RCC_AXI_SLAVE_GFXMMU_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_GFXMMUSCKG) + +#define __HAL_RCC_AXI_SLAVE_AHB_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AHBSCKG) + +#define __HAL_RCC_AXI_SLAVE_FMC_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_FMCCKG) + +#define __HAL_RCC_AXI_SLAVE_XSPI1_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_XSPI1CKG) + +#define __HAL_RCC_AXI_SLAVE_XSPI2_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_XSPI2CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM0_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM0CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM1_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM1CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM2_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM2CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM3_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM3CKG) + +#define __HAL_RCC_AXI_SLAVE_FLASH_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_FLIFTCKG) + +#define __HAL_RCC_AXI_SLAVE_EXTI_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_EXTICKG) + +#define __HAL_RCC_AXI_SLAVE_JTAG_CLK_GATING_ENABLE() CLEAR_BIT(RCC->CKGDISR, RCC_CKGDISR_JTAGCKG) + + +#define __HAL_RCC_AXI_INTERCONNECT_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AXICKG) + +#define __HAL_RCC_AXI_MASTER_AHB_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AHBCKG) + +#define __HAL_RCC_AXI_MASTER_SDMMC1_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_SDMMCCKG) + +#define __HAL_RCC_AXI_MASTER_HPDMA1_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_HPDMA1CKG) + +#define __HAL_RCC_AXI_MASTER_CPU_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_CPUCKG) + +#define __HAL_RCC_AXI_MASTER_GPU_0_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_GPU2DS0CKG) + +#define __HAL_RCC_AXI_MASTER_GPU_1_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_GPU2DS1CKG) + +#define __HAL_RCC_AXI_MASTER_GPU_CACHE_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_GPU2DCKG) + +#define __HAL_RCC_AXI_MASTER_DCMIPP_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_DCMIPPCKG) + +#define __HAL_RCC_AXI_MASTER_DMA2D_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_DMA2DCKG) + +#define __HAL_RCC_AXI_MASTER_LTDC_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_LTDCCKG) + +#define __HAL_RCC_AXI_MASTER_GFXMMU_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_GFXMMUMCKG) + +#define __HAL_RCC_AXI_SLAVE_GFXMMU_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_GFXMMUSCKG) + +#define __HAL_RCC_AXI_SLAVE_AHB_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AHBSCKG) + +#define __HAL_RCC_AXI_SLAVE_FMC_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_FMCCKG) + +#define __HAL_RCC_AXI_SLAVE_XSPI1_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_XSPI1CKG) + +#define __HAL_RCC_AXI_SLAVE_XSPI2_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_XSPI2CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM0_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM0CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM1_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM1CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM2_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM2CKG) + +#define __HAL_RCC_AXI_SLAVE_SRAM3_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_AXISRAM3CKG) + +#define __HAL_RCC_AXI_SLAVE_FLASH_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_FLIFTCKG) + +#define __HAL_RCC_AXI_SLAVE_EXTI_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_EXTICKG) + +#define __HAL_RCC_AXI_SLAVE_JTAG_CLK_GATING_DISABLE() SET_BIT(RCC->CKGDISR, RCC_CKGDISR_JTAGCKG) + +/** + * @} + */ + +/** @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_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_ADC12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#if defined(ETH) +#define __HAL_RCC_ETH1MAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1MACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_ETH1TX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1TXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_ETH1RX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1RXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_USB_OTG_FS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGFSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_USBPHYC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_USBPHYCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_ADF1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADF1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB1ENR);\ + UNUSED(tmpreg); \ + } while(0) + + +#define __HAL_RCC_GPDMA1_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA1EN) + +#define __HAL_RCC_ADC12_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN) + +#if defined(ETH) +#define __HAL_RCC_ETH1MAC_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1MACEN) + +#define __HAL_RCC_ETH1TX_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1TXEN) + +#define __HAL_RCC_ETH1RX_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1RXEN) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN) + +#define __HAL_RCC_USB_OTG_FS_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGFSEN) + +#define __HAL_RCC_USBPHYC_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_USBPHYCEN) + +#define __HAL_RCC_ADF1_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADF1EN) + +/** + * @} + */ + +/** @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_PSSI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PSSIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SDMMC2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SDMMC2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_CORDIC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CORDICEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SRAM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->AHB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_PSSI_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PSSIEN) + +#define __HAL_RCC_SDMMC2_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SDMMC2EN) + +#define __HAL_RCC_CORDIC_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CORDICEN) + +#define __HAL_RCC_SRAM1_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM1EN) + +#define __HAL_RCC_SRAM2_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN) + +/** + * @} + */ + +/** @defgroup RCC_AHB3_Peripheral_Clock_Enable_Disable AHB3 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB3 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_RNG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_RNGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB3ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_HASH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_HASHEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB3ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_CRYPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB3ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_SAESEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB3ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PKAEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB3ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* PKA */ + +#define __HAL_RCC_RNG_CLK_DISABLE() CLEAR_BIT(RCC->AHB3ENR, RCC_AHB3ENR_RNGEN) + +#define __HAL_RCC_HASH_CLK_DISABLE() CLEAR_BIT(RCC->AHB3ENR, RCC_AHB3ENR_HASHEN) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_CLK_DISABLE() CLEAR_BIT(RCC->AHB3ENR, RCC_AHB3ENR_CRYPEN) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_DISABLE() CLEAR_BIT(RCC->AHB3ENR, RCC_AHB3ENR_SAESEN) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_DISABLE() CLEAR_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PKAEN) +#endif /* PKA */ + +/** + * @} + */ + +/** @defgroup RCC_AHB4_Peripheral_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. + * @{ + */ + +#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOBEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOE_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOFEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOHEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOMEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPION_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIONEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOO_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOOEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_CRC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_CRCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_BKPRAM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_BKPRAMEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + + +#define __HAL_RCC_GPIOA_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN) + +#define __HAL_RCC_GPIOB_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOBEN) + +#define __HAL_RCC_GPIOC_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOCEN) + +#define __HAL_RCC_GPIOD_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN) + +#define __HAL_RCC_GPIOE_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN) + +#define __HAL_RCC_GPIOF_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOFEN) + +#define __HAL_RCC_GPIOG_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOGEN) + +#define __HAL_RCC_GPIOH_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOHEN) + +#define __HAL_RCC_GPIOM_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOMEN) + +#define __HAL_RCC_GPION_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIONEN) + +#define __HAL_RCC_GPIOO_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOOEN) + +#define __HAL_RCC_GPIOP_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOPEN) + +#define __HAL_RCC_CRC_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_CRCEN) + +#define __HAL_RCC_BKPRAM_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_BKPRAMEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB5_Peripheral_Clock_Enable_Disable AHB5 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB5 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_HPDMA1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_HPDMA1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_DMA2D_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_DMA2DEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_JPEGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_FMCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_XSPI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPI1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SDMMC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_SDMMC1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_XSPI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPI2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_XSPIM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPIMEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_GFXMMUEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB5ENR, RCC_AHB5ENR_GPU2DEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->AHB5ENR);\ + UNUSED(tmpreg); \ + } while(0) +#endif /* GPU2D */ + +#define __HAL_RCC_HPDMA1_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_HPDMA1EN) + +#define __HAL_RCC_DMA2D_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_DMA2DEN) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_JPEGEN) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_FMCEN) + +#define __HAL_RCC_XSPI1_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPI1EN) + +#define __HAL_RCC_SDMMC1_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_SDMMC1EN) + +#define __HAL_RCC_XSPI2_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPI2EN) + +#define __HAL_RCC_XSPIM_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPIMEN) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_GFXMMUEN) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_CLK_DISABLE() CLEAR_BIT(RCC->AHB5ENR, RCC_AHB5ENR_GPU2DEN) +#endif /* GPU2D */ + +/** + * @} + */ + +/** @defgroup RCC_APB1_Peripheral_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->APB1ENR1, RCC_APB1ENR1_TIM2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM12EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM13_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM13EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM14EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPTIM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_LPTIM1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_WWDG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_WWDGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPI2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPI3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPI3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPDIFRX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPDIFRXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_USART2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USART2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_USART3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USART3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_UART4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_UART5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_I2C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C1_I3C1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_I2C2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_I2C3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_I3C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C1_I3C1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_CEC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_CECEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_UART7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_UART8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART8EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_CRS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR2, RCC_APB1ENR2_CRSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_MDIOS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR2, RCC_APB1ENR2_MDIOSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_FDCAN_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR2, RCC_APB1ENR2_FDCANEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_UCPD1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR2, RCC_APB1ENR2_UCPD1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB1ENR1);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM2EN) + +#define __HAL_RCC_TIM3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM3EN) + +#define __HAL_RCC_TIM4_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM4EN) + +#define __HAL_RCC_TIM5_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM5EN) + +#define __HAL_RCC_TIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN) + +#define __HAL_RCC_TIM7_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN) + +#define __HAL_RCC_TIM12_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM12EN) + +#define __HAL_RCC_TIM13_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM13EN) + +#define __HAL_RCC_TIM14_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM14EN) + +#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_LPTIM1EN) + +#define __HAL_RCC_SPI2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPI2EN) + +#define __HAL_RCC_SPI3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPI3EN) + +#define __HAL_RCC_SPDIFRX_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPDIFRXEN) + +#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USART2EN) + +#define __HAL_RCC_USART3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USART3EN) + +#define __HAL_RCC_UART4_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART4EN) + +#define __HAL_RCC_UART5_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART5EN) + +#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C1_I3C1EN) + +#define __HAL_RCC_I2C2_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C2EN) + +#define __HAL_RCC_I2C3_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C3EN) + +#define __HAL_RCC_I3C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C1_I3C1EN) + +#define __HAL_RCC_CEC_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_CECEN) + +#define __HAL_RCC_UART7_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART7EN) + +#define __HAL_RCC_UART8_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART8EN) + +#define __HAL_RCC_CRS_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR2, RCC_APB1ENR2_CRSEN) + +#define __HAL_RCC_MDIOS_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR2, RCC_APB1ENR2_MDIOSEN) + +#define __HAL_RCC_FDCAN_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR2, RCC_APB1ENR2_FDCANEN) + +#define __HAL_RCC_UCPD1_CLK_DISABLE() CLEAR_BIT(RCC->APB1ENR2, RCC_APB1ENR2_UCPD1EN) + +/** + * @} + */ + +/** @defgroup RCC_APB2_Peripheral_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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + 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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM9_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM9EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPI5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#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_REG(RCC->APB2ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN) + +#define __HAL_RCC_USART1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN) + +#define __HAL_RCC_SPI1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN) + +#define __HAL_RCC_SPI4_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN) + +#define __HAL_RCC_TIM15_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN) + +#define __HAL_RCC_TIM16_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN) + +#define __HAL_RCC_TIM17_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN) + +#define __HAL_RCC_TIM9_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM9EN) + +#define __HAL_RCC_SPI5_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN) + +#define __HAL_RCC_SAI1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN) + +#define __HAL_RCC_SAI2_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN) + +/** + * @} + */ + +/** @defgroup RCC_APB4_Peripheral_Clock_Enable_Disable APB4 Peripheral Clock Enable Disable + * @brief Enable or disable the APB4 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->APB4ENR, RCC_APB4ENR_SBSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPUART1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_LPUART1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPI6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_SPI6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPTIM2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPTIM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPTIM4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPTIM5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_VREF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_VREFEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_RTCAPB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_RTCAPBEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_DTS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB4ENR, RCC_APB4ENR_DTSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB4ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SBS_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_SBSEN) + +#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_LPUART1EN) + +#define __HAL_RCC_SPI6_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_SPI6EN) + +#define __HAL_RCC_LPTIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM2EN) + +#define __HAL_RCC_LPTIM3_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM3EN) + +#define __HAL_RCC_LPTIM4_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM4EN) + +#define __HAL_RCC_LPTIM5_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM5EN) + +#define __HAL_RCC_VREF_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_VREFEN) + +#define __HAL_RCC_RTCAPB_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_RTCAPBEN) + +#define __HAL_RCC_DTS_CLK_DISABLE() CLEAR_BIT(RCC->APB4ENR, RCC_APB4ENR_DTSEN) + +/** + * @} + */ + +/** @defgroup RCC_APB5_Peripheral_Clock_Enable_Disable APB5 Peripheral Clock Enable Disable + * @brief Enable or disable the APB5 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_LTDC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB5ENR, RCC_APB5ENR_LTDCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_DCMIPP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB5ENR, RCC_APB5ENR_DCMIPPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GFXTIM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB5ENR, RCC_APB5ENR_GFXTIMEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_REG(RCC->APB5ENR);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LTDC_CLK_DISABLE() CLEAR_BIT(RCC->APB5ENR, RCC_APB5ENR_LTDCEN) + +#define __HAL_RCC_DCMIPP_CLK_DISABLE() CLEAR_BIT(RCC->APB5ENR, RCC_APB5ENR_DCMIPPEN) + +#define __HAL_RCC_GFXTIM_CLK_DISABLE() CLEAR_BIT(RCC->APB5ENR, RCC_APB5ENR_GFXTIMEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB1_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_ADC12_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN) != 0U) + +#if defined(ETH) +#define __HAL_RCC_ETH1MAC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1MACEN) != 0U) + +#define __HAL_RCC_ETH1TX_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1TXEN) != 0U) + +#define __HAL_RCC_ETH1RX_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETH1RXEN) != 0U) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN) != 0U) + +#define __HAL_RCC_USB_OTG_FS_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGFSEN) != 0U) + +#define __HAL_RCC_USBPHYC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_USBPHYCEN) != 0U) + +#define __HAL_RCC_ADF1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADF1EN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB2_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_PSSI_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PSSIEN) != 0U) + +#define __HAL_RCC_SDMMC2_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SDMMC2EN) != 0U) + +#define __HAL_RCC_CORDIC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CORDICEN) != 0U) + +#define __HAL_RCC_SRAM1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM1EN) != 0U) + +#define __HAL_RCC_SRAM2_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB3_Clock_Enable_Disable_Status AHB3 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the AHB3 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_RNG_IS_CLK_ENABLED() (READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_RNGEN) != 0U) + +#define __HAL_RCC_HASH_IS_CLK_ENABLED() (READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_HASHEN) != 0U) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_IS_CLK_ENABLED() (READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_CRYPEN) != 0U) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_IS_CLK_ENABLED() (READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_SAESEN) != 0U) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_IS_CLK_ENABLED() (READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PKAEN) != 0U) +#endif /* PKA */ + +/** + * @} + */ + +/** @defgroup RCC_AHB4_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. + * @{ + */ + +#define __HAL_RCC_GPIOA_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN) != 0U) + +#define __HAL_RCC_GPIOB_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOBEN) != 0U) + +#define __HAL_RCC_GPIOC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOCEN) != 0U) + +#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN) != 0U) + +#define __HAL_RCC_GPIOE_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN) != 0U) + +#define __HAL_RCC_GPIOF_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOFEN) != 0U) + +#define __HAL_RCC_GPIOG_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOGEN) != 0U) + +#define __HAL_RCC_GPIOH_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOHEN) != 0U) + +#define __HAL_RCC_GPIOM_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOMEN) != 0U) + +#define __HAL_RCC_GPION_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIONEN) != 0U) + +#define __HAL_RCC_GPIOO_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOOEN) != 0U) + +#define __HAL_RCC_GPIOP_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOPEN) != 0U) + +#define __HAL_RCC_CRC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_CRCEN) != 0U) + +#define __HAL_RCC_BKPRAM_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_BKPRAMEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB5_Clock_Enable_Disable_Status AHB5 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the AHB5 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_HPDMA1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_HPDMA1EN) != 0U) + +#define __HAL_RCC_DMA2D_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_DMA2DEN) != 0U) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_JPEGEN) != 0U) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_FMCEN) != 0U) + +#define __HAL_RCC_XSPI1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPI1EN) != 0U) + +#define __HAL_RCC_SDMMC1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_SDMMC1EN) != 0U) + +#define __HAL_RCC_XSPI2_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPI2EN) != 0U) + +#define __HAL_RCC_XSPIM_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_XSPIMEN) != 0U) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_GFXMMUEN) != 0U) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_IS_CLK_ENABLED() (READ_BIT(RCC->AHB5ENR, RCC_AHB5ENR_GPU2DEN) != 0U) +#endif /* GPU2D */ + +/** + * @} + */ + +/** @defgroup RCC_APB1_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->APB1ENR1, RCC_APB1ENR1_TIM2EN) != 0U) + +#define __HAL_RCC_TIM3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM3EN) != 0U) + +#define __HAL_RCC_TIM4_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM4EN) != 0U) + +#define __HAL_RCC_TIM5_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM5EN) != 0U) + +#define __HAL_RCC_TIM6_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN) != 0U) + +#define __HAL_RCC_TIM7_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN) != 0U) + +#define __HAL_RCC_TIM12_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM12EN) != 0U) + +#define __HAL_RCC_TIM13_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM13EN) != 0U) + +#define __HAL_RCC_TIM14_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_TIM14EN) != 0U) + +#define __HAL_RCC_LPTIM1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_LPTIM1EN) != 0U) + +#define __HAL_RCC_WWDG_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_WWDGEN) != 0U) + +#define __HAL_RCC_SPI2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPI2EN) != 0U) + +#define __HAL_RCC_SPI3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPI3EN) != 0U) + +#define __HAL_RCC_SPDIFRX_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_SPDIFRXEN) != 0U) + +#define __HAL_RCC_USART2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USART2EN) != 0U) + +#define __HAL_RCC_USART3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USART3EN) != 0U) + +#define __HAL_RCC_UART4_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART4EN) != 0U) + +#define __HAL_RCC_UART5_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART5EN) != 0U) + +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C1_I3C1EN) != 0U) + +#define __HAL_RCC_I2C2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C2EN) != 0U) + +#define __HAL_RCC_I2C3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C3EN) != 0U) + +#define __HAL_RCC_I3C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_I2C1_I3C1EN) != 0U) + +#define __HAL_RCC_CEC_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_CECEN) != 0U) + +#define __HAL_RCC_UART7_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART7EN) != 0U) + +#define __HAL_RCC_UART8_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR1, RCC_APB1ENR1_UART8EN) != 0U) + +#define __HAL_RCC_CRS_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR2, RCC_APB1ENR2_CRSEN) != 0U) + +#define __HAL_RCC_MDIOS_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR2, RCC_APB1ENR2_MDIOSEN) != 0U) + +#define __HAL_RCC_FDCAN_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR2, RCC_APB1ENR2_FDCANEN) != 0U) + +#define __HAL_RCC_UCPD1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1ENR2, RCC_APB1ENR2_UCPD1EN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB2_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_USART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN) != 0U) + +#define __HAL_RCC_SPI1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN) != 0U) + +#define __HAL_RCC_SPI4_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN) != 0U) + +#define __HAL_RCC_TIM15_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN) != 0U) + +#define __HAL_RCC_TIM16_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN) != 0U) + +#define __HAL_RCC_TIM17_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN) != 0U) + +#define __HAL_RCC_TIM9_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM9EN) != 0U) + +#define __HAL_RCC_SPI5_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN) != 0U) + +#define __HAL_RCC_SAI1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN) != 0U) + +#define __HAL_RCC_SAI2_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB4_Clock_Enable_Disable_Status APB4 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the APB4 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->APB4ENR, RCC_APB4ENR_SBSEN) != 0U) + +#define __HAL_RCC_LPUART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_LPUART1EN) != 0U) + +#define __HAL_RCC_SPI6_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_SPI6EN) != 0U) + +#define __HAL_RCC_LPTIM2_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM2EN) != 0U) + +#define __HAL_RCC_LPTIM3_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM3EN) != 0U) + +#define __HAL_RCC_LPTIM4_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM4EN) != 0U) + +#define __HAL_RCC_LPTIM5_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_LPTIM5EN) != 0U) + +#define __HAL_RCC_VREF_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_VREFEN) != 0U) + +#define __HAL_RCC_RTCAPB_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_RTCAPBEN) != 0U) + +#define __HAL_RCC_DTS_IS_CLK_ENABLED() (READ_BIT(RCC->APB4ENR, RCC_APB4ENR_DTSEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB5_Clock_Enable_Disable_Status APB5 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the APB5 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_LTDC_IS_CLK_ENABLED() (READ_BIT(RCC->APB5ENR, RCC_APB5ENR_LTDCEN) != 0U) + +#define __HAL_RCC_DCMIPP_IS_CLK_ENABLED() (READ_BIT(RCC->APB5ENR, RCC_APB5ENR_DCMIPPEN) != 0U) + +#define __HAL_RCC_GFXTIM_IS_CLK_ENABLED() (READ_BIT(RCC->APB5ENR, RCC_APB5ENR_GFXTIMEN) != 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, 0x8E008030UL) +#define __HAL_RCC_AHB1_RELEASE_RESET() WRITE_REG(RCC->AHB1RSTR, 0UL) + +#define __HAL_RCC_GPDMA1_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_GPDMA1RST) +#define __HAL_RCC_GPDMA1_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_GPDMA1RST) + +#define __HAL_RCC_ADC12_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ADC12RST) +#define __HAL_RCC_ADC12_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ADC12RST) + +#if defined(ETH) +#define __HAL_RCC_ETH1_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ETH1RST) +#define __HAL_RCC_ETH1_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ETH1RST) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_OTGHSRST) +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_OTGHSRST) + +#define __HAL_RCC_USB_OTG_FS_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_OTGFSRST) +#define __HAL_RCC_USB_OTG_FS_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_OTGFSRST) + +#define __HAL_RCC_USBPHYC_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_USBPHYCRST) +#define __HAL_RCC_USBPHYC_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_USBPHYCRST) + +#define __HAL_RCC_ADF1_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ADF1RST) +#define __HAL_RCC_ADF1_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ADF1RST) + +/** + * @} + */ + +/** @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, 0x00004202UL) +#define __HAL_RCC_AHB2_RELEASE_RESET() WRITE_REG(RCC->AHB2RSTR, 0UL) + +#define __HAL_RCC_PSSI_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_PSSIRST) +#define __HAL_RCC_PSSI_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_PSSIRST) + +#define __HAL_RCC_SDMMC2_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_SDMMC2RST) +#define __HAL_RCC_SDMMC2_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_SDMMC2RST) + +#define __HAL_RCC_CORDIC_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_CORDICRST) +#define __HAL_RCC_CORDIC_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_CORDICRST) + +/** + * @} + */ + +/** @defgroup RCC_AHB3_Force_Release_Reset AHB3 Peripheral Force Release Reset + * @brief Force or release AHB3 peripheral reset. + * @{ + */ + +#define __HAL_RCC_AHB3_FORCE_RESET() WRITE_REG(RCC->AHB3RSTR, 0x00000057UL) +#define __HAL_RCC_AHB3_RELEASE_RESET() WRITE_REG(RCC->AHB3RSTR, 0UL) + +#define __HAL_RCC_RNG_FORCE_RESET() SET_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_RNGRST) +#define __HAL_RCC_RNG_RELEASE_RESET() CLEAR_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_RNGRST) + +#define __HAL_RCC_HASH_FORCE_RESET() SET_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_HASHRST) +#define __HAL_RCC_HASH_RELEASE_RESET() CLEAR_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_HASHRST) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_FORCE_RESET() SET_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_CRYPRST) +#define __HAL_RCC_CRYP_RELEASE_RESET() CLEAR_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_CRYPRST) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_FORCE_RESET() SET_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_SAESRST) +#define __HAL_RCC_SAES_RELEASE_RESET() CLEAR_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_SAESRST) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_FORCE_RESET() SET_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_PKARST) +#define __HAL_RCC_PKA_RELEASE_RESET() CLEAR_BIT(RCC->AHB3RSTR, RCC_AHB3RSTR_PKARST) +#endif /* PKA */ + +/** + * @} + */ + +/** @defgroup RCC_AHB4_Force_Release_Reset AHB4 Peripheral Force Release Reset + * @brief Force or release AHB4 peripheral reset. + * @{ + */ + +#define __HAL_RCC_AHB4_FORCE_RESET() WRITE_REG(RCC->AHB4RSTR, 0x0008B0FFUL) +#define __HAL_RCC_AHB4_RELEASE_RESET() WRITE_REG(RCC->AHB4RSTR, 0UL) + +#define __HAL_RCC_GPIOA_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOARST) +#define __HAL_RCC_GPIOA_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOARST) + +#define __HAL_RCC_GPIOB_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOBRST) +#define __HAL_RCC_GPIOB_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOBRST) + +#define __HAL_RCC_GPIOC_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOCRST) +#define __HAL_RCC_GPIOC_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOCRST) + +#define __HAL_RCC_GPIOD_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIODRST) +#define __HAL_RCC_GPIOD_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIODRST) + +#define __HAL_RCC_GPIOE_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOERST) +#define __HAL_RCC_GPIOE_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOERST) + +#define __HAL_RCC_GPIOF_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOFRST) +#define __HAL_RCC_GPIOF_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOFRST) + +#define __HAL_RCC_GPIOG_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOGRST) +#define __HAL_RCC_GPIOG_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOGRST) + +#define __HAL_RCC_GPIOH_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOHRST) +#define __HAL_RCC_GPIOH_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOHRST) + +#define __HAL_RCC_GPIOM_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOMRST) +#define __HAL_RCC_GPIOM_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOMRST) + +#define __HAL_RCC_GPION_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIONRST) +#define __HAL_RCC_GPION_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIONRST) + +#define __HAL_RCC_GPIOO_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOORST) +#define __HAL_RCC_GPIOO_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOORST) + +#define __HAL_RCC_GPIOP_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOPRST) +#define __HAL_RCC_GPIOP_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_GPIOPRST) + +#define __HAL_RCC_CRC_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_CRCRST) +#define __HAL_RCC_CRC_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_CRCRST) + +/** + * @} + */ + +/** @defgroup RCC_AHB5_Force_Release_Reset AHB5 Peripheral Force Release Reset + * @brief Force or release AHB5 peripheral reset. + * @{ + */ + +#define __HAL_RCC_AHB5_FORCE_RESET() WRITE_REG(RCC->AHB5RSTR, 0x0018513BUL) +#define __HAL_RCC_AHB5_RELEASE_RESET() WRITE_REG(RCC->AHB5RSTR, 0UL) + +#define __HAL_RCC_HPDMA1_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_HPDMA1RST) +#define __HAL_RCC_HPDMA1_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_HPDMA1RST) + +#define __HAL_RCC_DMA2D_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_DMA2DRST) +#define __HAL_RCC_DMA2D_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_DMA2DRST) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_JPEGRST) +#define __HAL_RCC_JPEG_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_JPEGRST) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_FMCRST) +#define __HAL_RCC_FMC_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_FMCRST) + +#define __HAL_RCC_XSPI1_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_XSPI1RST) +#define __HAL_RCC_XSPI1_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_XSPI1RST) + +#define __HAL_RCC_SDMMC1_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_SDMMC1RST) +#define __HAL_RCC_SDMMC1_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_SDMMC1RST) + +#define __HAL_RCC_XSPI2_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_XSPI2RST) +#define __HAL_RCC_XSPI2_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_XSPI2RST) + +#define __HAL_RCC_XSPIM_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_XSPIMRST) +#define __HAL_RCC_XSPIM_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_XSPIMRST) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_GFXMMURST) +#define __HAL_RCC_GFXMMU_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_GFXMMURST) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_FORCE_RESET() SET_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_GPU2DRST) +#define __HAL_RCC_GPU2D_RELEASE_RESET() CLEAR_BIT(RCC->AHB5RSTR, RCC_AHB5RSTR_GPU2DRST) +#endif /* GPU2D */ + +/** + * @} + */ + +/** @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->APB1RSTR1, 0xC8FFC3FFUL); \ + WRITE_REG(RCC->APB1RSTR2, 0x08000122UL); \ + } while(0) +#define __HAL_RCC_APB1_RELEASE_RESET() do { \ + WRITE_REG(RCC->APB1RSTR1, 0UL); \ + WRITE_REG(RCC->APB1RSTR2, 0UL); \ + } while(0) + +#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM2RST) +#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM2RST) + +#define __HAL_RCC_TIM3_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM3RST) +#define __HAL_RCC_TIM3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM3RST) + +#define __HAL_RCC_TIM4_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM4RST) +#define __HAL_RCC_TIM4_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM4RST) + +#define __HAL_RCC_TIM5_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM5RST) +#define __HAL_RCC_TIM5_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM5RST) + +#define __HAL_RCC_TIM6_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM6RST) +#define __HAL_RCC_TIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM6RST) + +#define __HAL_RCC_TIM7_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM7RST) +#define __HAL_RCC_TIM7_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM7RST) + +#define __HAL_RCC_TIM12_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM12RST) +#define __HAL_RCC_TIM12_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM12RST) + +#define __HAL_RCC_TIM13_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM13RST) +#define __HAL_RCC_TIM13_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM13RST) + +#define __HAL_RCC_TIM14_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM14RST) +#define __HAL_RCC_TIM14_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_TIM14RST) + +#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_LPTIM1RST) +#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_LPTIM1RST) + +#define __HAL_RCC_SPI2_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_SPI2RST) +#define __HAL_RCC_SPI2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_SPI2RST) + +#define __HAL_RCC_SPI3_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_SPI3RST) +#define __HAL_RCC_SPI3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_SPI3RST) + +#define __HAL_RCC_SPDIFRX_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_SPDIFRXRST) +#define __HAL_RCC_SPDIFRX_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_SPDIFRXRST) + +#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_USART2RST) +#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_USART2RST) + +#define __HAL_RCC_USART3_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_USART3RST) +#define __HAL_RCC_USART3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_USART3RST) + +#define __HAL_RCC_UART4_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART4RST) +#define __HAL_RCC_UART4_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART4RST) + +#define __HAL_RCC_UART5_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART5RST) +#define __HAL_RCC_UART5_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART5RST) + +#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C1_I3C1RST) +#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C1_I3C1RST) + +#define __HAL_RCC_I2C2_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C2RST) +#define __HAL_RCC_I2C2_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C2RST) + +#define __HAL_RCC_I2C3_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C3RST) +#define __HAL_RCC_I2C3_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C3RST) + +#define __HAL_RCC_I3C1_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C1_I3C1RST) +#define __HAL_RCC_I3C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_I2C1_I3C1RST) + +#define __HAL_RCC_CEC_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_CECRST) +#define __HAL_RCC_CEC_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_CECRST) + +#define __HAL_RCC_UART7_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART7RST) +#define __HAL_RCC_UART7_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART7RST) + +#define __HAL_RCC_UART8_FORCE_RESET() SET_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART8RST) +#define __HAL_RCC_UART8_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR1, RCC_APB1RSTR1_UART8RST) + +#define __HAL_RCC_CRS_FORCE_RESET() SET_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_CRSRST) +#define __HAL_RCC_CRS_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_CRSRST) + +#define __HAL_RCC_MDIOS_FORCE_RESET() SET_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_MDIOSRST) +#define __HAL_RCC_MDIOS_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_MDIOSRST) + +#define __HAL_RCC_FDCAN_FORCE_RESET() SET_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_FDCANRST) +#define __HAL_RCC_FDCAN_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_FDCANRST) + +#define __HAL_RCC_UCPD1_FORCE_RESET() SET_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_UCPD1RST) +#define __HAL_RCC_UCPD1_RELEASE_RESET() CLEAR_BIT(RCC->APB1RSTR2, RCC_APB1RSTR2_UCPD1RST) + +/** + * @} + */ + +/** @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, 0xC8FFC3FFUL) +#define __HAL_RCC_APB2_RELEASE_RESET() WRITE_REG(RCC->APB2RSTR, 0UL) + +#define __HAL_RCC_TIM1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM1RST) +#define __HAL_RCC_TIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM1RST) + +#define __HAL_RCC_USART1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_USART1RST) +#define __HAL_RCC_USART1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_USART1RST) + +#define __HAL_RCC_SPI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI1RST) +#define __HAL_RCC_SPI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI1RST) + +#define __HAL_RCC_SPI4_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI4RST) +#define __HAL_RCC_SPI4_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI4RST) + +#define __HAL_RCC_TIM15_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM15RST) +#define __HAL_RCC_TIM15_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM15RST) + +#define __HAL_RCC_TIM16_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM16RST) +#define __HAL_RCC_TIM16_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM16RST) + +#define __HAL_RCC_TIM17_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM17RST) +#define __HAL_RCC_TIM17_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM17RST) + +#define __HAL_RCC_TIM9_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM9RST) +#define __HAL_RCC_TIM9_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM9RST) + +#define __HAL_RCC_SPI5_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI5RST) +#define __HAL_RCC_SPI5_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI5RST) + +#define __HAL_RCC_SAI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI1RST) +#define __HAL_RCC_SAI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI1RST) + +#define __HAL_RCC_SAI2_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI2RST) +#define __HAL_RCC_SAI2_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI2RST) + +/** + * @} + */ + +/** @defgroup RCC_APB4_Force_Release_Reset APB4 Peripheral Force Release Reset + * @brief Force or release APB4 peripheral reset. + * @{ + */ + +#define __HAL_RCC_APB4_FORCE_RESET() WRITE_REG(RCC->APB4RSTR, 0x04009E2AUL) +#define __HAL_RCC_APB4_RELEASE_RESET() WRITE_REG(RCC->APB4RSTR, 0UL) + +#define __HAL_RCC_SBS_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_SBSRST) +#define __HAL_RCC_SBS_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_SBSRST) + +#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPUART1RST) +#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPUART1RST) + +#define __HAL_RCC_SPI6_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_SPI6RST) +#define __HAL_RCC_SPI6_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_SPI6RST) + +#define __HAL_RCC_LPTIM2_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM2RST) +#define __HAL_RCC_LPTIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM2RST) + +#define __HAL_RCC_LPTIM3_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM3RST) +#define __HAL_RCC_LPTIM3_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM3RST) + +#define __HAL_RCC_LPTIM4_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM4RST) +#define __HAL_RCC_LPTIM4_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM4RST) + +#define __HAL_RCC_LPTIM5_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM5RST) +#define __HAL_RCC_LPTIM5_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_LPTIM5RST) + +#define __HAL_RCC_VREF_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_VREFRST) +#define __HAL_RCC_VREF_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_VREFRST) + +#define __HAL_RCC_DTS_FORCE_RESET() SET_BIT(RCC->APB4RSTR, RCC_APB4RSTR_DTSRST) +#define __HAL_RCC_DTS_RELEASE_RESET() CLEAR_BIT(RCC->APB4RSTR, RCC_APB4RSTR_DTSRST) + +/** + * @} + */ + +/** @defgroup RCC_APB5_Force_Release_Reset APB5 Peripheral Force Release Reset + * @brief Force or release APB5 peripheral reset. + * @{ + */ + +#define __HAL_RCC_APB5_FORCE_RESET() WRITE_REG(RCC->APB5RSTR, 0x00000016UL) +#define __HAL_RCC_APB5_RELEASE_RESET() WRITE_REG(RCC->APB5RSTR, 0UL) + +#define __HAL_RCC_LTDC_FORCE_RESET() SET_BIT(RCC->APB5RSTR, RCC_APB5RSTR_LTDCRST) +#define __HAL_RCC_LTDC_RELEASE_RESET() CLEAR_BIT(RCC->APB5RSTR, RCC_APB5RSTR_LTDCRST) + +#define __HAL_RCC_DCMIPP_FORCE_RESET() SET_BIT(RCC->APB5RSTR, RCC_APB5RSTR_DCMIPPRST) +#define __HAL_RCC_DCMIPP_RELEASE_RESET() CLEAR_BIT(RCC->APB5RSTR, RCC_APB5RSTR_DCMIPPRST) + +#define __HAL_RCC_GFXTIM_FORCE_RESET() SET_BIT(RCC->APB5RSTR, RCC_APB5RSTR_GFXTIMRST) +#define __HAL_RCC_GFXTIM_RELEASE_RESET() CLEAR_BIT(RCC->APB5RSTR, RCC_APB5RSTR_GFXTIMRST) + +/** + * @} + */ + + +/** @defgroup RCC_AHB1_Clock_Sleep_Enable_Disable AHB1 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_ADC12_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ADC12LPEN) +#if defined(ETH) +#define __HAL_RCC_ETH1MAC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1MACLPEN) + +#define __HAL_RCC_ETH1TX_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1TXLPEN) + +#define __HAL_RCC_ETH1RX_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1RXLPEN) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_OTGHSLPEN) + +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_OTGFSLPEN) + +#define __HAL_RCC_USBPHYC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_USBPHYCLPEN) + +#define __HAL_RCC_ADF1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ADF1LPEN) + + +#define __HAL_RCC_GPDMA1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_GPDMA1LPEN) + +#define __HAL_RCC_ADC12_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ADC12LPEN) + +#if defined(ETH) +#define __HAL_RCC_ETH1MAC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1MACLPEN) + +#define __HAL_RCC_ETH1TX_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1TXLPEN) + +#define __HAL_RCC_ETH1RX_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1RXLPEN) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_OTGHSLPEN) + +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_OTGFSLPEN) + +#define __HAL_RCC_USBPHYC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_USBPHYCLPEN) + +#define __HAL_RCC_ADF1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ADF1LPEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB2_Clock_Sleep_Enable_Disable AHB2 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_PSSI_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_PSSILPEN) + +#define __HAL_RCC_SDMMC2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SDMMC2LPEN) + +#define __HAL_RCC_CORDIC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_CORDICLPEN) + +#define __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM1LPEN) + +#define __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM2LPEN) + + +#define __HAL_RCC_PSSI_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_PSSILPEN) + +#define __HAL_RCC_SDMMC2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SDMMC2LPEN) + +#define __HAL_RCC_CORDIC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_CORDICLPEN) + +#define __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM1LPEN) + +#define __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM2LPEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB3_Clock_Sleep_Enable_Disable AHB3 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB3 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_RNG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_RNGLPEN) + +#define __HAL_RCC_HASH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_HASHLPEN) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_CRYPLPEN) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_SAESLPEN) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_PKALPEN) +#endif /* PKA */ + + +#define __HAL_RCC_RNG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_RNGLPEN) + +#define __HAL_RCC_HASH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_HASHLPEN) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_CRYPLPEN) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_SAESLPEN) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_PKALPEN) +#endif /* PKA */ + +/** + * @} + */ + +/** @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 Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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->AHB4LPENR, RCC_AHB4LPENR_GPIOALPEN) + +#define __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOBLPEN) + +#define __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOCLPEN) + +#define __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIODLPEN) + +#define __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOELPEN) + +#define __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOFLPEN) + +#define __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOGLPEN) + +#define __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOHLPEN) + +#define __HAL_RCC_GPIOM_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOMLPEN) + +#define __HAL_RCC_GPION_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIONLPEN) + +#define __HAL_RCC_GPIOO_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOOLPEN) + +#define __HAL_RCC_GPIOP_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOPLPEN) + +#define __HAL_RCC_CRC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_CRCLPEN) + +#define __HAL_RCC_BKPRAM_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_BKPRAMLPEN) + + +#define __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOALPEN) + +#define __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOBLPEN) + +#define __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOCLPEN) + +#define __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIODLPEN) + +#define __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOELPEN) + +#define __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOFLPEN) + +#define __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOGLPEN) + +#define __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOHLPEN) + +#define __HAL_RCC_GPIOM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOMLPEN) + +#define __HAL_RCC_GPION_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIONLPEN) + +#define __HAL_RCC_GPIOO_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOOLPEN) + +#define __HAL_RCC_GPIOP_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOPLPEN) + +#define __HAL_RCC_CRC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_CRCLPEN) + +#define __HAL_RCC_BKPRAM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_BKPRAMLPEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB5_Clock_Sleep_Enable_Disable AHB5 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_HPDMA1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_HPDMA1LPEN) + +#define __HAL_RCC_DMA2D_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DMA2DLPEN) + +#define __HAL_RCC_FLASH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_FLASHLPEN) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_JPEGLPEN) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_FMCLPEN) + +#define __HAL_RCC_XSPI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPI1LPEN) + +#define __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_SDMMC1LPEN) + +#define __HAL_RCC_XSPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPI2LPEN) + +#define __HAL_RCC_XSPIM_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPIMLPEN) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_GFXMMULPEN) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_GPU2DLPEN) +#endif /* GPU2D */ + +#define __HAL_RCC_DTCM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DTCM1LPEN) + +#define __HAL_RCC_DTCM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DTCM2LPEN) + +#define __HAL_RCC_ITCM_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_ITCMLPEN) + +#define __HAL_RCC_AXISRAM_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_AXISRAMLPEN) + + +#define __HAL_RCC_HPDMA1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_HPDMA1LPEN) + +#define __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DMA2DLPEN) + +#define __HAL_RCC_FLASH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_FLASHLPEN) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_JPEGLPEN) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_FMCLPEN) + +#define __HAL_RCC_XSPI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPI1LPEN) + +#define __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_SDMMC1LPEN) + +#define __HAL_RCC_XSPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPI2LPEN) + +#define __HAL_RCC_XSPIM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPIMLPEN) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_GFXMMULPEN) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_GPU2DLPEN) +#endif /* GPU2D */ + +#define __HAL_RCC_DTCM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DTCM1LPEN) + +#define __HAL_RCC_DTCM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DTCM2LPEN) + +#define __HAL_RCC_ITCM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_ITCMLPEN) + +#define __HAL_RCC_AXISRAM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_AXISRAMLPEN) + +/** + * @} + */ + +/** @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 Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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->APB1LPENR1, RCC_APB1LPENR1_TIM2LPEN) + +#define __HAL_RCC_TIM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM3LPEN) + +#define __HAL_RCC_TIM4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM4LPEN) + +#define __HAL_RCC_TIM5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM5LPEN) + +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM6LPEN) + +#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM7LPEN) + +#define __HAL_RCC_TIM12_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM12LPEN) + +#define __HAL_RCC_TIM13_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM13LPEN) + +#define __HAL_RCC_TIM14_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM14LPEN) + +#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_LPTIM1LPEN) + +#define __HAL_RCC_WWDG_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_WWDGLPEN) + +#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPI2LPEN) + +#define __HAL_RCC_SPI3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPI3LPEN) + +#define __HAL_RCC_SPDIFRX_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPDIFRXLPEN) + +#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_USART2LPEN) + +#define __HAL_RCC_USART3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_USART3LPEN) + +#define __HAL_RCC_UART4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART4LPEN) + +#define __HAL_RCC_UART5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART5LPEN) + +#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C1_I3C1LPEN) + +#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C2LPEN) + +#define __HAL_RCC_I2C3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C3LPEN) + +#define __HAL_RCC_I3C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C1_I3C1LPEN) + +#define __HAL_RCC_CEC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_CECLPEN) + +#define __HAL_RCC_UART7_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART7LPEN) + +#define __HAL_RCC_UART8_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART8LPEN) + +#define __HAL_RCC_CRS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_CRSLPEN) + +#define __HAL_RCC_MDIOS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_MDIOSLPEN) + +#define __HAL_RCC_FDCAN_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_FDCANLPEN) + +#define __HAL_RCC_UCPD1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_UCPD1LPEN) + + +#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM2LPEN) + +#define __HAL_RCC_TIM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM3LPEN) + +#define __HAL_RCC_TIM4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM4LPEN) + +#define __HAL_RCC_TIM5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM5LPEN) + +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM6LPEN) + +#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM7LPEN) + +#define __HAL_RCC_TIM12_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM12LPEN) + +#define __HAL_RCC_TIM13_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM13LPEN) + +#define __HAL_RCC_TIM14_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM14LPEN) + +#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_LPTIM1LPEN) + +#define __HAL_RCC_WWDG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_WWDGLPEN) + +#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPI2LPEN) + +#define __HAL_RCC_SPI3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPI3LPEN) + +#define __HAL_RCC_SPDIFRX_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPDIFRXLPEN) + +#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_USART2LPEN) + +#define __HAL_RCC_USART3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_USART3LPEN) + +#define __HAL_RCC_UART4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART4LPEN) + +#define __HAL_RCC_UART5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART5LPEN) + +#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C1_I3C1LPEN) + +#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C2LPEN) + +#define __HAL_RCC_I2C3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C3LPEN) + +#define __HAL_RCC_I3C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C1_I3C1LPEN) + +#define __HAL_RCC_CEC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_CECLPEN) + +#define __HAL_RCC_UART7_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART7LPEN) + +#define __HAL_RCC_UART8_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART8LPEN) + +#define __HAL_RCC_CRS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_CRSLPEN) + +#define __HAL_RCC_MDIOS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_MDIOSLPEN) + +#define __HAL_RCC_FDCAN_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_FDCANLPEN) + +#define __HAL_RCC_UCPD1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_UCPD1LPEN) + +/** + * @} + */ + +/** @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 Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_USART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN) + +#define __HAL_RCC_SPI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI1LPEN) + +#define __HAL_RCC_SPI4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI4LPEN) + +#define __HAL_RCC_TIM15_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM15LPEN) + +#define __HAL_RCC_TIM16_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM16LPEN) + +#define __HAL_RCC_TIM17_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM17LPEN) + +#define __HAL_RCC_TIM9_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM9LPEN) + +#define __HAL_RCC_SPI5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI5LPEN) + +#define __HAL_RCC_SAI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI1LPEN) + +#define __HAL_RCC_SAI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI2LPEN) + + +#define __HAL_RCC_TIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM1LPEN) + +#define __HAL_RCC_USART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN) + +#define __HAL_RCC_SPI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI1LPEN) + +#define __HAL_RCC_SPI4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI4LPEN) + +#define __HAL_RCC_TIM15_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM15LPEN) + +#define __HAL_RCC_TIM16_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM16LPEN) + +#define __HAL_RCC_TIM17_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM17LPEN) + +#define __HAL_RCC_TIM9_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM9LPEN) + +#define __HAL_RCC_SPI5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI5LPEN) + +#define __HAL_RCC_SAI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI1LPEN) + +#define __HAL_RCC_SAI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI2LPEN) + +/** + * @} + */ + +/** @defgroup RCC_APB4_Clock_Sleep_Enable_Disable APB4 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB4 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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->APB4LPENR, RCC_APB4LPENR_SBSLPEN) + +#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPUART1LPEN) + +#define __HAL_RCC_SPI6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_SPI6LPEN) + +#define __HAL_RCC_LPTIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM2LPEN) + +#define __HAL_RCC_LPTIM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM3LPEN) + +#define __HAL_RCC_LPTIM4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM4LPEN) + +#define __HAL_RCC_LPTIM5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM5LPEN) + +#define __HAL_RCC_VREF_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_VREFLPEN) + +#define __HAL_RCC_RTCAPB_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_RTCAPBLPEN) + +#define __HAL_RCC_DTS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB4LPENR, RCC_APB4LPENR_DTSLPEN) + + +#define __HAL_RCC_SBS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_SBSLPEN) + +#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPUART1LPEN) + +#define __HAL_RCC_SPI6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_SPI6LPEN) + +#define __HAL_RCC_LPTIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM2LPEN) + +#define __HAL_RCC_LPTIM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM3LPEN) + +#define __HAL_RCC_LPTIM4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM4LPEN) + +#define __HAL_RCC_LPTIM5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM5LPEN) + +#define __HAL_RCC_VREF_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_VREFLPEN) + +#define __HAL_RCC_RTCAPB_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_RTCAPBLPEN) + +#define __HAL_RCC_DTS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB4LPENR, RCC_APB4LPENR_DTSLPEN) + +/** + * @} + */ + +/** @defgroup RCC_APB5_Clock_Sleep_Enable_Disable APB5 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB5 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_LTDC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB5LPENR, RCC_APB5LPENR_LTDCLPEN) + +#define __HAL_RCC_DCMIPP_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB5LPENR, RCC_APB5LPENR_DCMIPPLPEN) + +#define __HAL_RCC_GFXTIM_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB5LPENR, RCC_APB5LPENR_GFXTIMLPEN) + + +#define __HAL_RCC_LTDC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB5LPENR, RCC_APB5LPENR_LTDCLPEN) + +#define __HAL_RCC_DCMIPP_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB5LPENR, RCC_APB5LPENR_DCMIPPLPEN) + +#define __HAL_RCC_GFXTIM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB5LPENR, RCC_APB5LPENR_GFXTIMLPEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB1_Clock_Sleep_Enable_Disable_Status AHB1 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the AHB1 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_GPDMA1LPEN) != 0U) + +#define __HAL_RCC_ADC12_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ADC12LPEN) != 0U) +#if defined(ETH) +#define __HAL_RCC_ETH1MAC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1MACLPEN) != 0U) + +#define __HAL_RCC_ETH1TX_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1TXLPEN) != 0U) + +#define __HAL_RCC_ETH1RX_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1RXLPEN) != 0U) +#endif /* ETH */ + +#define __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_OTGHSLPEN) != 0U) + +#define __HAL_RCC_USB_OTG_FS_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_OTGFSLPEN) != 0U) + +#define __HAL_RCC_USBPHYC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_USBPHYCLPEN) != 0U) + +#define __HAL_RCC_ADF1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ADF1LPEN) != 0U) +/** + * @} + */ + +/** @defgroup RCC_AHB2_Clock_Sleep_Enable_Disable_Status AHB2 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the AHB2 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_PSSI_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_PSSILPEN) != 0U) + +#define __HAL_RCC_SDMMC2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SDMMC2LPEN) != 0U) + +#define __HAL_RCC_CORDIC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_CORDICLPEN) != 0U) + +#define __HAL_RCC_SRAM1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM1LPEN) != 0U) + +#define __HAL_RCC_SRAM2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM2LPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB3_Clock_Sleep_Enable_Disable_Status AHB3 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the AHB3 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_RNG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_RNGLPEN) != 0U) + +#define __HAL_RCC_HASH_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_HASHLPEN) != 0U) + +#if defined(CRYP) +#define __HAL_RCC_CRYP_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_CRYPLPEN) != 0U) +#endif /* CRYP */ + +#if defined(SAES) +#define __HAL_RCC_SAES_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_SAESLPEN) != 0U) +#endif /* SAES */ + +#if defined(PKA) +#define __HAL_RCC_PKA_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB3LPENR, RCC_AHB3LPENR_PKALPEN) != 0U) +#endif /* PKA */ + +/** + * @} + */ + +/** @defgroup RCC_AHB4_Clock_Sleep_Enable_Disable_Status AHB4 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the AHB4 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOALPEN) != 0U) + +#define __HAL_RCC_GPIOB_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOBLPEN) != 0U) + +#define __HAL_RCC_GPIOC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOCLPEN) != 0U) + +#define __HAL_RCC_GPIOD_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIODLPEN) != 0U) + +#define __HAL_RCC_GPIOE_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOELPEN) != 0U) + +#define __HAL_RCC_GPIOF_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOFLPEN) != 0U) + +#define __HAL_RCC_GPIOG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOGLPEN) != 0U) + +#define __HAL_RCC_GPIOH_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOHLPEN) != 0U) + +#define __HAL_RCC_GPIOM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOMLPEN) != 0U) + +#define __HAL_RCC_GPION_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIONLPEN) != 0U) + +#define __HAL_RCC_GPIOO_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOOLPEN) != 0U) + +#define __HAL_RCC_GPIOP_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOPLPEN) != 0U) + +#define __HAL_RCC_CRC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_CRCLPEN) != 0U) + +#define __HAL_RCC_BKPRAM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_BKPRAMLPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB5_Clock_Sleep_Enable_Disable_Status AHB5 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the AHB5 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_HPDMA1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_HPDMA1LPEN) != 0U) + +#define __HAL_RCC_DMA2D_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DMA2DLPEN) != 0U) + +#define __HAL_RCC_FLASH_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_FLASHLPEN) != 0U) + +#if defined(JPEG) +#define __HAL_RCC_JPEG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_JPEGLPEN) != 0U) +#endif /* JPEG */ + +#define __HAL_RCC_FMC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_FMCLPEN) != 0U) + +#define __HAL_RCC_XSPI1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPI1LPEN) != 0U) + +#define __HAL_RCC_SDMMC1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_SDMMC1LPEN) != 0U) + +#define __HAL_RCC_XSPI2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPI2LPEN) != 0U) + +#define __HAL_RCC_XSPIM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_XSPIMLPEN) != 0U) + +#if defined(GFXMMU) +#define __HAL_RCC_GFXMMU_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_GFXMMULPEN) != 0U) +#endif /* GFXMMU */ + +#if defined(GPU2D) +#define __HAL_RCC_GPU2D_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_GPU2DLPEN) != 0U) +#endif /* GPU2D */ + +#define __HAL_RCC_DTCM1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DTCM1LPEN) != 0U) + +#define __HAL_RCC_DTCM2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_DTCM2LPEN) != 0U) + +#define __HAL_RCC_ITCM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_ITCMLPEN) != 0U) + +#define __HAL_RCC_AXISRAM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->AHB5LPENR, RCC_AHB5LPENR_AXISRAMLPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Sleep_Enable_Disable_Status APB1 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the APB1 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM2LPEN) != 0U) + +#define __HAL_RCC_TIM3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM3LPEN) != 0U) + +#define __HAL_RCC_TIM4_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM4LPEN) != 0U) + +#define __HAL_RCC_TIM5_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM5LPEN) != 0U) + +#define __HAL_RCC_TIM6_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM6LPEN) != 0U) + +#define __HAL_RCC_TIM7_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM7LPEN) != 0U) + +#define __HAL_RCC_TIM12_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM12LPEN) != 0U) + +#define __HAL_RCC_TIM13_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM13LPEN) != 0U) + +#define __HAL_RCC_TIM14_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_TIM14LPEN) != 0U) + +#define __HAL_RCC_LPTIM1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_LPTIM1LPEN) != 0U) + +#define __HAL_RCC_WWDG_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_WWDGLPEN) != 0U) + +#define __HAL_RCC_SPI2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPI2LPEN) != 0U) + +#define __HAL_RCC_SPI3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPI3LPEN) != 0U) + +#define __HAL_RCC_SPDIFRX_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_SPDIFRXLPEN) != 0U) + +#define __HAL_RCC_USART2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_USART2LPEN) != 0U) + +#define __HAL_RCC_USART3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_USART3LPEN) != 0U) + +#define __HAL_RCC_UART4_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART4LPEN) != 0U) + +#define __HAL_RCC_UART5_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART5LPEN) != 0U) + +#define __HAL_RCC_I2C1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C1_I3C1LPEN) != 0U) + +#define __HAL_RCC_I2C2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C2LPEN) != 0U) + +#define __HAL_RCC_I2C3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C3LPEN) != 0U) + +#define __HAL_RCC_I3C1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_I2C1_I3C1LPEN) != 0U) + +#define __HAL_RCC_CEC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_CECLPEN) != 0U) + +#define __HAL_RCC_UART7_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART7LPEN) != 0U) + +#define __HAL_RCC_UART8_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR1, RCC_APB1LPENR1_UART8LPEN) != 0U) + +#define __HAL_RCC_CRS_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_CRSLPEN) != 0U) + +#define __HAL_RCC_MDIOS_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_MDIOSLPEN) != 0U) + +#define __HAL_RCC_FDCAN_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_FDCANLPEN) != 0U) + +#define __HAL_RCC_UCPD1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB1LPENR2, RCC_APB1LPENR2_UCPD1LPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB2_Clock_Sleep_Enable_Disable_Status APB2 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the APB2 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM1LPEN) != 0U) + +#define __HAL_RCC_USART1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN) != 0U) + +#define __HAL_RCC_SPI1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI1LPEN) != 0U) + +#define __HAL_RCC_SPI4_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI4LPEN) != 0U) + +#define __HAL_RCC_TIM15_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM15LPEN) != 0U) + +#define __HAL_RCC_TIM16_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM16LPEN) != 0U) + +#define __HAL_RCC_TIM17_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM17LPEN) != 0U) + +#define __HAL_RCC_TIM9_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM9LPEN) != 0U) + +#define __HAL_RCC_SPI5_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI5LPEN) != 0U) + +#define __HAL_RCC_SAI1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI1LPEN) != 0U) + +#define __HAL_RCC_SAI2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI2LPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB4_Clock_Sleep_Enable_Disable_Status APB4 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the APB4 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_SBSLPEN) != 0U) + +#define __HAL_RCC_LPUART1_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPUART1LPEN) != 0U) + +#define __HAL_RCC_SPI6_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_SPI6LPEN) != 0U) + +#define __HAL_RCC_LPTIM2_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM2LPEN) != 0U) + +#define __HAL_RCC_LPTIM3_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM3LPEN) != 0U) + +#define __HAL_RCC_LPTIM4_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM4LPEN) != 0U) + +#define __HAL_RCC_LPTIM5_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_LPTIM5LPEN) != 0U) + +#define __HAL_RCC_VREF_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_VREFLPEN) != 0U) + +#define __HAL_RCC_RTCAPB_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_RTCAPBLPEN) != 0U) + +#define __HAL_RCC_DTS_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB4LPENR, RCC_APB4LPENR_DTSLPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_APB5_Clock_Sleep_Enable_Disable_Status APB5 Peripheral Clock Sleep Enabled or Disabled Status + * @brief Check whether the APB5 peripheral clock during Low Power (Sleep) mode is enabled or not. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @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_LTDC_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB5LPENR, RCC_APB5LPENR_LTDCLPEN) != 0U) + +#define __HAL_RCC_DCMIPP_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB5LPENR, RCC_APB5LPENR_DCMIPPLPEN) != 0U) + +#define __HAL_RCC_GFXTIM_IS_CLK_SLEEP_ENABLED() (READ_BIT(RCC->APB5LPENR, RCC_APB5LPENR_GFXTIMLPEN) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_Osc_config Oscillators configuration + * @{ + */ + +/** @brief Macro to enable or disable the Internal High Speed oscillator (HSI). + * @note After enabling the HSI, the application software should wait on + * HSIRDY and HSIDIVF flags to be set indicating that the HSI clock is + * stable and the divider ready and that HSI clock can be used to clock + * the PLL and/or system clock. + * @note HSI can not be stopped if it is used directly or through the PLL + * as system clock. In this case, you have to select another source + * of the system clock then stop the HSI. + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * @param __STATE__ specifies the new state of the HSI. + * This parameter can be one of the following values: + * @arg @ref RCC_HSI_OFF turn OFF the HSI oscillator + * @arg @ref RCC_HSI_ON turn ON the HSI oscillator (divide it by 1 (default after reset)) + * @arg @ref RCC_HSI_DIV2 turn ON the HSI oscillator and divide it by 2 + * @arg @ref RCC_HSI_DIV4 turn ON the HSI oscillator and divide it by 4 + * @arg @ref RCC_HSI_DIV8 turn ON the HSI oscillator and divide it by 8 + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + */ +#define __HAL_RCC_HSI_CONFIG(__STATE__) \ + MODIFY_REG(RCC->CR, RCC_CR_HSION | RCC_CR_HSIDIV , (uint32_t)(__STATE__)) + +/** @brief Macro to get the HSI divider. + * @retval The HSI divider. The returned value can be one + * of the following: + * - RCC_CR_HSIDIV_1 HSI oscillator divided by 1 (default after reset) + * - RCC_CR_HSIDIV_2 HSI oscillator divided by 2 + * - RCC_CR_HSIDIV_4 HSI oscillator divided by 4 + * - RCC_CR_HSIDIV_8 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 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 start-up + * 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 Clock + * Security System CSS 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. + */ +#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 some peripherals. + * @note Keeping the HSI ON in STOP mode allows to avoid slowing down the communication + * speed because of the HSI start-up 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 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 + * start-up 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 Clock Security System CSS is enabled). + * @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. + */ +#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 to adjust 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 + * (default is RCC_CSICALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0x3F. + * @retval None + */ +#define __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(__CSICALIBRATIONVALUE__) \ + MODIFY_REG(RCC->CSICFGR, RCC_CSICFGR_CSITRIM, (uint32_t)(__CSICALIBRATIONVALUE__) << RCC_CSICFGR_CSITRIM_Pos); + +/** + * @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 Macro to enable or disable the Internal High Speed oscillator for USB (HSI48). + * @note After enabling the HSI48, the application software should wait on + * HSI48RDY flag to be set indicating that HSI48 clock is stable and can + * be used to clock the USB. + * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. + */ +#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 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. + */ +#define __HAL_RCC_LSI_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_LSION) + +#define __HAL_RCC_LSI_DISABLE() CLEAR_BIT(RCC->CSR, RCC_CSR_LSION) + +/** + * @brief Macro to configure the External High Speed oscillator (__HSE__). + * @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 PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL 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. + * @note This function reset the CSSON bit, so if the clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @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 (analog). + * @arg @ref RCC_HSE_BYPASS_DIGITAL HSE oscillator bypassed with external digital clock. + */ +#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 Transition 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 The external input clock can have a frequency up to 1 MHz and be low swing (analog) or digital(*). + A duty cycle close to 50% is recommended. + * @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, RCC_LSE_BYPASS or RCC_LSE_BYPASS_DIGITAL), 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. + * @note If the RTC is used, the LSE bypass must not be configured in digital mode but in low swing analog mode (*) + * @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 (analog). + * @arg @ref RCC_LSE_BYPASS_DIGITAL LSE oscillator bypassed with external digital clock. + */ +#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) + +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_config RCC_RTC_Clock_config + * @{ + */ + +/** @brief Macros to enable or disable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#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 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_FORCE() and + * __HAL_RCC_BACKUPRESET_RELEASE() macros, or by a Power On Reset (POR). + * @param __RTC_CLKSOURCE__ 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_DIV2 HSE divide by 2 selected as RTC clock up to + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV63 for HSE divide by 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(__RTC_CLKSOURCE__) \ + ((((__RTC_CLKSOURCE__) & (0x3FUL << 12U)) != 0U) ? \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_RTCPRE, (((__RTC_CLKSOURCE__) & (~RCC_BDCR_RTCSEL)) >> 4U)) : \ + CLEAR_BIT(RCC->CFGR, RCC_CFGR_RTCPRE)) + +#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__) \ + do { \ + __HAL_RCC_RTC_CLKPRESCALER(__RTC_CLKSOURCE__); \ + SET_BIT(RCC->BDCR, ((__RTC_CLKSOURCE__) & RCC_BDCR_RTCSEL)); \ + } while(0) + +#define __HAL_RCC_GET_RTC_SOURCE() \ + ((READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL) == RCC_BDCR_RTCSEL) ? \ + ((READ_BIT(RCC->CFGR, RCC_CFGR_RTCPRE) << 4U) | RCC_BDCR_RTCSEL) : READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL)) + +/** @brief Macros to force or release the Vswitch 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. + */ +#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_PLL_Clocks_config PLL Clocks configuration + * @{ + */ + +/** @brief Macro to configure the PLLs clock source. + * @note This function must be used only when all PLLs are disabled. + * @param __PLLSOURCE__ specifies the PLLs entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_CSI CSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_NONE No oscillator clock selected as PLL clock entry (consumption gain) + */ +#define __HAL_RCC_PLLSOURCE_CONFIG(__PLLSOURCE__) \ + MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_PLLSRC, (__PLLSOURCE__)) + +/** @brief Macro to get the oscillator used as PLL clock source. + * @retval The oscillator used as PLL clock source. + * The returned value can be one of the following values: + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator is used as PLL clock source. + * @arg @ref RCC_PLLSOURCE_CSI CSI oscillator is used as PLL clock source. + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator is used as PLL clock source. + * @arg @ref RCC_PLLSOURCE_NONE No oscillator is used as PLL clock source. + */ +#define __HAL_RCC_GET_PLL_OSCSOURCE() \ + READ_BIT(RCC->PLLCKSELR, RCC_PLLCKSELR_PLLSRC) + +/** @brief Macros to enable or disable the PLL1. + * @note After enabling the main PLL, the application software should wait on + * PLL1RDY flag to be set indicating that PLL1 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 (PLL_P_CLK, PLL_Q_CLK, PLL_R_CLK, PLL_S_CLK, PLL_T_CLK) + * @note PLL_P_CLK cannot be stopped if used as System Clock + * @param __PLL_CLOCKOUT__ specifies the PLL clock to be output + * This parameter can be one or a combination of the following values: + * @arg @ref RCC_PLL_PCLK This clock is used to generate system clock up to 500MHz + * @arg @ref RCC_PLL_QCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_RCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_SCLK This clock is used to generate peripherals clock up to 500MHz + * + * @retval None + */ +#define __HAL_RCC_PLL1CLKOUT_ENABLE(__PLL_CLOCKOUT__) SET_BIT(RCC->PLLCFGR, (__PLL_CLOCKOUT__)) + +#define __HAL_RCC_PLL1CLKOUT_DISABLE(__PLL_CLOCKOUT__) CLEAR_BIT(RCC->PLLCFGR, (__PLL_CLOCKOUT__)) + +/** + * @brief Macro to get the PLL1 clock output enable status. + * @param __PLL_CLOCKOUT__ specifies the PLL1 clock to be output. + * This parameter can be one of the following values: + * @arg @ref RCC_PLL_PCLK This clock is used to generate system clock up to 500MHz + * @arg @ref RCC_PLL_QCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_RCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_SCLK This clock is used to generate peripherals clock up to 500MHz + * @retval SET / RESET + */ +#define __HAL_RCC_GET_PLL1CLKOUT_CONFIG(__PLL_CLOCKOUT__) READ_BIT(RCC->PLLCFGR, (__PLL_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->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN) + +#define __HAL_RCC_PLL1_FRACN_DISABLE() CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN) + +/** + * @brief Macro to configure the main PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * + * @param __PLLSOURCE__ specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_CSI CSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_NONE No oscillator clock selected as PLL clock entry (consumption gain) + * @note This clock source is common for PLL1, PLL2 and PLL3. It cannot be + * change on any PLL if another PLL is already enabled. + * + * @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 PLLM 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 8 and 420. + * @note You have to set the PLLN parameter correctly to ensure that the VCO + * output frequency is between 150 and 420 MHz (when in medium VCO range) or + * between 128 and 560 MHZ (when in wide VCO range) + * + * @param __PLL1P__ specifies the division factor for system clock. + * This parameter must be a number between 1 and 128 (where odd numbers are 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 + * + * @param __PLL1S__ specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 8 + * + * + * @note To insure an optimal behavior of the PLL when one of the post-divider (DIVP, DIVQ, + * DIVR, DIVS or DIVT) is not used, application shall clear the enable bit (PLL1yEN) + * and assign lowest possible value to __PLL1P__, __PLL1Q__, __PLL1R__, __PLL1S__ + * or __PLL1T__ parameters. + * @retval None + */ + +#define __HAL_RCC_PLL1_CONFIG(__PLLSOURCE__, __PLL1M__, __PLL1N__, __PLL1P__, __PLL1Q__, __PLL1R__, __PLL1S__) \ + do { \ + MODIFY_REG(RCC->PLLCKSELR, (RCC_PLLCKSELR_PLLSRC | RCC_PLLCKSELR_DIVM1) , ((__PLLSOURCE__) | ( (__PLL1M__) << RCC_PLLCKSELR_DIVM1_Pos))); \ + WRITE_REG(RCC->PLL1DIVR1, ((((__PLL1N__) - 1U) & RCC_PLL1DIVR1_DIVN) | \ + ((((__PLL1P__) - 1U) << RCC_PLL1DIVR1_DIVP_Pos) & RCC_PLL1DIVR1_DIVP) | \ + ((((__PLL1Q__) - 1U) << RCC_PLL1DIVR1_DIVQ_Pos) & RCC_PLL1DIVR1_DIVQ) | \ + ((((__PLL1R__) - 1U) << RCC_PLL1DIVR1_DIVR_Pos) & RCC_PLL1DIVR1_DIVR))); \ + MODIFY_REG(RCC->PLL1DIVR2, RCC_PLL1DIVR2_DIVS, \ + (((__PLL1S__) - 1U) & RCC_PLL1DIVR2_DIVS)); \ + } while(0) + +/** + * @brief Macro to configures the PLL1 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: + * 128 to 560 MHz if PLL1VCOSEL = 0 + * 150 to 420 MHz if PLL1VCOSEL = 1. + * + * @retval None + */ +#define __HAL_RCC_PLL1_FRACN_CONFIG(__PLL1FRACN__) \ + MODIFY_REG(RCC->PLL1FRACR, RCC_PLL1FRACR_FRACN, (uint32_t)(__PLL1FRACN__) << RCC_PLL1FRACR_FRACN_Pos) + +/** @brief Macro to select the PLL1 reference frequency range. + * @param __PLL_VCOINPUT_RANGE__ specifies the PLL1 input frequency range + * This parameter can be one of the following values: + * @arg @ref RCC_PLL_VCOINPUT_RANGE0 Range frequency is between 1 and 2 MHz + * @arg @ref RCC_PLL_VCOINPUT_RANGE1 Range frequency is between 2 and 4 MHz + * @arg @ref RCC_PLL_VCOINPUT_RANGE2 Range frequency is between 4 and 8 MHz + * @arg @ref RCC_PLL_VCOINPUT_RANGE3 Range frequency is between 8 and 16 MHz + * + * @retval None + */ +#define __HAL_RCC_PLL1_VCOINPUT_RANGE(__PLL_VCOINPUT_RANGE__) \ + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL1RGE, (__PLL_VCOINPUT_RANGE__)) + +/** @brief Macro to select the PLL1 reference frequency range. + * @param __PLLVCORANGE__ specifies the PLL1 input frequency range + * This parameter can be one of the following values: + * @arg @ref RCC_PLL_VCO_HIGH Range frequency is between 128 to 560 MHz + * @arg @ref RCC_PLL_VCO_LOW Range frequency is between 150 and 420 MHz + * @retval None + */ +#define __HAL_RCC_PLL1_VCORANGE(__PLLVCORANGE__) \ + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL1VCOSEL, (__PLLVCORANGE__)) + +/** @brief Macros to enable or disable 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 PLL2 is disabled by hardware when entering Stop and Standby modes. + */ +#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, PLL2_S_CLK, PLL2_T_CLK) + * @param __PLL_CLOCKOUT__ Specifies the PLL2 clock(s) to be output + * This parameter can be one or a combination of the following values: + * @arg @ref RCC_PLL_PCLK This clock is used to generate system clock up to 500MHz + * @arg @ref RCC_PLL_QCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_RCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_SCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_TCLK This clock is used to generate peripherals clock up to 500MHz + * @retval None + */ +#define __HAL_RCC_PLL2CLKOUT_ENABLE(__PLL_CLOCKOUT__) SET_BIT(RCC->PLLCFGR, ((__PLL_CLOCKOUT__) << (RCC_PLLCFGR_PLL2PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos))) + +#define __HAL_RCC_PLL2CLKOUT_DISABLE(__PLL_CLOCKOUT__) CLEAR_BIT(RCC->PLLCFGR, ((__PLL_CLOCKOUT__) << (RCC_PLLCFGR_PLL2PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos))) + +/** + * @brief Macro to get the PLL2 clock output enable status. + * @param __PLL_CLOCKOUT__ specifies the PLL2 clock to be output. + * This parameter can be one of the following values: + * @arg @ref RCC_PLL_PCLK This clock is used to generate system clock up to 500MHz + * @arg @ref RCC_PLL_QCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_RCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_SCLK This clock is used to generate peripherals clock up to 500MHz + * @arg @ref RCC_PLL_TCLK This clock is used to generate peripherals clock up to 500MHz + * @retval SET / RESET + */ +#define __HAL_RCC_GET_PLL2CLKOUT_CONFIG(__PLL_CLOCKOUT__) (READ_BIT(RCC->PLLCFGR, ((__PLL_CLOCKOUT__) << (RCC_PLLCFGR_PLL2PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos))) \ + >> (RCC_PLLCFGR_PLL2PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos)) + +/** + * @brief Enables or disables Fractional Part Of The Multiplication Factor of PLL2 VCO + * @note Enabling/disabling Fractional Part can be any time without the need to stop the PLL2 + * @retval None + */ +#define __HAL_RCC_PLL2_FRACN_ENABLE() SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2FRACEN) + +#define __HAL_RCC_PLL2_FRACN_DISABLE() CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2FRACEN) + +/** + * @brief Macro to configures the PLL2 multiplication and division factors. + * @note This function must be used only when PLL2 is disabled. + * + * @param __PLLSOURCE__ specifies the PLL2 clock source + * This parameter must be a value of @ref RCC_PLL_Clock_Source + * @note PLL2 clock source is addressing a common clock source for all PLLs. + * + * @param __PLL2M__ specifies the division factor for PLL2 VCO input clock + * This parameter must be a number between 1 and 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 16 MHz. + * + * @param __PLL2N__ specifies the multiplication factor for PLL2 VCO output clock + * This parameter must be a number between 4 and 512 or between 8 and 420(*). + * @note You have to set the PLL2N 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 or between 128 and 560 MHZ(*) (when in wide VCO range) + * + * @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. + * + * @param __PLL2S__ specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 8. + * + * @param __PLL2T__ specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 8. + * + * @note To insure an optimal behavior of the PLL when one of the post-divider (DIVP, DIVQ, + * DIVR, DIVS and DIVT) is not used, application shall clear the enable bit (PLL2yEN) + * and assign lowest possible value to __PLL2P__, __PLL2Q__, __PLL2R__, __PLL2S__ + * or __PLL2T__ parameters. + * @retval None + */ + +#define __HAL_RCC_PLL2_CONFIG(__PLLSOURCE__, __PLL2M__, __PLL2N__, __PLL2P__, __PLL2Q__, __PLL2R__, __PLL2S__, __PLL2T__) \ + do{ \ + MODIFY_REG(RCC->PLLCKSELR, (RCC_PLLCKSELR_DIVM2 | RCC_PLLCKSELR_PLLSRC), \ + (((__PLL2M__) << RCC_PLLCKSELR_DIVM2_Pos) | (__PLLSOURCE__))); \ + WRITE_REG(RCC->PLL2DIVR1, ((((__PLL2N__) - 1U) & RCC_PLL2DIVR1_DIVN) | \ + ((((__PLL2P__) - 1U) << RCC_PLL2DIVR1_DIVP_Pos) & RCC_PLL2DIVR1_DIVP) | \ + ((((__PLL2Q__) - 1U) << RCC_PLL2DIVR1_DIVQ_Pos) & RCC_PLL2DIVR1_DIVQ) | \ + ((((__PLL2R__) - 1U) << RCC_PLL2DIVR1_DIVR_Pos) & RCC_PLL2DIVR1_DIVR))); \ + MODIFY_REG(RCC->PLL2DIVR2, (RCC_PLL2DIVR2_DIVS | RCC_PLL2DIVR2_DIVT) , \ + ((((__PLL2S__) - 1U) & RCC_PLL2DIVR2_DIVS) | \ + ((((__PLL2T__) - 1U) << RCC_PLL2DIVR2_DIVT_Pos) & RCC_PLL2DIVR2_DIVT))); \ + } while(0) + +/** + * @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 or 128 to 560 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_FRACN,((uint32_t)(__PLL2FRACN__) << RCC_PLL2FRACR_FRACN_Pos)) + +/** @brief Macro to select the PLL2 reference frequency range. + * @param __PLL_VCOINPUT_RANGE__ specifies the PLL2 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL_VCOINPUT_RANGE0: Range frequency is between 1 and 2 MHz + * @arg RCC_PLL_VCOINPUT_RANGE1: Range frequency is between 2 and 4 MHz + * @arg RCC_PLL_VCOINPUT_RANGE2: Range frequency is between 4 and 8 MHz + * @arg RCC_PLL_VCOINPUT_RANGE3: Range frequency is between 8 and 16 MHz + * @retval None + */ +#define __HAL_RCC_PLL2_VCOINPUT_RANGE(__PLL_VCOINPUT_RANGE__) \ + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL2RGE, ((__PLL_VCOINPUT_RANGE__) << (RCC_PLLCFGR_PLL2RGE_Pos - RCC_PLLCFGR_PLL1RGE_Pos))) + + +/** @brief Macro to select the PLL2 reference frequency range. + * @param __PLLVCORANGE__ Specifies the PLL2 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL_VCO_HIGH: Range frequency is between 192 and 836 MHz or between 128 to 560 MHz(*) + * @arg RCC_PLL_VCO_LOW: Range frequency is between 150 and 420 MHz + * + * + * @retval None + */ +#define __HAL_RCC_PLL2_VCORANGE(__PLLVCORANGE__) \ + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL2VCOSEL, ((__PLLVCORANGE__) << (RCC_PLLCFGR_PLL2VCOSEL_Pos - RCC_PLLCFGR_PLL1VCOSEL_Pos))) + +/** @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 any time without the need to stop the PLL3 + * @retval None + */ +#define __HAL_RCC_PLL3_FRACN_ENABLE() SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3FRACEN) + +#define __HAL_RCC_PLL3_FRACN_DISABLE() CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3FRACEN) + +/** + * @brief Enables or disables each clock output (PLL3_P_CLK, PLL3_Q_CLK, PLL3_R_CLK, PLL3_S_CLK, PLL3_T_CLK) + * @param __PLL_CLOCKOUT__ Specifies the PLL3 clock(s) to be output + * This parameter can be one or a combination of the following values: + * @arg RCC_PLL_PCLK + * @arg RCC_PLL_QCLK + * @arg RCC_PLL_RCLK + * @arg RCC_PLL_SCLK + * @retval SET / RESET + */ +#define __HAL_RCC_PLL3CLKOUT_ENABLE(__PLL_CLOCKOUT__) SET_BIT(RCC->PLLCFGR, ((__PLL_CLOCKOUT__) << (RCC_PLLCFGR_PLL3PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos))) + +#define __HAL_RCC_PLL3CLKOUT_DISABLE(__PLL_CLOCKOUT__) CLEAR_BIT(RCC->PLLCFGR, ((__PLL_CLOCKOUT__) << (RCC_PLLCFGR_PLL3PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos))) + +/** + * @brief Macro to get the PLL3 clock output enable status. + * @param __PLL_CLOCKOUT__ specifies the PLL3 clock(s) to be output. + * This parameter can be one of the following values: + * @arg RCC_PLL_PCLK + * @arg RCC_PLL_QCLK + * @arg RCC_PLL_RCLK + * @arg RCC_PLL_SCLK + * @retval SET / RESET + */ +#define __HAL_RCC_GET_PLL3CLKOUT_CONFIG(__PLL_CLOCKOUT__) (READ_BIT(RCC->PLLCFGR, ((__PLL_CLOCKOUT__) << (RCC_PLLCFGR_PLL3PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos))) \ + >> (RCC_PLLCFGR_PLL3PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos)) + +/** + * @brief Macro to configures the PLL3 multiplication and division factors. + * @note This function must be used only when PLL3 is disabled. + * + * @param __PLLSOURCE__ specifies the PLL3 clock source + * This parameter must be a value of @ref RCC_PLL_Clock_Source + * @note PLL3 clock source is addressing a common clock source for all PLLs. + * + * @param __PLL3M__ specifies the division factor for PLL3 VCO input clock + * This parameter must be a number between 1 and 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 16 MHz. + * + * @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 or between 128 and 560 MHZ(*) (when in wide VCO range) + * + * @param __PLL3P__ specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 2 and 128 (where odd numbers not allowed) + * + * @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 + * + * @param __PLL3S__ specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 8. + * + * @note To insure an optimal behavior of the PLL when one of the post-divider (DIVP, DIVQ, + * DIVR, DIVS and DIVT) is not used, application shall clear the enable bit (PLL3yEN) + * and assign lowest possible value to __PLL3P__, __PLL3Q__, __PLL3R__, __PLL3S__ + * or __PLL3T__ parameters. + */ + +#define __HAL_RCC_PLL3_CONFIG(__PLLSOURCE__, __PLL3M__, __PLL3N__, __PLL3P__, __PLL3Q__, __PLL3R__, __PLL3S__) \ + do{ \ + MODIFY_REG(RCC->PLLCKSELR, (RCC_PLLCKSELR_DIVM3 | RCC_PLLCKSELR_PLLSRC), \ + (((__PLL3M__) << RCC_PLLCKSELR_DIVM3_Pos) | (__PLLSOURCE__))); \ + WRITE_REG(RCC->PLL3DIVR1, ((((__PLL3N__) - 1U) & RCC_PLL3DIVR1_DIVN) | \ + ((((__PLL3P__) - 1U) << RCC_PLL3DIVR1_DIVP_Pos) & RCC_PLL3DIVR1_DIVP) | \ + ((((__PLL3Q__) - 1U) << RCC_PLL3DIVR1_DIVQ_Pos) & RCC_PLL3DIVR1_DIVQ) | \ + ((((__PLL3R__) - 1U) << RCC_PLL3DIVR1_DIVR_Pos) & RCC_PLL3DIVR1_DIVR))); \ + MODIFY_REG(RCC->PLL3DIVR2, RCC_PLL3DIVR2_DIVS, \ + (((__PLL3S__) - 1U) & RCC_PLL3DIVR2_DIVS)); \ + } while(0) + +/** + * @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 or 128 to 560 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_FRACN, (uint32_t)(__PLL3FRACN__) << RCC_PLL3FRACR_FRACN_Pos) + +/** @brief Macro to select the PLL3 reference frequency range. + * @param __PLL_VCOINPUT_RANGE__ specifies the PLL1 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL_VCOINPUT_RANGE0: Range frequency is between 1 and 2 MHz + * @arg RCC_PLL_VCOINPUT_RANGE1: Range frequency is between 2 and 4 MHz + * @arg RCC_PLL_VCOINPUT_RANGE2: Range frequency is between 4 and 8 MHz + * @arg RCC_PLL_VCOINPUT_RANGE3: Range frequency is between 8 and 16 MHz + * @retval None + */ +#define __HAL_RCC_PLL3_VCOINPUT_RANGE(__PLL_VCOINPUT_RANGE__) \ + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL3RGE, ((__PLL_VCOINPUT_RANGE__) << (RCC_PLLCFGR_PLL3RGE_Pos - RCC_PLLCFGR_PLL1RGE_Pos))) + +/** @brief Macro to select the PLL3 reference frequency range. + * @param __PLLVCORANGE__ specifies the PLL1 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL_VCO_HIGH: Range frequency is between 192 and 836 MHz or between 128 to 560 MHz(*) + * @arg RCC_PLL_VCO_HIGH: Range frequency is between 150 and 420 MHz + * + * + * @retval None + */ +#define __HAL_RCC_PLL3_VCORANGE(__PLLVCORANGE__) \ + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLL3VCOSEL, ((__PLLVCORANGE__) << (RCC_PLLCFGR_PLL3VCOSEL_Pos - RCC_PLLCFGR_PLL1VCOSEL_Pos))) + +/** + * @} + */ + +/** @defgroup RCC_sysclk_config System clock source configuration + * @{ + */ + +/** + * @brief Macro to configure the system clock source. + * @param __SYSCLKSOURCE__ specifies the system clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_SYSCLKSOURCE_HSI HSI oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_CSI CSI oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_HSE HSE oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_PLLCLK PLL1 output is used as system clock source. + * @retval None + */ +#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_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 values: + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSI HSI used as system clock. + * @arg @ref RCC_SYSCLKSOURCE_STATUS_CSI CSI used as system clock. + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSE HSE used as system clock. + * @arg @ref RCC_SYSCLKSOURCE_STATUS_PLLCLK PLL1 used as system clock. + */ +#define __HAL_RCC_GET_SYSCLK_SOURCE() \ + READ_BIT(RCC->CFGR, RCC_CFGR_SWS) + +/** + * @} + */ + +/** @addtogroup RCC_Osc_config + * @{ + */ + +/** + * @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 write access using + * HAL_PWR_EnableBkUpAccess() function before to configure the LSE + * (to be done once after reset). + * @note This parameter cannot be updated while LSE is ON. + * @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__)); +/** + * @} + */ + +/** @defgroup RCC_wkup_config Wakeup from stop configuration + * @{ + */ + +/** + * @brief Macro to configure the wake up from stop clock. + * @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->CFGR, RCC_CFGR_STOPWUCK, (__STOPWUCLK__)) + +/** + * @brief Macro to configure the Kernel wake up from stop clock. + * @param __STOPKERWUCLK__ specifies the Kernel clock source used after wake up from stop + * This parameter can be one of the following values: + * @arg @ref RCC_STOP_KERWAKEUPCLOCK_HSI HSI selected as Kernel clock source + * @arg @ref RCC_STOP_KERWAKEUPCLOCK_CSI CSI selected as Kernel clock source + * @retval None + */ +#define __HAL_RCC_KERWAKEUPSTOP_CLK_CONFIG(__STOPKERWUCLK__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_STOPKERWUCK, (__STOPKERWUCLK__)) +/** + * @} + */ + +/** @defgroup RCC_MCOx_Clock_Config RCC MCOx Clock Config + * @{ + */ + +/** @brief Macro to configure the MCO1 clock. + * @param __MCOCLKSOURCE__ specifies the MCO clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO1 source + * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO1 source + * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO1 source + * @arg @ref RCC_MCO1SOURCE_PLL1Q PLL1Q clock selected as MCO1 source + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO1 source + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCO1 clock + */ +#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE), ((__MCOCLKSOURCE__) | (__MCODIV__))) + +/** @brief Macro to configure the MCO2 clock. + * @param __MCOCLKSOURCE__ specifies the MCO clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO2SOURCE_SYSCLK System clock (SYSCLK) selected as MCO2 source + * @arg @ref RCC_MCO2SOURCE_PLL2P PLL2P clock selected as MCO2 source + * @arg @ref RCC_MCO2SOURCE_HSE HSE clock selected as MCO2 source + * @arg @ref RCC_MCO2SOURCE_PLL1P PLL1P clock selected as MCO2 source + * @arg @ref RCC_MCO2SOURCE_CSI CSI clock selected as MCO2 source + * @arg @ref 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 @ref RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCO2 clock + */ +#define __HAL_RCC_MCO2_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2 | RCC_CFGR_MCO2PRE), ((__MCOCLKSOURCE__) | ((__MCODIV__) << 7U))); + +/** + * @} + */ + +/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management + * @brief macros to manage the specified RCC Flags and interrupts. + * @{ + */ +/** @brief Enable RCC interrupt. + * @param __INTERRUPT__ specifies the RCC interrupt source(s) 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_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_CSIRDY CSI ready interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + * @arg @ref RCC_IT_PLL1RDY PLL1 ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt + * @arg @ref RCC_IT_LSECSS Clock security system interrupt + */ +#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) SET_BIT(RCC->CIER, (__INTERRUPT__)) + +/** @brief Disable RCC interrupt. + * @param __INTERRUPT__ specifies the RCC interrupt source(s) 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_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_CSIRDY CSI ready interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + * @arg @ref RCC_IT_PLL1RDY PLL1 ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt + * @arg @ref RCC_IT_LSECSS LSE clock security system interrupt + */ +#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(RCC->CIER, (__INTERRUPT__)) + +/** @brief Clear the RCC's 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_HSI48RDY HSI48 ready interrupt + * @arg @ref RCC_IT_PLL1RDY PLL1 ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt + * @arg @ref RCC_IT_LSECSS LSE clock security system interrupt + * @arg @ref RCC_IT_HSECSS HSE clock security interrupt + */ +#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_HSI48RDY HSI48 ready interrupt + * @arg @ref RCC_IT_PLL1RDY PLL1 ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt + * @arg @ref RCC_IT_LSECSS LSE clock security system interrupt + * @arg @ref RCC_IT_HSECSS HSE clock security interrupt + * @retval The pending state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_RCC_GET_IT(__INTERRUPT__) (READ_BIT(RCC->CIFR, (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Set RMVF bit to clear the reset flags. + * The reset flags are: RCC_FLAG_BORRST, RCC_FLAG_PINRST, RCC_FLAG_PORRST, + * RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST and RCC_FLAG_LPWRRST. + */ +#define __HAL_RCC_CLEAR_RESET_FLAGS() SET_BIT(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_HSIRDY HSI oscillator clock ready + * @arg @ref RCC_FLAG_HSIDIV HSI divider ready + * @arg @ref RCC_FLAG_CSIRDY CSI oscillator clock ready + * @arg @ref RCC_FLAG_HSI48RDY HSI48 clock ready + * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready + * @arg @ref RCC_FLAG_PLL1RDY PLL1 clock ready + * @arg @ref RCC_FLAG_PLL2RDY PLL2 clock ready + * @arg @ref RCC_FLAG_PLL3RDY PLL3 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_BORRST BOR reset + * @arg @ref RCC_FLAG_PINRST Pin reset + * @arg @ref RCC_FLAG_PORRST Power-on reset + * @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). + */ +#define __HAL_RCC_GET_FLAG(__FLAG__) (((((((__FLAG__) >> 5U) == RCC_CR_REG_INDEX) ? RCC->CR : \ + ((((__FLAG__) >> 5U) == RCC_BDCR_REG_INDEX) ? RCC->BDCR : \ + ((((__FLAG__) >> 5U) == RCC_CSR_REG_INDEX) ? RCC->CSR : \ + ((((__FLAG__) >> 5U) == RCC_RSR_REG_INDEX) ? RCC->RSR : RCC->CIFR)))) & \ + (1UL << ((__FLAG__) & RCC_FLAG_MASK))) != 0U) ? 1U : 0U) + +/** + * @} + */ + +/** + * @} + */ + +/* Include RCC HAL Extension module */ +#include "stm32h7rsxx_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(RCC_OscInitTypeDef *RCC_OscInitStruct); +HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *RCC_ClkInitStruct, 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); +void HAL_RCC_DisableCSS(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_GetPCLK4Freq(void); +uint32_t HAL_RCC_GetPCLK5Freq(void); +uint32_t HAL_RCC_GetPLL1PFreq(void); +uint32_t HAL_RCC_GetPLL1QFreq(void); +uint32_t HAL_RCC_GetPLL1RFreq(void); +uint32_t HAL_RCC_GetPLL1SFreq(void); +uint32_t HAL_RCC_GetPLL2PFreq(void); +uint32_t HAL_RCC_GetPLL2QFreq(void); +uint32_t HAL_RCC_GetPLL2RFreq(void); +uint32_t HAL_RCC_GetPLL2SFreq(void); +uint32_t HAL_RCC_GetPLL2TFreq(void); +uint32_t HAL_RCC_GetPLL3PFreq(void); +uint32_t HAL_RCC_GetPLL3QFreq(void); +uint32_t HAL_RCC_GetPLL3RFreq(void); +uint32_t HAL_RCC_GetPLL3SFreq(void); +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency); +/* CSS NMI IRQ handler */ +void HAL_RCC_NMI_IRQHandler(void); +/* User callbacks in non blocking mode (IT mode) */ +void HAL_RCC_HSECSSCallback(void); +void HAL_RCC_LSECSSCallback(void); +uint32_t HAL_RCC_GetResetSource(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ +#define RCC_PLL_VCOINPUTFREQ_MAX 16000000U /* Maximum VCO input frequency is 16 MHz */ +#define RCC_PLL_VCOINPUTFREQ_MIN 1000000U /* Minimum VCO input frequency is 1 MHz */ + +#define RCC_PLL_TIMEOUT_VALUE (50U) /* 50 ms */ + +/* Defines used for Flags */ +#define RCC_CR_REG_INDEX 1U +#define RCC_BDCR_REG_INDEX 2U +#define RCC_CSR_REG_INDEX 3U +#define RCC_RSR_REG_INDEX 4U + +#define RCC_FLAG_MASK 0x0000001FU + +#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCC_Private_Macros + * @{ + */ + +/** @defgroup RCC_IS_RCC_Definitions RCC Private macros to check input parameters + * @{ + */ + +#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_CSI) == RCC_OSCILLATORTYPE_CSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((__OSCILLATOR__) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)) + +#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(__HSIDIV__) (((__HSIDIV__) == RCC_HSI_DIV1) || ((__HSIDIV__) == RCC_HSI_DIV2) || \ + ((__HSIDIV__) == RCC_HSI_DIV4) || ((__HSIDIV__) == RCC_HSI_DIV8)) + +#define IS_RCC_HSI_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) \ + <= (uint32_t)( RCC_HSICFGR_HSITRIM >> RCC_HSICFGR_HSITRIM_Pos)) + +#define IS_RCC_HSI48(__HSI48__) (((__HSI48__) == RCC_HSI48_OFF) || ((__HSI48__) == RCC_HSI48_ON)) + +#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_CSI_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) \ + <= (uint32_t)( RCC_CSICFGR_CSITRIM >> RCC_CSICFGR_CSITRIM_Pos)) + +#define IS_RCC_PLL(__PLL__) (((__PLL__) == RCC_PLL_NONE) || ((__PLL__) == RCC_PLL_OFF) || \ + ((__PLL__) == RCC_PLL_ON)) + +#define IS_RCC_PLLSOURCE(__SOURCE__) (((__SOURCE__) == RCC_PLLSOURCE_HSI) || \ + ((__SOURCE__) == RCC_PLLSOURCE_CSI) || \ + ((__SOURCE__) == RCC_PLLSOURCE_HSE)) + +#define IS_RCC_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 63U)) + +#define IS_RCC_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 420U)) + +#define IS_RCC_PLLP_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U)) + +#define IS_RCC_PLLQ_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U)) + +#define IS_RCC_PLLR_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U)) + +#define IS_RCC_PLLS_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 8U)) + +#define IS_RCC_PLLT_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 8U)) + +#define IS_RCC_PLL_VCOINPUTFREQ(__VALUE__) ((RCC_PLL_VCOINPUTFREQ_MIN <= (__VALUE__)) &&\ + ((__VALUE__) <= RCC_PLL_VCOINPUTFREQ_MAX)) + +#define IS_RCC_PLLFRACN_VALUE(__VALUE__) ((__VALUE__) <= 8191U) + +#define IS_RCC_PLLCLOCKOUT_VALUE(__VALUE__) (((__VALUE__) == RCC_PLL_PCLK) || \ + ((__VALUE__) == RCC_PLL_QCLK) || \ + ((__VALUE__) == RCC_PLL_RCLK) || \ + ((__VALUE__) == RCC_PLL_SCLK)) + +#define IS_RCC_PLLRGE_VALUE(__VALUE__) (((__VALUE__) == RCC_PLL_VCOINPUT_RANGE0) || \ + ((__VALUE__) == RCC_PLL_VCOINPUT_RANGE1) || \ + ((__VALUE__) == RCC_PLL_VCOINPUT_RANGE2) || \ + ((__VALUE__) == RCC_PLL_VCOINPUT_RANGE3)) + +#define IS_RCC_PLLVCO_VALUE(__VALUE__) (((__VALUE__) == RCC_PLL_VCO_HIGH) || \ + ((__VALUE__) == RCC_PLL_VCO_LOW)) + +#define IS_RCC_CLOCKTYPE(__CLK__) ((1U <= (__CLK__)) && ((__CLK__) <= 63U)) + +#define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK)) + +#define IS_RCC_SYSCLK(__SYSCLK__) (((__SYSCLK__) == RCC_SYSCLK_DIV1) || ((__SYSCLK__) == RCC_SYSCLK_DIV2) || \ + ((__SYSCLK__) == RCC_SYSCLK_DIV4) || ((__SYSCLK__) == RCC_SYSCLK_DIV8) || \ + ((__SYSCLK__) == RCC_SYSCLK_DIV16) || ((__SYSCLK__) == RCC_SYSCLK_DIV64) || \ + ((__SYSCLK__) == RCC_SYSCLK_DIV128) || ((__SYSCLK__) == RCC_SYSCLK_DIV256) || \ + ((__SYSCLK__) == RCC_SYSCLK_DIV512)) + +#define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_HCLK_DIV1) || ((__HCLK__) == RCC_HCLK_DIV2) || \ + ((__HCLK__) == RCC_HCLK_DIV4) || ((__HCLK__) == RCC_HCLK_DIV8) || \ + ((__HCLK__) == RCC_HCLK_DIV16) || ((__HCLK__) == RCC_HCLK_DIV64) || \ + ((__HCLK__) == RCC_HCLK_DIV128) || ((__HCLK__) == RCC_HCLK_DIV256) || \ + ((__HCLK__) == RCC_HCLK_DIV512)) + +#define IS_RCC_PCLK1(__PCLK1__) (((__PCLK1__) == RCC_APB1_DIV1) || ((__PCLK1__) == RCC_APB1_DIV2) || \ + ((__PCLK1__) == RCC_APB1_DIV4) || ((__PCLK1__) == RCC_APB1_DIV8) || \ + ((__PCLK1__) == RCC_APB1_DIV16)) + +#define IS_RCC_PCLK2(__PCLK2__) (((__PCLK2__) == RCC_APB2_DIV1) || ((__PCLK2__) == RCC_APB2_DIV2) || \ + ((__PCLK2__) == RCC_APB2_DIV4) || ((__PCLK2__) == RCC_APB2_DIV8) || \ + ((__PCLK2__) == RCC_APB2_DIV16)) + +#define IS_RCC_PCLK4(__PCLK4__) (((__PCLK4__) == RCC_APB4_DIV1) || ((__PCLK4__) == RCC_APB4_DIV2) || \ + ((__PCLK4__) == RCC_APB4_DIV4) || ((__PCLK4__) == RCC_APB4_DIV8) || \ + ((__PCLK4__) == RCC_APB4_DIV16)) + +#define IS_RCC_PCLK5(__PCLK5__) (((__PCLK5__) == RCC_APB5_DIV1) || ((__PCLK5__) == RCC_APB5_DIV2) || \ + ((__PCLK5__) == RCC_APB5_DIV4) || ((__PCLK5__) == RCC_APB5_DIV8) || \ + ((__PCLK5__) == RCC_APB5_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_DISABLE)) + +#define IS_RCC_MCO(__MCOX__) (((__MCOX__) == RCC_MCO1_PA8) || \ + ((__MCOX__) == RCC_MCO2_PC9)) + +#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_NONE) || ((__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_FLAG(__FLAG__) (((__FLAG__) == RCC_FLAG_HSIRDY) || ((__FLAG__) == RCC_FLAG_HSIDIV ) || \ + ((__FLAG__) == RCC_FLAG_CSIRDY) || ((__FLAG__) == RCC_FLAG_HSI48RDY) || \ + ((__FLAG__) == RCC_FLAG_HSERDY) || ((__FLAG__) == RCC_FLAG_PLL1RDY) || \ + ((__FLAG__) == RCC_FLAG_PLL2RDY) || ((__FLAG__) == RCC_FLAG_PLL3RDY) || \ + ((__FLAG__) == RCC_FLAG_LSERDY) || ((__FLAG__) == RCC_FLAG_LSECSSD) || \ + ((__FLAG__) == RCC_FLAG_LSIRDY) || ((__FLAG__) == RCC_FLAG_BORRST) || \ + ((__FLAG__) == RCC_FLAG_PINRST) || ((__FLAG__) == RCC_FLAG_PORRST) || \ + ((__FLAG__) == RCC_FLAG_SFTRST) || ((__FLAG__) == RCC_FLAG_IWDGRST) || \ + ((__FLAG__) == RCC_FLAG_WWDGRST) || ((__FLAG__) == RCC_FLAG_LPWRRST)) + +#define IS_RCC_HSICALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x7FU) + +#define IS_RCC_CSICALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x3FU) + +#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)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_RCC_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc_ex.h new file mode 100644 index 0000000..2523edd --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_rcc_ex.h @@ -0,0 +1,1996 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_rcc_ex.h + * @author MCD Application Team + * @brief Header file of RCC HAL Extension 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 STM32H7RSxx_HAL_RCC_EX_H +#define STM32H7RSxx_HAL_RCC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup RCCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Types RCCEx Exported Types + * @{ + */ + +/** + * @brief RCC PLL1 Clocks structure definition + */ + +/** + * @brief RCC extended clocks structure definition + */ +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t FmcClockSelection; /*!< Specifies FMC clock source + This parameter can be a value of @ref RCCEx_FMC_Clock_Source */ + + uint32_t Xspi1ClockSelection; /*!< Specifies XSPI1 clock source + This parameter can be a value of @ref RCCEx_XSPI1_Clock_Source */ + + uint32_t Xspi2ClockSelection; /*!< Specifies XSPI2 clock source + This parameter can be a value of @ref RCCEx_XSPI2_Clock_Source */ + + uint32_t CkperClockSelection; /*!< Specifies CKPER clock source + This parameter can be a value of @ref RCCEx_CLKP_Clock_Source */ + + uint32_t AdcClockSelection; /*!< Specifies ADC interface clock source + This parameter can be a value of @ref RCCEx_ADC_Clock_Source */ + + uint32_t Adf1ClockSelection; /*!< Specifies ADF1 Clock clock source + This parameter can be a value of @ref RCCEx_ADF1_Clock_Source */ + + uint32_t CecClockSelection; /*!< Specifies CEC clock source + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + + uint32_t Eth1RefClockSelection; /*!< Specifies ETH1 REF clock source + This parameter can be a value of @ref RCCEx_ETH1REF_Clock_Source */ + + uint32_t Eth1PhyClockSelection; /*!< Specifies ETH1 PHY clock source + This parameter can be a value of @ref RCCEx_ETH1PHY_Clock_Source */ + + uint32_t FdcanClockSelection; /*!< Specifies FDCAN kernel clock source + This parameter can be a value of @ref RCCEx_FDCAN_Clock_Source */ + + uint32_t I2c1_I3c1ClockSelection; /*!< Specifies I2C1/I3C1 clock source + This parameter can be a value of @ref RCCEx_I2C1_I3C1_Clock_Source */ + + uint32_t I2c23ClockSelection; /*!< Specifies I2C2/I2C3 clock source + This parameter can be a value of @ref RCCEx_I2C23_Clock_Source */ + + uint32_t Lptim1ClockSelection; /*!< Specifies LPTIM1 clock source + This parameter can be a value of @ref RCCEx_LPTIM1_Clock_Source */ + + uint32_t Lptim23ClockSelection; /*!< Specifies LPTIM2/LPTIM3 clock source + This parameter can be a value of @ref RCCEx_LPTIM23_Clock_Source */ + + uint32_t Lptim45ClockSelection; /*!< Specifies LPTIM4/LPTIM5 clock source + This parameter can be a value of @ref RCCEx_LPTIM45_Clock_Source */ + + uint32_t Lpuart1ClockSelection; /*!< Specifies LPUART1 clock source + This parameter can be a value of @ref RCCEx_LPUART1_Clock_Source */ + + uint32_t LtdcClockSelection; /*!< Specifies LPUART1 clock source + This parameter can be a value of @ref RCCEx_LTDC_Clock_Source */ + + uint32_t PssiClockSelection; /*!< Specifies PSSI clock source + This parameter can be a value of @ref RCCEx_PSSI_Clock_Source */ + + uint32_t Sai1ClockSelection; /*!< Specifies SAI1 clock source + This parameter can be a value of @ref RCCEx_SAI1_Clock_Source */ + + uint32_t Sai2ClockSelection; /*!< Specifies SAI2 clock source + This parameter can be a value of @ref RCCEx_SAI2_Clock_Source */ + + uint32_t Sdmmc12ClockSelection; /*!< Specifies SDMMC clock source + This parameter can be a value of @ref RCCEx_SDMMC12_Clock_Source */ + + uint32_t Spi1ClockSelection; /*!< Specifies SPI1 clock source + This parameter can be a value of @ref RCCEx_SPI1_Clock_Source */ + + uint32_t Spi23ClockSelection; /*!< Specifies SPI2/SPI3 clock source + This parameter can be a value of @ref RCCEx_SPI23_Clock_Source */ + + uint32_t Spi45ClockSelection; /*!< Specifies SPI4/SPI5 clock source + This parameter can be a value of @ref RCCEx_SPI45_Clock_Source */ + + uint32_t Spi6ClockSelection; /*!< Specifies SPI6 clock source + This parameter can be a value of @ref RCCEx_SPI6_Clock_Source */ + + uint32_t SpdifrxClockSelection; /*!< Specifies SPDIFRX Clock clock source + This parameter can be a value of @ref RCCEx_SPDIFRX_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< Specifies USART1 clock source + This parameter can be a value of @ref RCCEx_USART1_Clock_Source */ + + uint32_t Usart234578ClockSelection; /*!< Specifies USART2/USART3/UART4/UART5/UART7/UART8 clock source + This parameter can be a value of @ref RCCEx_USART234578_Clock_Source */ + + uint32_t UsbPhycClockSelection; /*!< Specifies USB PHYC clock source + This parameter can be a value of @ref RCCEx_USB_PHYC_Clock_Source */ + + uint32_t UsbOtgFsClockSelection; /*!< Specifies USB OTG FS clock source + This parameter can be a value of @ref RCCEx_USB_OTGFS_Clock_Source */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock clock source + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t TIMPresSelection; /*!< Specifies TIM Clock Prescalers Selection. + This parameter can be a value of @ref RCCEx_TIM_Prescaler_Selection */ +} RCC_PeriphCLKInitTypeDef; + +/** + * @brief RCC_CRS Init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the division factor of the SYNC signal. + This parameter can be a value of @ref RCCEx_CRS_SynchroDivider */ + + uint32_t Source; /*!< Specifies the SYNC signal source. + This parameter can be a value of @ref RCCEx_CRS_SynchroSource */ + + uint32_t Polarity; /*!< Specifies the input polarity for the SYNC signal source. + This parameter can be a value of @ref RCCEx_CRS_SynchroPolarity */ + + uint32_t ReloadValue; /*!< Specifies the value to be loaded in the frequency error counter with each SYNC event. + It can be calculated in using macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) + This parameter must be a number between 0 and 0xFFFF or a value of @ref RCCEx_CRS_ReloadValueDefault .*/ + + uint32_t ErrorLimitValue; /*!< Specifies the value to be used to evaluate the captured frequency error value. + This parameter must be a number between 0 and 0xFF or a value of @ref RCCEx_CRS_ErrorLimitDefault */ + + uint32_t HSI48CalibrationValue; /*!< Specifies a user-programmable trimming value to the HSI48 oscillator. + This parameter must be a number between 0 and 0x3F or a value of @ref RCCEx_CRS_HSI48CalibrationDefault */ + +} RCC_CRSInitTypeDef; + +/** + * @brief RCC_CRS Synchronization structure definition + */ +typedef struct +{ + uint32_t ReloadValue; /*!< Specifies the value loaded in the Counter reload value. + This parameter must be a number between 0 and 0xFFFF */ + + uint32_t HSI48CalibrationValue; /*!< Specifies value loaded in HSI48 oscillator smooth trimming. + This parameter must be a number between 0 and 0x3F */ + + uint32_t FreqErrorCapture; /*!< Specifies the value loaded in the .FECAP, the frequency error counter + value latched in the time of the last SYNC event. + This parameter must be a number between 0 and 0xFFFF */ + + uint32_t FreqErrorDirection; /*!< Specifies the value loaded in the .FEDIR, the counting direction of the + frequency error counter latched in the time of the last SYNC event. + It shows whether the actual frequency is below or above the target. + This parameter must be a value of @ref RCCEx_CRS_FreqErrorDirection*/ + +} RCC_CRSSynchroInfoTypeDef; + +/** + * @} + */ + + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Constants RCCEx Exported Constants + * @{ + */ + +/** @defgroup RCCEx_Periph_Clock_Selection Periph Clock Selection + * @{ + */ +#define RCC_PERIPHCLK_FMC (0x00000001U) +#define RCC_PERIPHCLK_XSPI1 (0x00000002U) +#define RCC_PERIPHCLK_XSPI2 (0x00000004U) +#define RCC_PERIPHCLK_CKPER (0x00000008U) +#define RCC_PERIPHCLK_ADC (0x00000010U) +#define RCC_PERIPHCLK_ADF1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000040U) +#define RCC_PERIPHCLK_ETH1REF (0x00000080U) +#define RCC_PERIPHCLK_ETH1PHY (0x00000100U) +#define RCC_PERIPHCLK_FDCAN (0x00000200U) +#define RCC_PERIPHCLK_I2C23 (0x00000400U) +#define RCC_PERIPHCLK_I2C1_I3C1 (0x00000800U) +#define RCC_PERIPHCLK_LPTIM1 (0x00001000U) +#define RCC_PERIPHCLK_LPTIM23 (0x00002000U) +#define RCC_PERIPHCLK_LPTIM45 (0x00004000U) +#define RCC_PERIPHCLK_LPUART1 (0x00008000U) +#define RCC_PERIPHCLK_LTDC (0x00010000U) +#define RCC_PERIPHCLK_PSSI (0x00020000U) +#define RCC_PERIPHCLK_RTC (0x00040000U) +#define RCC_PERIPHCLK_SAI1 (0x00080000U) +#define RCC_PERIPHCLK_SAI2 (0x00100000U) +#define RCC_PERIPHCLK_SDMMC12 (0x00200000U) +#define RCC_PERIPHCLK_SPDIFRX (0x00400000U) +#define RCC_PERIPHCLK_SPI1 (0x00800000U) +#define RCC_PERIPHCLK_SPI23 (0x01000000U) +#define RCC_PERIPHCLK_SPI45 (0x02000000U) +#define RCC_PERIPHCLK_SPI6 (0x04000000U) +#define RCC_PERIPHCLK_TIM (0x08000000U) +#define RCC_PERIPHCLK_USART1 (0x10000000U) +#define RCC_PERIPHCLK_USART234578 (0x20000000U) +#define RCC_PERIPHCLK_USBPHYC (0x40000000U) +#define RCC_PERIPHCLK_USBOTGFS (0x80000000U) +/** + * @} + */ + +/** @defgroup RCCEx_FMC_Clock_Source FMC Clock Source + * @{ + */ +#define RCC_FMCCLKSOURCE_HCLK 0U /*!< HCLK selection (default) */ +#define RCC_FMCCLKSOURCE_PLL1Q RCC_CCIPR1_FMCSEL_0 /*!< PLL 'Q' output selection */ +#define RCC_FMCCLKSOURCE_PLL2R RCC_CCIPR1_FMCSEL_1 /*!< PLL2 'R' output selection */ +#define RCC_FMCCLKSOURCE_HSI RCC_CCIPR1_FMCSEL /*!< HSI selection */ +#define RCC_FMCCLKSOURCE_HCLK_DIV4 (RCC_CKPROTR_FMCSWP_2 | RCC_CKPROTR_FMCSWP_0) /*!< HCLK/4 selection (recovery position) */ +/** + * @} + */ + +/** @defgroup RCCEx_XSPI1_Clock_Source XSPI1 Clock Source + * @{ + */ +#define RCC_XSPI1CLKSOURCE_HCLK 0U /*!< HCLK selection (default) */ +#define RCC_XSPI1CLKSOURCE_PLL2S RCC_CCIPR1_XSPI1SEL_0 /*!< PLL2 'S' output selection */ +#define RCC_XSPI1CLKSOURCE_PLL2T RCC_CCIPR1_XSPI1SEL_1 /*!< PLL2 'T' output selection */ +#define RCC_XSPI1CLKSOURCE_HCLK_DIV4 RCC_CKPROTR_XSPI1SWP_2 /*!< HCLK/4 selection (recovery position) */ +/** + * @} + */ + +/** @defgroup RCCEx_XSPI2_Clock_Source XSPI2 Clock Source + * @{ + */ +#define RCC_XSPI2CLKSOURCE_HCLK 0U /*!< HCLK selection (default) */ +#define RCC_XSPI2CLKSOURCE_PLL2S RCC_CCIPR1_XSPI2SEL_0 /*!< PLL2 'S' output selection */ +#define RCC_XSPI2CLKSOURCE_PLL2T RCC_CCIPR1_XSPI2SEL_1 /*!< PLL2 'T' output selection */ +#define RCC_XSPI2CLKSOURCE_HCLK_DIV4 RCC_CKPROTR_XSPI2SWP_2 /*!< HCLK/4 selection (recovery position) */ +/** + * @} + */ + +/** @defgroup RCCEx_CLKP_Clock_Source CLKP Clock Source + * @{ + */ +#define RCC_CLKPSOURCE_HSI 0U /*!< HSI selection (default) */ +#define RCC_CLKPSOURCE_CSI RCC_CCIPR1_CKPERSEL_0 /*!< CSI selection */ +#define RCC_CLKPSOURCE_HSE RCC_CCIPR1_CKPERSEL_1 /*!< HSE selection */ +/** + * @} + */ + +/** @defgroup RCCEx_ADC_Clock_Source ADC Clock Source + * @{ + */ +#define RCC_ADCCLKSOURCE_PLL2P 0U /*!< PLL2 'P' output selection (default) */ +#define RCC_ADCCLKSOURCE_PLL3R RCC_CCIPR1_ADCSEL_0 /*!< PLL3 'R' output selection */ +#define RCC_ADCCLKSOURCE_CLKP RCC_CCIPR1_ADCSEL_1 /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_ADF1_Clock_Source ADF1 Clock Source + * @{ + */ +#define RCC_ADF1CLKSOURCE_HCLK 0U /*!< HCLK selection (default) */ +#define RCC_ADF1CLKSOURCE_PLL2P RCC_CCIPR1_ADF1SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_ADF1CLKSOURCE_PLL3P RCC_CCIPR1_ADF1SEL_1 /*!< PLL3 'P' output selection */ +#define RCC_ADF1CLKSOURCE_PIN (RCC_CCIPR1_ADF1SEL_1 | RCC_CCIPR1_ADF1SEL_0) /*!< External I2S_PIN selection */ +#define RCC_ADF1CLKSOURCE_CSI RCC_CCIPR1_ADF1SEL_2 /*!< CSI selection */ +#define RCC_ADF1CLKSOURCE_HSI (RCC_CCIPR1_ADF1SEL_2 | RCC_CCIPR1_ADF1SEL_0) /*!< HSI selection */ +/** + * @} + */ + +/** @defgroup RCCEx_CEC_Clock_Source CEC Clock Source + * @{ + */ +#define RCC_CECCLKSOURCE_LSE 0U /*!< LSE selection (default) */ +#define RCC_CECCLKSOURCE_LSI RCC_CCIPR2_CECSEL_0 /*!< LSI selection */ +#define RCC_CECCLKSOURCE_CSI RCC_CCIPR2_CECSEL_1 /*!< CSI divided by 122 selection */ +/** + * @} + */ + +/** @defgroup RCCEx_ETH1REF_Clock_Source ETH1 REF Clock Source + * @{ + */ +#define RCC_ETH1REFCLKSOURCE_PHY 0U /*!< ETH PHY selection (default) */ +#define RCC_ETH1REFCLKSOURCE_HSE RCC_CCIPR1_ETH1REFCKSEL_0 /*!< HSE selection */ +#define RCC_ETH1REFCLKSOURCE_ETH RCC_CCIPR1_ETH1REFCKSEL_1 /*!< ETH Feedback output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_ETH1PHY_Clock_Source ETH1 PHY Clock Source + * @{ + */ +#define RCC_ETH1PHYCLKSOURCE_HSE 0U /*!< HSE selection (default) */ +#define RCC_ETH1PHYCLKSOURCE_PLL3S RCC_CCIPR1_ETH1PHYCKSEL /*!< PLL3 'S' output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_FDCAN_Clock_Source FDCAN Kernel Clock Source + * @{ + */ +#define RCC_FDCANCLKSOURCE_HSE 0U /*!< HSE selection (default) */ +#define RCC_FDCANCLKSOURCE_PLL1Q RCC_CCIPR2_FDCANSEL_0 /*!< PLL1 'Q' output selection */ +#define RCC_FDCANCLKSOURCE_PLL2P RCC_CCIPR2_FDCANSEL_1 /*!< PLL2 'P' output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_I2C23_Clock_Source I2C2/I2C3 Clock Source + * @{ + */ +#define RCC_I2C23CLKSOURCE_PCLK1 0U /*!< PCLK1 selection (default) */ +#define RCC_I2C23CLKSOURCE_PLL3R RCC_CCIPR2_I2C23SEL_0 /*!< PLL3 'R' output selection */ +#define RCC_I2C23CLKSOURCE_HSI RCC_CCIPR2_I2C23SEL_1 /*!< HSI selection */ +#define RCC_I2C23CLKSOURCE_CSI (RCC_CCIPR2_I2C23SEL_1 | RCC_CCIPR2_I2C23SEL_0) /*!< CSI selection */ +/** + * @} + */ + +/** @defgroup RCCEx_I2C1_I3C1_Clock_Source I2C1/I3C1Clock Source + * @{ + */ +#define RCC_I2C1_I3C1CLKSOURCE_PCLK1 0U /*!< PCLK1 selection (default) */ +#define RCC_I2C1_I3C1CLKSOURCE_PLL3R RCC_CCIPR2_I2C1_I3C1SEL_0 /*!< PLL3 'R' output selection */ +#define RCC_I2C1_I3C1CLKSOURCE_HSI RCC_CCIPR2_I2C1_I3C1SEL_1 /*!< HSI selection */ +#define RCC_I2C1_I3C1CLKSOURCE_CSI (RCC_CCIPR2_I2C1_I3C1SEL_1 | RCC_CCIPR2_I2C1_I3C1SEL_0) /*!< CSI selection */ +/** + * @} + */ + +/** @defgroup RCCEx_LPTIM1_Clock_Source LPTIM1 Clock Source + * @{ + */ +#define RCC_LPTIM1CLKSOURCE_PCLK1 0U /*!< PCLK1 selection (default) */ +#define RCC_LPTIM1CLKSOURCE_PLL2P RCC_CCIPR2_LPTIM1SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_LPTIM1CLKSOURCE_PLL3R RCC_CCIPR2_LPTIM1SEL_1 /*!< PLL3 'R' output selection */ +#define RCC_LPTIM1CLKSOURCE_LSE (RCC_CCIPR2_LPTIM1SEL_1 | RCC_CCIPR2_LPTIM1SEL_0) /*!< LSE selection */ +#define RCC_LPTIM1CLKSOURCE_LSI RCC_CCIPR2_LPTIM1SEL_2 /*!< LSI selection */ +#define RCC_LPTIM1CLKSOURCE_CLKP (RCC_CCIPR2_LPTIM1SEL_2 | RCC_CCIPR2_LPTIM1SEL_0) /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_LPTIM23_Clock_Source LPTIM2/LPTIM3 Clock Source + * @{ + */ +#define RCC_LPTIM23CLKSOURCE_PCLK4 0U /*!< PCLK4 selection (default) */ +#define RCC_LPTIM23CLKSOURCE_PLL2P RCC_CCIPR4_LPTIM23SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_LPTIM23CLKSOURCE_PLL3R RCC_CCIPR4_LPTIM23SEL_1 /*!< PLL3 'R' output selection */ +#define RCC_LPTIM23CLKSOURCE_LSE (RCC_CCIPR4_LPTIM23SEL_1 | RCC_CCIPR4_LPTIM23SEL_0) /*!< LSE selection */ +#define RCC_LPTIM23CLKSOURCE_LSI RCC_CCIPR4_LPTIM23SEL_2 /*!< LSI selection */ +#define RCC_LPTIM23CLKSOURCE_CLKP (RCC_CCIPR4_LPTIM23SEL_2 | RCC_CCIPR4_LPTIM23SEL_0) /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_LPTIM45_Clock_Source LPTIM4/LPTIM5 Clock Source + * @{ + */ +#define RCC_LPTIM45CLKSOURCE_PCLK4 0U /*!< PCLK4 selection (default) */ +#define RCC_LPTIM45CLKSOURCE_PLL2P RCC_CCIPR4_LPTIM45SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_LPTIM45CLKSOURCE_PLL3R RCC_CCIPR4_LPTIM45SEL_1 /*!< PLL3 'R' output selection */ +#define RCC_LPTIM45CLKSOURCE_LSE (RCC_CCIPR4_LPTIM45SEL_1 | RCC_CCIPR4_LPTIM45SEL_0) /*!< LSE selection */ +#define RCC_LPTIM45CLKSOURCE_LSI RCC_CCIPR4_LPTIM45SEL_2 /*!< LSI selection */ +#define RCC_LPTIM45CLKSOURCE_CLKP (RCC_CCIPR4_LPTIM45SEL_2 | RCC_CCIPR4_LPTIM45SEL_0) /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_LPUART1_Clock_Source LPUART1 Clock Source + * @{ + */ +#define RCC_LPUART1CLKSOURCE_PCLK4 0U /*!< PCLK4 selection (default) */ +#define RCC_LPUART1CLKSOURCE_PLL2Q RCC_CCIPR4_LPUART1SEL_0 /*!< PLL2 'Q' output selection */ +#define RCC_LPUART1CLKSOURCE_PLL3Q RCC_CCIPR4_LPUART1SEL_1 /*!< PLL2 'Q' output selection */ +#define RCC_LPUART1CLKSOURCE_HSI (RCC_CCIPR4_LPUART1SEL_1 | RCC_CCIPR4_LPUART1SEL_0) /*!< HSI selection */ +#define RCC_LPUART1CLKSOURCE_CSI RCC_CCIPR4_LPUART1SEL_2 /*!< CSI selection */ +#define RCC_LPUART1CLKSOURCE_LSE (RCC_CCIPR4_LPUART1SEL_2 | RCC_CCIPR4_LPUART1SEL_0) /*!< LSE selection */ +/** + * @} + */ + +/** @defgroup RCCEx_LTDC_Clock_Source LTDC Clock Source + * @{ + */ +#define RCC_LTDCCLKSOURCE_PLL3R 0U /*!< PLL3 'R' output selection (unique) */ +/** + * @} + */ + +/** @defgroup RCCEx_PSSI_Clock_Source PSSI Clock Source + * @{ + */ +#define RCC_PSSICLKSOURCE_PLL3R 0U /*!< PLL3 'R' output selection (default) */ +#define RCC_PSSICLKSOURCE_CLKP RCC_CCIPR1_PSSISEL /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SAI1_Clock_Source SAI1 Clock Source + * @{ + */ +#define RCC_SAI1CLKSOURCE_PLL1Q 0U /*!< PLL1 'Q' output selection (default) */ +#define RCC_SAI1CLKSOURCE_PLL2P RCC_CCIPR3_SAI1SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_SAI1CLKSOURCE_PLL3P RCC_CCIPR3_SAI1SEL_1 /*!< PLL3 'P' output selection */ +#define RCC_SAI1CLKSOURCE_PIN (RCC_CCIPR3_SAI1SEL_1 | RCC_CCIPR3_SAI1SEL_0) /*!< I2S_PIN selection */ +#define RCC_SAI1CLKSOURCE_CLKP RCC_CCIPR3_SAI1SEL_2 /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SAI2_Clock_Source SAI2 Clock Source + * @{ + */ +#define RCC_SAI2CLKSOURCE_PLL1Q 0U /*!< PLL1 'Q' output selection (default) */ +#define RCC_SAI2CLKSOURCE_PLL2P RCC_CCIPR3_SAI2SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_SAI2CLKSOURCE_PLL3P RCC_CCIPR3_SAI2SEL_1 /*!< PLL3 'P' output selection */ +#define RCC_SAI2CLKSOURCE_PIN (RCC_CCIPR3_SAI2SEL_1 | RCC_CCIPR3_SAI2SEL_0) /*!< I2S_PIN selection */ +#define RCC_SAI2CLKSOURCE_CLKP RCC_CCIPR3_SAI2SEL_2 /*!< Clock peripheral output selection */ +#define RCC_SAI2CLKSOURCE_SPDIF (RCC_CCIPR3_SAI2SEL_2 | RCC_CCIPR3_SAI2SEL_0) /*!< SPDIF output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SDMMC12_Clock_Source SDMMC Clock Source + * @{ + */ +#define RCC_SDMMC12CLKSOURCE_PLL2S 0U /*!< PLL2 'S' output selection (default) */ +#define RCC_SDMMC12CLKSOURCE_PLL2T RCC_CCIPR1_SDMMC12SEL /*!< PLL2 'T' output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SPDIFRX_Clock_Source SPDIFRX Clock Source + * @{ + */ +#define RCC_SPDIFRXCLKSOURCE_PLL1Q 0U /*!< PLL1 'Q' output selection (default) */ +#define RCC_SPDIFRXCLKSOURCE_PLL2R RCC_CCIPR2_SPDIFRXSEL_0 /*!< PLL2 'R' output selection */ +#define RCC_SPDIFRXCLKSOURCE_PLL3R RCC_CCIPR2_SPDIFRXSEL_1 /*!< PLL3 'R' output selection */ +#define RCC_SPDIFRXCLKSOURCE_HSI RCC_CCIPR2_SPDIFRXSEL /*!< HSI selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SPI1_Clock_Source SPI1 Clock Source + * @{ + */ +#define RCC_SPI1CLKSOURCE_PLL1Q 0U /*!< PLL1 'Q' output selection (default) */ +#define RCC_SPI1CLKSOURCE_PLL2P RCC_CCIPR3_SPI1SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_SPI1CLKSOURCE_PLL3P RCC_CCIPR3_SPI1SEL_1 /*!< PLL3 'P' output selection */ +#define RCC_SPI1CLKSOURCE_PIN (RCC_CCIPR3_SPI1SEL_1 | RCC_CCIPR3_SPI1SEL_0) /*!< I2S_PIN selection */ +#define RCC_SPI1CLKSOURCE_CLKP RCC_CCIPR3_SPI1SEL_2 /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SPI23_Clock_Source SPI2/SPI3 Clock Source + * @{ + */ +#define RCC_SPI23CLKSOURCE_PLL1Q 0U /*!< PLL1 'Q' output selection (default) */ +#define RCC_SPI23CLKSOURCE_PLL2P RCC_CCIPR2_SPI23SEL_0 /*!< PLL2 'P' output selection */ +#define RCC_SPI23CLKSOURCE_PLL3P RCC_CCIPR2_SPI23SEL_1 /*!< PLL3 'P' output selection */ +#define RCC_SPI23CLKSOURCE_PIN (RCC_CCIPR2_SPI23SEL_1 | RCC_CCIPR2_SPI23SEL_0) /*!< I2S_PIN selection */ +#define RCC_SPI23CLKSOURCE_CLKP RCC_CCIPR2_SPI23SEL_2 /*!< Clock peripheral output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SPI45_Clock_Source SPI4/SPI5 Clock Source + * @{ + */ +#define RCC_SPI45CLKSOURCE_PCLK2 0U /*!< PCLK2 selection (default) */ +#define RCC_SPI45CLKSOURCE_PLL2Q RCC_CCIPR3_SPI45SEL_0 /*!< PLL2 'Q' output selection */ +#define RCC_SPI45CLKSOURCE_PLL3Q RCC_CCIPR3_SPI45SEL_1 /*!< PLL3 'Q' output selection */ +#define RCC_SPI45CLKSOURCE_HSI (RCC_CCIPR3_SPI45SEL_1 | RCC_CCIPR3_SPI45SEL_0) /*!< HSI selection */ +#define RCC_SPI45CLKSOURCE_CSI RCC_CCIPR3_SPI45SEL_2 /*!< CSI selection */ +#define RCC_SPI45CLKSOURCE_HSE (RCC_CCIPR3_SPI45SEL_2 | RCC_CCIPR3_SPI45SEL_0) /*!< HSE selection */ +/** + * @} + */ + +/** @defgroup RCCEx_SPI6_Clock_Source SPI6 Clock Source + * @{ + */ +#define RCC_SPI6CLKSOURCE_PCLK4 0U /*!< PCLK4 selection (default) */ +#define RCC_SPI6CLKSOURCE_PLL2Q RCC_CCIPR4_SPI6SEL_0 /*!< PLL2 'Q' output selection */ +#define RCC_SPI6CLKSOURCE_PLL3Q RCC_CCIPR4_SPI6SEL_1 /*!< PLL3 'Q' output selection */ +#define RCC_SPI6CLKSOURCE_HSI (RCC_CCIPR4_SPI6SEL_1 | RCC_CCIPR4_SPI6SEL_0) /*!< HSI selection */ +#define RCC_SPI6CLKSOURCE_CSI RCC_CCIPR4_SPI6SEL_2 /*!< CSI selection */ +#define RCC_SPI6CLKSOURCE_HSE (RCC_CCIPR4_SPI6SEL_2 | RCC_CCIPR4_SPI6SEL_0) /*!< HSE selection */ +/** + * @} + */ + +/** @defgroup RCCEx_TIM_Prescaler_Selection TIM Prescaler Selection + * @{ + */ +#define RCC_TIMPRES_DISABLE 0U /*!< Timers clocks prescaler not set (default) */ +#define RCC_TIMPRES_ENABLE RCC_CFGR_TIMPRE /*!< Timers clocks prescaler set */ + +/** + * @} + */ + +/** @defgroup RCCEx_USART1_Clock_Source USART1 Clock Source + * @{ + */ +#define RCC_USART1CLKSOURCE_PCLK2 0U /*!< PCLK2 selection (default) */ +#define RCC_USART1CLKSOURCE_PLL2Q RCC_CCIPR3_USART1SEL_0 /*!< PLL2 'Q' output selection */ +#define RCC_USART1CLKSOURCE_PLL3Q RCC_CCIPR3_USART1SEL_1 /*!< PLL2 'Q' output selection */ +#define RCC_USART1CLKSOURCE_HSI (RCC_CCIPR3_USART1SEL_1 | RCC_CCIPR3_USART1SEL_0) /*!< HSI selection */ +#define RCC_USART1CLKSOURCE_CSI RCC_CCIPR3_USART1SEL_2 /*!< CSI selection */ +#define RCC_USART1CLKSOURCE_LSE (RCC_CCIPR3_USART1SEL_2 | RCC_CCIPR3_USART1SEL_0) /*!< LSE selection */ +/** + * @} + */ + +/** @defgroup RCCEx_USART234578_Clock_Source USART2/USART3/UART4/UART5/UART7/UART8 Clock Source + * @{ + */ +#define RCC_USART234578CLKSOURCE_PCLK1 0U /*!< PCLK1 selection (default) */ +#define RCC_USART234578CLKSOURCE_PLL2Q RCC_CCIPR2_UART234578SEL_0 /*!< PLL2 'Q' output selection */ +#define RCC_USART234578CLKSOURCE_PLL3Q RCC_CCIPR2_UART234578SEL_1 /*!< PLL3 'Q' output selection */ +#define RCC_USART234578CLKSOURCE_HSI (RCC_CCIPR2_UART234578SEL_1 | RCC_CCIPR2_UART234578SEL_0) /*!< HSI selection */ +#define RCC_USART234578CLKSOURCE_CSI RCC_CCIPR2_UART234578SEL_2 /*!< CSI selection */ +#define RCC_USART234578CLKSOURCE_LSE (RCC_CCIPR2_UART234578SEL_2 | RCC_CCIPR2_UART234578SEL_0) /*!< LSE selection */ +/** + * @} + */ + +/** @defgroup RCCEx_USB_PHYC_Clock_Source USB PHYC Clock Source + * @{ + */ +#define RCC_USBPHYCCLKSOURCE_HSE 0U /*!< HSE selection (default) */ +#define RCC_USBPHYCCLKSOURCE_HSE_DIV2 RCC_CCIPR1_USBPHYCSEL_0 /*!< HSE div 2 selection */ +#define RCC_USBPHYCCLKSOURCE_PLL3Q RCC_CCIPR1_USBPHYCSEL_1 /*!< PLL3 'Q' output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_USB_OTGFS_Clock_Source USB OTG FS Clock Source + * @{ + */ +#define RCC_USBOTGFSCLKSOURCE_HSI48 0U /*!< HSI48 selection (default) */ +#define RCC_USBOTGFSCLKSOURCE_PLL3Q RCC_CCIPR1_OTGFSSEL_0 /*!< PLL3 'Q' output selection */ +#define RCC_USBOTGFSCLKSOURCE_HSE RCC_CCIPR1_OTGFSSEL_1 /*!< HSE selection */ +#define RCC_USBOTGFSCLKSOURCE_CLK48 RCC_CCIPR1_OTGFSSEL /*!< USBPHYC CLK48 output selection */ +/** + * @} + */ + +/** @defgroup RCCEx_Clock_Protection Clock Protection + * @{ + */ +#define RCC_CLOCKPROTECT_XSPI RCC_CKPROTR_XSPICKP /*!< XSPIs clock protection */ +#define RCC_CLOCKPROTECT_FMC RCC_CKPROTR_FMCCKP /*!< FMC clock protection */ +/** + * @} + */ + + +/** @defgroup RCCEx_EXTI_LINE_LSECSS LSE CSS external interrupt line + * @{ + */ +#define RCC_EXTI_LINE_LSECSS EXTI_IMR1_IM18 /*!< External interrupt line 18 connected to the LSE CSS EXTI Line */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Status CRS Status + * @{ + */ +#define RCC_CRS_NONE 0x00000000U +#define RCC_CRS_TIMEOUT 0x00000001U +#define RCC_CRS_SYNCOK 0x00000002U +#define RCC_CRS_SYNCWARN 0x00000004U +#define RCC_CRS_SYNCERR 0x00000008U +#define RCC_CRS_SYNCMISS 0x00000010U +#define RCC_CRS_TRIMOVF 0x00000020U +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroSource CRS SynchroSource + * @{ + */ +#define RCC_CRS_SYNC_SOURCE_GPIO 0U /*!< Synchro Signal source GPIO */ +#define RCC_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define RCC_CRS_SYNC_SOURCE_USB_OTG_FS CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB OTG FS SOF (default) */ +#define RCC_CRS_SYNC_SOURCE_USB_OTG_HS (CRS_CFGR_SYNCSRC_1|CRS_CFGR_SYNCSRC_0) /*!< Synchro Signal source USB OTG HS SOF */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroDivider CRS SynchroDivider + * @{ + */ +#define RCC_CRS_SYNC_DIV1 0U /*!< Synchro Signal not divided (default) */ +#define RCC_CRS_SYNC_DIV2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ +#define RCC_CRS_SYNC_DIV4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ +#define RCC_CRS_SYNC_DIV8 (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ +#define RCC_CRS_SYNC_DIV16 CRS_CFGR_SYNCDIV_2 /*!< Synchro Signal divided by 16 */ +#define RCC_CRS_SYNC_DIV32 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ +#define RCC_CRS_SYNC_DIV64 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ +#define RCC_CRS_SYNC_DIV128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroPolarity CRS SynchroPolarity + * @{ + */ +#define RCC_CRS_SYNC_POLARITY_RISING 0U /*!< Synchro Active on rising edge (default) */ +#define RCC_CRS_SYNC_POLARITY_FALLING CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ReloadValueDefault CRS ReloadValueDefault + * @{ + */ +#define RCC_CRS_RELOADVALUE_DEFAULT 0x0000BB7FU /*!< 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). */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ErrorLimitDefault CRS ErrorLimitDefault + * @{ + */ +#define RCC_CRS_ERRORLIMIT_DEFAULT 0x00000022U /*!< Default Frequency error limit */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_HSI48CalibrationDefault CRS HSI48CalibrationDefault + * @{ + */ +#define RCC_CRS_HSI48CALIBRATION_DEFAULT 0x00000020U /*!< 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 */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_FreqErrorDirection CRS FreqErrorDirection + * @{ + */ +#define RCC_CRS_FREQERRORDIR_UP 0U /*!< Upcounting direction, the actual frequency is above the target */ +#define RCC_CRS_FREQERRORDIR_DOWN CRS_ISR_FEDIR /*!< Downcounting direction, the actual frequency is below the target */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Interrupt_Sources CRS Interrupt Sources + * @{ + */ +#define RCC_CRS_IT_SYNCOK CRS_CR_SYNCOKIE /*!< SYNC event OK */ +#define RCC_CRS_IT_SYNCWARN CRS_CR_SYNCWARNIE /*!< SYNC warning */ +#define RCC_CRS_IT_ERR CRS_CR_ERRIE /*!< Error */ +#define RCC_CRS_IT_ESYNC CRS_CR_ESYNCIE /*!< Expected SYNC */ +#define RCC_CRS_IT_SYNCERR CRS_CR_ERRIE /*!< SYNC error */ +#define RCC_CRS_IT_SYNCMISS CRS_CR_ERRIE /*!< SYNC missed */ +#define RCC_CRS_IT_TRIMOVF CRS_CR_ERRIE /*!< Trimming overflow or underflow */ + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Flags CRS Flags + * @{ + */ +#define RCC_CRS_FLAG_SYNCOK CRS_ISR_SYNCOKF /*!< SYNC event OK flag */ +#define RCC_CRS_FLAG_SYNCWARN CRS_ISR_SYNCWARNF /*!< SYNC warning flag */ +#define RCC_CRS_FLAG_ERR CRS_ISR_ERRF /*!< Error flag */ +#define RCC_CRS_FLAG_ESYNC CRS_ISR_ESYNCF /*!< Expected SYNC flag */ +#define RCC_CRS_FLAG_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ +#define RCC_CRS_FLAG_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ +#define RCC_CRS_FLAG_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Macros RCCEx Exported Macros + * @{ + */ + +/** @brief Macro to configure the ADC clock + * @param __ADC_CLKSOURCE__ specifies the ADC digital interface clock source. + * This parameter can be one of the following values: + * @arg RCC_ADCCLKSOURCE_PLL2P PLL2_P Clock selected as ADC clock + * @arg RCC_ADCCLKSOURCE_PLL3R PLL3_R Clock selected as ADC clock + * @arg RCC_ADCCLKSOURCE_CLKP CLKP Clock selected as ADC clock + */ +#define __HAL_RCC_ADC_CONFIG(__ADC_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ADCSEL, (uint32_t)(__ADC_CLKSOURCE__)) + +/** @brief Macro to get the ADC clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_ADCCLKSOURCE_PLL2P PLL2_P Clock selected as ADC clock + * @arg RCC_ADCCLKSOURCE_PLL3R PLL3_R Clock selected as ADC clock + * @arg RCC_ADCCLKSOURCE_CLKP CLKP Clock selected as ADC clock + */ +#define __HAL_RCC_GET_ADC_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ADCSEL))) + +/** @brief Macro to configure the ADF1 clock + * @param __ADF1_CLKSOURCE__ specifies the ADF1 clock source. + * This parameter can be one of the following values: + * @arg RCC_ADF1CLKSOURCE_HCLK HCLK Clock selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_PLL2P PLL2_P Clock selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_PLL3P PLL3_P Clock selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_PIN External I2S_CKIN selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_CSI CSI selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_HSI HSI selected as ADF1 clock + */ +#define __HAL_RCC_ADF1_CONFIG(__ADF1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ADF1SEL, (uint32_t)(__ADF1_CLKSOURCE__)) + +/** @brief Macro to get the ADF1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_ADF1CLKSOURCE_HCLK HCLK Clock selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_PLL2P PLL2_P Clock selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_PLL3P PLL3_P Clock selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_PIN External I2S_CKIN selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_CSI CSI selected as ADF1 clock + * @arg RCC_ADF1CLKSOURCE_HSI HSI selected as ADF1 clock + */ +#define __HAL_RCC_GET_ADF1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ADF1SEL))) + +/** @brief Macro to configure the HDMI-CEC clock source. + * @param __CEC_CLKSOURCE__ 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 CSI divided by 122 selected as CEC clock + */ +#define __HAL_RCC_CEC_CONFIG(__CEC_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_CECSEL, (uint32_t)(__CEC_CLKSOURCE__)) + +/** @brief Macro to get the HDMI-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 CSI divided by 122 selected as CEC clock + */ +#define __HAL_RCC_GET_CEC_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_CECSEL))) + +/** @brief Macro to configure the CLKP : Oscillator clock for peripheral + * @param __CLKP_CLKSOURCE__ specifies Oscillator clock for peripheral + * This parameter can be one of the following values: + * @arg RCC_CLKPSOURCE_HSI HSI selected as peripheral clock (default) + * @arg RCC_CLKPSOURCE_CSI CSI selected as peripheral clock + * @arg RCC_CLKPSOURCE_HSE HSE selected as peripheral clock + */ +#define __HAL_RCC_CLKP_CONFIG(__CLKP_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_CKPERSEL, (uint32_t)(__CLKP_CLKSOURCE__)) + +/** @brief Macro to get the Oscillator clock for peripheral source. + * @retval The clock source can be one of the following values: + * @arg RCC_CLKPSOURCE_HSI HSI selected as peripheral clock (default) + * @arg RCC_CLKPSOURCE_CSI CSI selected as peripheral clock + * @arg RCC_CLKPSOURCE_HSE HSE selected as peripheral clock + */ +#define __HAL_RCC_GET_CLKP_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_CKPERSEL))) + +/** @brief Macro to configure the ETH1 REF clock source. + * @param __ETH1REF_CLKSOURCE__ specifies clock source for ETH1 REF + * This parameter can be one of the following values: + * @arg RCC_ETH1REFCLKSOURCE_PHY ETH PHY selected as ETH1 REF clock (default) + * @arg RCC_ETH1REFCLKSOURCE_HSE HSE selected as ETH1 clock + * @arg RCC_ETH1REFCLKSOURCE_ETH ETH feedback selected as ETH1 REF clock + */ +#define __HAL_RCC_ETH1REF_CONFIG(__ETH1REF_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ETH1REFCKSEL, (uint32_t)(__ETH1REF_CLKSOURCE__)) + +/** @brief Macro to get the ETH1 REF clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_ETH1REFCLKSOURCE_PHY ETH PHY selected as ETH1 clock (default) + * @arg RCC_ETH1REFCLKSOURCE_HSE HSE selected as ETH1 clock + * @arg RCC_ETH1REFCLKSOURCE_ETH ETH feedback selected as ETH1 clock + */ +#define __HAL_RCC_GET_ETH1REF_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ETH1REFCKSEL))) + +/** @brief Macro to configure the ETH1 PHY clock source. + * @param __ETH1PHY_CLKSOURCE__ specifies clock source for ETH PHY + * This parameter can be one of the following values: + * @arg RCC_ETH1PHYCLKSOURCE_HSE HSE selected as ETH PHY clock (default) + * @arg RCC_ETH1PHYCLKSOURCE_PLL3S PLL3_S selected as ETH PHY clock + */ +#define __HAL_RCC_ETH1PHY_CONFIG(__ETH1PHY_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ETH1PHYCKSEL, (uint32_t)(__ETH1PHY_CLKSOURCE__)) + +/** @brief Macro to get the ETH1 PHY clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_ETH1PHYCLKSOURCE_HSE HSE selected as ETH PHY clock (default) + * @arg RCC_ETH1PHYCLKSOURCE_PLL3S PLL3_S selected as ETH PHY clock + */ +#define __HAL_RCC_GET_ETH1PHY_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ETH1PHYCKSEL))) + +/** @brief Macro to configure the FDCAN kernel clock source. + * @param __FDCAN_CLKSOURCE__ specifies clock source for FDCAN kernel + * This parameter can be one of the following values: + * @arg RCC_FDCANCLKSOURCE_HSE HSE selected as FDCAN kernel clock (default) + * @arg RCC_FDCANCLKSOURCE_PLL1Q PLL1_Q selected as FDCAN kernel clock + * @arg RCC_FDCANCLKSOURCE_PLL2P PLL2_P selected as FDCAN kernel clock + */ +#define __HAL_RCC_FDCAN_CONFIG(__FDCAN_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_FDCANSEL, (uint32_t)(__FDCAN_CLKSOURCE__)) + +/** @brief Macro to get the FDCAN kernel clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_FDCANCLKSOURCE_HSE HSE selected as FDCAN kernel clock (default) + * @arg RCC_FDCANCLKSOURCE_PLL1Q PLL1_Q selected as FDCAN kernel clock + * @arg RCC_FDCANCLKSOURCE_PLL2P PLL2_P selected as FDCAN kernel clock + */ +#define __HAL_RCC_GET_FDCAN_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_FDCANSEL))) + +/** @brief Macro to configure the FMC clock source. + * + * @param __FMC_CLKSOURCE__ specifies the FMC clock source. + * @arg RCC_FMCCLKSOURCE_HCLK HCLK Clock selected as FMC clock + * @arg RCC_FMCCLKSOURCE_PLL1Q PLL1_Q Clock selected as FMC clock + * @arg RCC_FMCCLKSOURCE_PLL2R PLL2_R Clock selected as FMC clock + * @arg RCC_FMCCLKSOURCE_HSI HSI selected as FMC clock + */ +#define __HAL_RCC_FMC_CONFIG(__FMC_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_FMCSEL, (uint32_t)(__FMC_CLKSOURCE__)) + +/** @brief Macro to get the FMC clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_FMCCLKSOURCE_HCLK HCLK Clock selected as FMC clock + * @arg RCC_FMCCLKSOURCE_PLL1Q PLL1_Q Clock selected as FMC clock + * @arg RCC_FMCCLKSOURCE_PLL2R PLL2_R Clock selected as FMC clock + * @arg RCC_FMCCLKSOURCE_HSI HSI selected as FMC clock + * @arg RCC_FMCCLKSOURCE_HCLK_DIV4 Recovery Clock selected as FMC clock + */ +#define __HAL_RCC_GET_FMC_SOURCE() ((READ_BIT(RCC->CKPROTR, RCC_CKPROTR_FMCSWP) == RCC_FMCCLKSOURCE_HCLK_DIV4) ? \ + RCC_FMCCLKSOURCE_HCLK_DIV4 : ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_FMCSEL)))) + +/** @brief Macro to configure the I2C1/I3C1 clock source. + * @param __I2C1_I3C1_CLKSOURCE__ specifies the I2C1/I3C1clock source. + * This parameter can be one of the following values: + * @arg RCC_I2C1_I3C1CLKSOURCE_PCLK1 APB1 selected as I2C1/I3C1clock + * @arg RCC_I2C1_I3C1CLKSOURCE_PLL3R PLL3_R selected as I2C1/I3C1clock + * @arg RCC_I2C1_I3C1CLKSOURCE_HSI HSI selected as I2C1/I3C1clock + * @arg RCC_I2C1_I3C1CLKSOURCE_CSI CSI selected as I2C1/I3C1clock + */ +#define __HAL_RCC_I2C1_I3C1_CONFIG(__I2C1_I3C1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_I2C1_I3C1SEL, (uint32_t)(__I2C1_I3C1_CLKSOURCE__)) + +/** @brief Macro to get the I2C1/I3C1clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_I2C1_I3C1CLKSOURCE_PCLK1 APB1 selected as I2C1/I3C1clock + * @arg RCC_I2C1_I3C1CLKSOURCE_PLL3R PLL3_R selected as I2C1/I3C1clock + * @arg RCC_I2C1_I3C1CLKSOURCE_HSI HSI selected as I2C1/I3C1clock + * @arg RCC_I2C1_I3C1CLKSOURCE_CSI CSI selected as I2C1/I3C1clock + */ +#define __HAL_RCC_GET_I2C1_I3C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_I2C1_I3C1SEL))) + +/** @brief Macro to configure the I2C2/I2C3 clock source. + * @param __I2C23_CLKSOURCE__ specifies the I2C2/I2C3 clock source. + * This parameter can be one of the following values: + * @arg RCC_I2C23CLKSOURCE_PCLK1 APB1 selected as I2C2/I2C3 clock + * @arg RCC_I2C23CLKSOURCE_PLL3R PLL3_R selected as I2C2/I2C3 clock + * @arg RCC_I2C23CLKSOURCE_HSI HSI selected as I2C2/I2C3 clock + * @arg RCC_I2C23CLKSOURCE_CSI CSI selected as I2C2/I2C3 clock + */ +#define __HAL_RCC_I2C23_CONFIG(__I2C23_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_I2C23SEL, (uint32_t)(__I2C23_CLKSOURCE__)) + +/** @brief Macro to get the I2C2/I2C3 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_I2C23CLKSOURCE_PCLK1 APB1 selected as I2C2/I2C3 clock + * @arg RCC_I2C23CLKSOURCE_PLL3R PLL3_R selected as I2C2/I2C3 clock + * @arg RCC_I2C23CLKSOURCE_HSI HSI selected as I2C2/I2C3 clock + * @arg RCC_I2C23CLKSOURCE_CSI CSI selected as I2C2/I2C3 clock + */ +#define __HAL_RCC_GET_I2C23_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_I2C23SEL))) + +/** @brief Macro to configure the I3C1 clock source. + * @param __I3C1_CLKSOURCE__ specifies the I3C1 clock source. + * This parameter can be one of the following values: + * @arg RCC_I3C1CLKSOURCE_PCLK1 APB1 selected as I3C1 clock + * @arg RCC_I3C1CLKSOURCE_PLL3R PLL3_R selected as I3C1 clock + * @arg RCC_I3C1CLKSOURCE_HSI HSI selected as I3C1 clock + * @arg RCC_I3C1CLKSOURCE_CSI CSI selected as I3C1 clock + */ +#define __HAL_RCC_I3C1_CONFIG(__I3C1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_I2C1_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 RCC_I3C1CLKSOURCE_PCLK1 APB1 selected as I3C1 clock + * @arg RCC_I3C1CLKSOURCE_PLL3R PLL3_R selected as I3C1 clock + * @arg RCC_I3C1CLKSOURCE_HSI HSI selected as I3C1 clock + * @arg RCC_I3C1CLKSOURCE_CSI CSI selected as I3C1 clock + */ +#define __HAL_RCC_GET_I3C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_I2C1_I3C1SEL))) + +/** @brief Macro to configure the LPTIM1 clock source. + * @param __LPTIM1_CLKSOURCE__ specifies the LPTIM1 clock source. + * This parameter can be one of the following values: + * @arg RCC_LPTIM1CLKSOURCE_PCLK1 APB1 clock selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_PLL2P PLL2_P selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_PLL3R PLL3_R selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_LSE LSE selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_LSI LSI Clock selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_CLKP CLKP selected as LPTIM1 clock + */ +#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 RCC_LPTIM1CLKSOURCE_PCLK1 APB1 clock selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_PLL2P PLL2_P selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_PLL3R PLL3_R selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_LSE LSE selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_LSI LSI Clock selected as LPTIM1 clock + * @arg RCC_LPTIM1CLKSOURCE_CLKP CLKP selected as LPTIM1 clock + */ +#define __HAL_RCC_GET_LPTIM1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM1SEL))) + +/** @brief Macro to configure the LPTIM2/LPTIM3 clock source. + * @param __LPTIM23_CLKSOURCE__ specifies the LPTIM2/LPTIM3 clock source. + * This parameter can be one of the following values: + * @arg RCC_LPTIM23CLKSOURCE_PCLK4 APB4 clock selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_PLL2P PLL2_P selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_PLL3R PLL3_R selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_LSE LSE selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_LSI LSI Clock selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_CLKP CLKP selected as LPTIM2/LPTIM3 clock + */ +#define __HAL_RCC_LPTIM23_CONFIG(__LPTIM23_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_LPTIM23SEL, (uint32_t)(__LPTIM23_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM2/LPTIM3 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_LPTIM23CLKSOURCE_PCLK4 APB4 clock selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_PLL2P PLL2_P selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_PLL3R PLL3_R selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_LSE LSE selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_LSI LSI Clock selected as LPTIM2/LPTIM3 clock + * @arg RCC_LPTIM23CLKSOURCE_CLKP CLKP selected as LPTIM2/LPTIM3 clock + */ +#define __HAL_RCC_GET_LPTIM23_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_LPTIM23SEL))) + +/** @brief Macro to configure the LPTIM4/LPTIM5 clock source. + * @param __LPTIM45_CLKSOURCE__ specifies the LPTIM4/LPTIM5 clock source. + * This parameter can be one of the following values: + * @arg RCC_LPTIM45CLKSOURCE_PCLK4 APB4 clock selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_PLL2P PLL2_P selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_PLL3R PLL3_R selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_LSE LSE selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_LSI LSI Clock selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_CLKP CLKP selected as LPTIM4/LPTIM5 clock + */ +#define __HAL_RCC_LPTIM45_CONFIG(__LPTIM45_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_LPTIM45SEL, (uint32_t)(__LPTIM45_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM4/LPTIM5 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_LPTIM45CLKSOURCE_PCLK4 APB4 clock selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_PLL2P PLL2_P selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_PLL3R PLL3_R selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_LSE LSE selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_LSI LSI Clock selected as LPTIM4/LPTIM5 clock + * @arg RCC_LPTIM45CLKSOURCE_CLKP CLKP selected as LPTIM4/LPTIM5 clock + */ +#define __HAL_RCC_GET_LPTIM45_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_LPTIM45SEL))) + +/** @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 RCC_LPUART1CLKSOURCE_PCLK4 APB4 Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_PLL2Q PLL2_Q Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_PLL3Q PLL3_Q Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_HSI HSI selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_CSI CSI Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_LSE LSE selected as LPUART1 clock + */ +#define __HAL_RCC_LPUART1_CONFIG(__LPUART1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_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 RCC_LPUART1CLKSOURCE_PCLK4 APB4 Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_PLL2Q PLL2_Q Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_PLL3Q PLL3_Q Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_HSI HSI selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_CSI CSI Clock selected as LPUART1 clock + * @arg RCC_LPUART1CLKSOURCE_LSE LSE selected as LPUART1 clock + */ +#define __HAL_RCC_GET_LPUART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_LPUART1SEL))) + +/** @brief Macro to get the LTDC clock source. + * @retval The clock source is internally connected to: + * @arg RCC_LTDCCLKSOURCE_PLL3R PLL3_R Clock selected as LTDC clock + */ +#define __HAL_RCC_GET_LTDC_SOURCE() RCC_LTDCCLKSOURCE_PLL3R + +/** @brief Macro to configure the XSPI1 clock source. + * + * @param __XSPI1_CLKSOURCE__ specifies the XSPI1 clock source. + * @arg RCC_XSPI1CLKSOURCE_HCLK HCLK Clock selected as XSPI1 clock + * @arg RCC_XSPI1CLKSOURCE_PLL2S PLL2_S Clock selected as XSPI1 clock + * @arg RCC_XSPI1CLKSOURCE_PLL2T PLL2_T Clock selected as XSPI1 clock + */ +#define __HAL_RCC_XSPI1_CONFIG(__XSPI1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_XSPI1SEL, (uint32_t)(__XSPI1_CLKSOURCE__)) + +/** @brief Macro to get the XSPI1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_XSPI1CLKSOURCE_HCLK HCLK Clock selected as XSPI1 clock + * @arg RCC_XSPI1CLKSOURCE_PLL2S PLL2_S Clock selected as XSPI1 clock + * @arg RCC_XSPI1CLKSOURCE_PLL2T PLL2_T Clock selected as XSPI1 clock + * @arg RCC_XSPI1CLKSOURCE_HCLK_DIV4 Recovery Clock selected as XSPI1 clock + */ +#define __HAL_RCC_GET_XSPI1_SOURCE() ((READ_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPI1SWP) == RCC_XSPI1CLKSOURCE_HCLK_DIV4) ? \ + RCC_XSPI1CLKSOURCE_HCLK_DIV4 : ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_XSPI1SEL)))) + +/** @brief Macro to configure the XSPI2 clock source. + * + * @param __XSPI2_CLKSOURCE__ specifies the XSPI2 clock source. + * @arg RCC_XSPI2CLKSOURCE_HCLK HCLK Clock selected as XSPI2 clock + * @arg RCC_XSPI2CLKSOURCE_PLL2S PLL2_S Clock selected as XSPI2 clock + * @arg RCC_XSPI2CLKSOURCE_PLL2T PLL2_T Clock selected as XSPI2 clock + */ +#define __HAL_RCC_XSPI2_CONFIG(__XSPI2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_XSPI2SEL, (uint32_t)(__XSPI2_CLKSOURCE__)) + +/** @brief Macro to get the XSPI2 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_XSPI2CLKSOURCE_HCLK HCLK Clock selected as XSPI2 clock + * @arg RCC_XSPI2CLKSOURCE_PLL2S PLL2_S Clock selected as XSPI2 clock + * @arg RCC_XSPI2CLKSOURCE_PLL2T PLL2_T Clock selected as XSPI2 clock + * @arg RCC_XSPI2CLKSOURCE_HCLK_DIV4 Recovery Clock selected as XSPI2 clock + */ +#define __HAL_RCC_GET_XSPI2_SOURCE() ((READ_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPI2SWP) == RCC_XSPI2CLKSOURCE_HCLK_DIV4) ? \ + RCC_XSPI2CLKSOURCE_HCLK_DIV4 : ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_XSPI2SEL)))) + +/** + * @brief Macro to configure the PSSI clock source. + * @param __PSSI_CLKSOURCE__ defines the PSSI clock source. + * This parameter can be one of the following values: + * @arg RCC_PSSICLKSOURCE_PLL3R PLL3_R selected as PSSI clock + * @arg RCC_PSSICLKSOURCE_CLKP Peripheral clock selected as PSSI clock + * @retval None + */ +#define __HAL_RCC_PSSI_CONFIG(__PSSI_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_PSSISEL, (__PSSI_CLKSOURCE__)) + +/** @brief Macro to get the PSSI clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_PSSICLKSOURCE_PLL3R PLL3_R selected as PSSI clock + * @arg RCC_PSSICLKSOURCE_CLKP Peripheral clock selected as PSSI clock + */ +#define __HAL_RCC_GET_PSSI_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_PSSISEL))) + +/** + * @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 RCC_SAI1CLKSOURCE_PLL1Q PLL1_Q selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_PLL2P PLL2_P selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_PLL3P PLL3_P selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_PIN External I2S_CKIN selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_CLKP Peripheral clock selected as SAI1 clock + * @retval None + */ +#define __HAL_RCC_SAI1_CONFIG(__SAI1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SAI1SEL, (__SAI1_CLKSOURCE__)) + +/** @brief Macro to get the SAI1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SAI1CLKSOURCE_PLL1Q PLL1_Q selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_PLL2P PLL2_P selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_PLL3P PLL3_P selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_PIN External I2S_CKIN selected as SAI1 clock + * @arg RCC_SAI1CLKSOURCE_CLKP Peripheral clock selected as SAI1 clock + */ +#define __HAL_RCC_GET_SAI1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SAI1SEL))) + +/** + * @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 RCC_SAI2CLKSOURCE_PLL1Q PLL1_Q selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_PLL2P PLL2_P selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_PLL3P PLL3_P selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_PIN External I2S_CKIN selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_CLKP Peripheral clock selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_SPDIF SPDIF output clock selected as SAI2 clock + * @retval None + */ +#define __HAL_RCC_SAI2_CONFIG(__SAI2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SAI2SEL, (__SAI2_CLKSOURCE__)) + +/** @brief Macro to get the SAI2 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SAI2CLKSOURCE_PLL1Q PLL1_Q selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_PLL2P PLL2_P selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_PLL3P PLL3_P selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_PIN External I2S_CKIN selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_CLKP Peripheral clock selected as SAI2 clock + * @arg RCC_SAI2CLKSOURCE_SPDIF SPDIF output clock selected as SAI2 clock + */ +#define __HAL_RCC_GET_SAI2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SAI2SEL))) + + +/** @brief Macro to configure the SDMMC kernel clock source. + * @param __SDMMC12_CLKSOURCE__ specifies clock source for SDMMC + * This parameter can be one of the following values: + * @arg RCC_SDMMC12CLKSOURCE_PLL2S PLL2_S selected as SDMMC kernel clock + * @arg RCC_SDMMC12CLKSOURCE_PLL2T PLL2_R selected as SDMMC kernel clock + */ +#define __HAL_RCC_SDMMC12_CONFIG(__SDMMC12_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_SDMMC12SEL, (uint32_t)(__SDMMC12_CLKSOURCE__)) + +/** @brief Macro to get the SDMMC kernel clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SDMMC12CLKSOURCE_PLL2S PLL2_S selected as SDMMC12 kernel clock + * @arg RCC_SDMMC12CLKSOURCE_PLL2T PLL2_R selected as SDMMC12 kernel clock + */ +#define __HAL_RCC_GET_SDMMC12_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_SDMMC12SEL))) + +/** + * @brief Macro to Configure the SPDIFRX clock source. + * @param __SPDIFRX_CLKSOURCE__ defines the SPDIFRX clock source. + * This parameter can be one of the following values: + * @arg RCC_SPDIFRXCLKSOURCE_PLL1Q PLL1_Q selected as SPDIFRX clock + * @arg RCC_SPDIFRXCLKSOURCE_PLL2R PLL2_R selected as SPDIFRX clock + * @arg RCC_SPDIFRXCLKSOURCE_PLL3R PLL3_R selected as SPDIFRX clock + * @arg RCC_SPDIFRXCLKSOURCE_HSI HSI selected as SPDIFRX clock + * @retval None + */ +#define __HAL_RCC_SPDIFRX_CONFIG(__SPDIFRX_CLKSOURCE__ ) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_SPDIFRXSEL, (__SPDIFRX_CLKSOURCE__)) + +/** + * @brief Macro to get the SPDIFRX clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPDIFRXCLKSOURCE_PLL1Q PLL1_Q selected as SPDIFRX clock + * @arg RCC_SPDIFRXCLKSOURCE_PLL2R PLL2_R selected as SPDIFRX clock + * @arg RCC_SPDIFRXCLKSOURCE_PLL3R PLL3_R selected as SPDIFRX clock + * @arg RCC_SPDIFRXCLKSOURCE_HSI HSI selected as SPDIFRX clock + * @retval None + */ +#define __HAL_RCC_GET_SPDIFRX_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_SPDIFRXSEL))) + +/** + * @brief Macro to configure the SPI1 clock source. + * @param __SPI1_CLKSOURCE__ defines the SPI1 clock source. + * This parameter can be one of the following values: + * @arg RCC_SPI1CLKSOURCE_PLL1Q PLL1_Q selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL2P PLL2_P selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL3P PLL3_P selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PIN External I2S_CKIN selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_CLKP Peripheral clock selected as SPI1 clock + * @retval None + */ +#define __HAL_RCC_SPI1_CONFIG(__SPI1_CLKSOURCE__ ) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI1SEL, (__SPI1_CLKSOURCE__)) + +/** @brief Macro to get the SPI1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI1CLKSOURCE_PLL1Q PLL1_Q selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL2P PLL2_P selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL3P PLL3_P selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PIN External I2S_CKIN selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_CLKP Peripheral clock selected as SPI1 clock + */ +#define __HAL_RCC_GET_SPI1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI1SEL))) + +/** + * @brief Macro to configure the SPI2/SPI3 clock source. + * @param __SPI23_CLKSOURCE__ defines the SPI2/SPI3 clock source. + * This parameter can be one of the following values: + * @arg RCC_SPI23CLKSOURCE_PLL1Q PLL1_Q selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_PLL2P PLL2_P selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_PLL3P PLL3_P selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_PIN External I2S_CKIN selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_CLKP Peripheral clock selected as SPI2/SPI3 clock + * @retval None + */ +#define __HAL_RCC_SPI23_CONFIG(__SPI23_CLKSOURCE__ ) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_SPI23SEL, (__SPI23_CLKSOURCE__)) + +/** @brief Macro to get the SPI2/SPI3 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI23CLKSOURCE_PLL1Q PLL1_Q selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_PLL2P PLL2_P selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_PLL3P PLL3_P selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_PIN External I2S_CKIN selected as SPI2/SPI3 clock + * @arg RCC_SPI23CLKSOURCE_CLKP Peripheral clock selected as SPI2/SPI3 clock + */ +#define __HAL_RCC_GET_SPI23_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_SPI23SEL))) + +/** + * @brief Macro to configure the SPI4/SPI5 clock source. + * @param __SPI45_CLKSOURCE__ defines the SPI4/SPI5 clock source. + * This parameter can be one of the following values: + * @arg RCC_SPI45CLKSOURCE_PCLK2 APB2 Clock selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_PLL2Q PLL2_Q selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_PLL3Q PLL3_Q selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_HSI HSI selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_CSI CSI selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_HSE HSE selected as SPI4/SPI5 clock + * @retval None + */ +#define __HAL_RCC_SPI45_CONFIG(__SPI45_CLKSOURCE__ ) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI45SEL, (__SPI45_CLKSOURCE__)) + +/** @brief Macro to get the SPI4/SPI5 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI45CLKSOURCE_PCLK2 APB2 Clock selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_PLL2Q PLL2_Q selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_PLL3Q PLL3_Q selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_HSI HSI selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_CSI CSI selected as SPI4/SPI5 clock + * @arg RCC_SPI45CLKSOURCE_HSE HSE selected as SPI4/SPI5 clock + */ +#define __HAL_RCC_GET_SPI45_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI45SEL))) + +/** + * @brief Macro to configure the SPI6 clock source. + * @param __SPI6_CLKSOURCE__ defines the SPI6 clock source. + * This parameter can be one of the following values: + * @arg RCC_SPI6CLKSOURCE_PCLK4 APB4 Clock selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL2Q PLL2_Q selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL3Q PLL3_Q selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSI HSI selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_CSI CSI selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSE HSE selected as SPI6 clock + * @retval None + */ +#define __HAL_RCC_SPI6_CONFIG(__SPI6_CLKSOURCE__ ) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SPI6SEL, (__SPI6_CLKSOURCE__)) + +/** @brief Macro to get the SPI6 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI6CLKSOURCE_PCLK4 APB4 Clock selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL2Q PLL2_Q selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL3Q PLL3_Q selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSI HSI selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_CSI CSI selected as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSE HSE selected as SPI6 clock + */ +#define __HAL_RCC_GET_SPI6_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_SPI6SEL))) + +/** @brief Macro to configure the USART1 clock source. + * @param __USART1_CLKSOURCE__ specifies the USART1 clock source. + * This parameter can be one of the following values: + * @arg RCC_USART1CLKSOURCE_PCLK2 APB2 Clock selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_PLL2Q PLL2_Q selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_PLL3Q PLL3_Q selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_CSI CSI selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + */ +#define __HAL_RCC_USART1_CONFIG(__USART1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_USART1SEL, (uint32_t)(__USART1_CLKSOURCE__)) + +/** @brief Macro to get the USART1/6/9* /10* clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_USART1CLKSOURCE_PCLK2 APB2 Clock selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_PLL2Q PLL2_Q selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_PLL3Q PLL3_Q selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_CSI CSI selected as USART1 clock + * @arg RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + */ +#define __HAL_RCC_GET_USART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_USART1SEL))) + +/** @brief Macro to configure the USART2/USART3/UART4/UART5/UART7/UART8 clock source. + * @param __USART234578_CLKSOURCE__ specifies the USART2/UART3/UART4/UART5/UART7/UART8 clock source. + * This parameter can be one of the following values: + * @arg RCC_USART234578CLKSOURCE_PCLK1 APB1 Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_PLL2Q PLL2_Q Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_PLL3Q PLL3_Q Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_HSI HSI selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_CSI CSI Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_LSE LSE selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + */ +#define __HAL_RCC_USART234578_CONFIG(__USART234578_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_UART234578SEL, (uint32_t)(__USART234578_CLKSOURCE__)) + +/** @brief Macro to get the USART2/USART3/UART4/UART5/UART7/UART8 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_USART234578CLKSOURCE_PCLK1 APB1 Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_PLL2Q PLL2_Q Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_PLL3Q PLL3_Q Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_HSI HSI selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_CSI CSI Clock selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + * @arg RCC_USART234578CLKSOURCE_LSE LSE selected as USART2/USART3/UART4/UART5/UART7/UART8 clock + */ +#define __HAL_RCC_GET_USART234578_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_UART234578SEL))) + +/** @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_DISABLE + * The timers kernel clock is equal to: + * - PCLKx_freq, if PCLKx = RCC_APBx_DIV1 + * - 2*PCLKx_freq, otherwise (default after reset) + * @arg RCC_TIMPRES_ENABLE + * The timers kernel clock is equal to: + * - PCLKx_freq, if PCLKx = RCC_APBx_DIV1 + * - 2*PCLKx_freq, if PCLKx = RCC_APBx_DIV2 + * - 4*PCLKx_freq, otherwise + */ +#define __HAL_RCC_TIMCLKPRESCALER_CONFIG(__PRESC__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_TIMPRE, (uint32_t)(__PRESC__)) + +/** @brief Macro to get the Timers clocks prescalers + * @retval The parameter can be one of the following values: + * @arg RCC_TIMPRES_DISABLE + * The timers kernel clock is equal to: + * - PCLKx_freq, if PCLKx = RCC_APBx_DIV1 + * - 2*PCLKx_freq, otherwise (default after reset) + * @arg RCC_TIMPRES_ENABLE + * The timers kernel clock is equal to: + * - PCLKx_freq, if PCLKx = RCC_APBx_DIV1 + * - 2*PCLKx_freq, if PCLKx = RCC_APBx_DIV2 + * - 4*PCLKx_freq, otherwise + */ +#define __HAL_RCC_GET_TIMCLKPRESCALER() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_TIMPRE))) + +/** @brief Macro to configure the USBPHYC clock. + * @param __USBPHYC_CLKSOURCE__ specifies the USBPHYC clock source. + * This parameter can be one of the following values: + * @arg RCC_USBPHYCCLKSOURCE_HSE HSE selected as USBPHYC clock + * @arg RCC_USBPHYCCLKSOURCE_HSE_DIV2 HSE divided by 2 selected as USBPHYC clock + * @arg RCC_USBPHYCCLKSOURCE_PLL3Q PLL3_Q Clock selected as USBPHYC clock + */ +#define __HAL_RCC_USBPHYC_CONFIG(__USBPHYC_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USBPHYCSEL, (uint32_t)(__USBPHYC_CLKSOURCE__)) + +/** @brief Macro to get the USBPHYC clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_USBPHYCCLKSOURCE_HSE HSE selected as USBPHYC clock + * @arg RCC_USBPHYCCLKSOURCE_HSE_DIV2 HSE divided by 2 selected as USBPHYC clock + * @arg RCC_USBPHYCCLKSOURCE_PLL3Q PLL3_Q Clock selected as USBPHYC clock + */ +#define __HAL_RCC_GET_USBPHYC_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USBPHYCSEL))) + +/** @brief Macro to configure the USB OTGFS clock. + * @param __USBOTGFS_CLKSOURCE__ specifies the USB OTGFS clock source. + * This parameter can be one of the following values: + * @arg RCC_USBOTGFSCLKSOURCE_HSI48 HSI48 selected as USB OTGFS clock + * @arg RCC_USBOTGFSCLKSOURCE_PLL3Q PLL3_Q Clock selected as USB OTGFS clock + * @arg RCC_USBOTGFSCLKSOURCE_HSE HSI48 selected as USB OTGFS clock + * @arg RCC_USBOTGFSCLKSOURCE_CLK48 USBPHYC CLK48 output selected as USB OTGFS clock + */ +#define __HAL_RCC_USBOTGFS_CONFIG(__USBOTGFS_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_OTGFSSEL, (uint32_t)(__USBOTGFS_CLKSOURCE__)) + +/** @brief Macro to get the USB OTGFS clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_USBOTGFSCLKSOURCE_HSI48 HSI48 selected as USB OTGFS clock + * @arg RCC_USBOTGFSCLKSOURCE_PLL3Q PLL3_Q Clock selected as USB OTGFS clock + * @arg RCC_USBOTGFSCLKSOURCE_HSE HSI48 selected as USB OTGFS clock + * @arg RCC_USBOTGFSCLKSOURCE_CLK48 USBPHYC CLK48 output selected as USB OTGFS clock + */ +#define __HAL_RCC_GET_USBOTGFS_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_OTGFSSEL))) + +/** + * @brief Enable the RCC LSE CSS Extended Interrupt Line. + * @retval None + */ +#define __HAL_RCC_LSECSS_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Disable the RCC LSE CSS Extended Interrupt Line. + * @retval None + */ +#define __HAL_RCC_LSECSS_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Enable the RCC LSE CSS Event Line. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Disable the RCC LSE CSS Event Line. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Enable the RCC LSE CSS Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Disable the RCC LSE CSS Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Enable the RCC LSE CSS Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Disable the RCC LSE CSS Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Enable the RCC LSE CSS Extended Interrupt Rising & Falling Trigger. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_FALLING_EDGE() \ + do { \ + __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE(); \ + __HAL_RCC_LSECSS_EXTI_ENABLE_FALLING_EDGE(); \ + } while(0) + +/** + * @brief Disable the RCC LSE CSS Extended Interrupt Rising & Falling Trigger. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_DISABLE_RISING_FALLING_EDGE() \ + do { \ + __HAL_RCC_LSECSS_EXTI_DISABLE_RISING_EDGE(); \ + __HAL_RCC_LSECSS_EXTI_DISABLE_FALLING_EDGE(); \ + } while(0) + +/** + * @brief Check whether the specified RCC LSE CSS EXTI interrupt flag is set or not. + * @retval EXTI RCC LSE CSS Line Status. + */ +#define __HAL_RCC_LSECSS_EXTI_GET_FLAG() (READ_BIT(EXTI->PR1, RCC_EXTI_LINE_LSECSS) == RCC_EXTI_LINE_LSECSS) + +/** + * @brief Clear the RCC LSE CSS EXTI flag. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_CLEAR_FLAG() WRITE_REG(EXTI->PR1, RCC_EXTI_LINE_LSECSS) + +/** + * @brief Generate a Software interrupt on the RCC LSE CSS EXTI line. + * @retval None. + */ +#define __HAL_RCC_LSECSS_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER1, RCC_EXTI_LINE_LSECSS) + +/** + * @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__ (SET or RESET). + */ +#define __HAL_RCC_CRS_GET_IT_SOURCE(__INTERRUPT__) ((READ_BIT(CRS->CR, (__INTERRUPT__)) != 0U) ? SET : RESET) + +/** @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 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 + * @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 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 pre-scaling. 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) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCCEx_Exported_Functions + * @{ + */ +/** @addtogroup RCCEx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef *PeriphClkInit); +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk); +void HAL_RCCEx_EnableClockProtection(uint32_t ProtectClk); +void HAL_RCCEx_DisableClockProtection(uint32_t ProtectClk); +/** + * @} + */ + +/** @addtogroup RCCEx_Exported_Functions_Group2 + * @{ + */ +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_EnableLSECSS_IT(void); +void HAL_RCCEx_LSECSS_IRQHandler(void); +void HAL_RCCEx_LSECSS_Callback(void); +/** + * @} + */ + +/** @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); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCCEx_Private_Macros + * @{ + */ + +/** @defgroup RCCEx_IS_RCC_Definitions Private macros to check input parameters + * @{ + */ + +#define IS_RCC_PERIPHCLOCK(__SELECTION__) \ + ((((__SELECTION__) & RCC_PERIPHCLK_FMC) == RCC_PERIPHCLK_FMC) || \ + (((__SELECTION__) & RCC_PERIPHCLK_XSPI1) == RCC_PERIPHCLK_XSPI1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_XSPI2) == RCC_PERIPHCLK_XSPI2) || \ + (((__SELECTION__) & RCC_PERIPHCLK_CKPER) == RCC_PERIPHCLK_CKPER) || \ + (((__SELECTION__) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC) || \ + (((__SELECTION__) & RCC_PERIPHCLK_ADF1) == RCC_PERIPHCLK_ADF1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) || \ + (((__SELECTION__) & RCC_PERIPHCLK_ETH1REF) == RCC_PERIPHCLK_ETH1REF) || \ + (((__SELECTION__) & RCC_PERIPHCLK_ETH1PHY) == RCC_PERIPHCLK_ETH1PHY) || \ + (((__SELECTION__) & RCC_PERIPHCLK_FDCAN) == RCC_PERIPHCLK_FDCAN) || \ + (((__SELECTION__) & RCC_PERIPHCLK_I2C1_I3C1) == RCC_PERIPHCLK_I2C1_I3C1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_I2C23) == RCC_PERIPHCLK_I2C23) || \ + (((__SELECTION__) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_LPTIM23) == RCC_PERIPHCLK_LPTIM23) || \ + (((__SELECTION__) & RCC_PERIPHCLK_LPTIM45) == RCC_PERIPHCLK_LPTIM45) || \ + (((__SELECTION__) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) || \ + (((__SELECTION__) & RCC_PERIPHCLK_PSSI) == RCC_PERIPHCLK_PSSI) || \ + (((__SELECTION__) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SDMMC12) == RCC_PERIPHCLK_SDMMC12) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SPI1) == RCC_PERIPHCLK_SPI1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SPI23) == RCC_PERIPHCLK_SPI23) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SPI45) == RCC_PERIPHCLK_SPI45) || \ + (((__SELECTION__) & RCC_PERIPHCLK_SPI6) == RCC_PERIPHCLK_SPI6) || \ + (((__SELECTION__) & RCC_PERIPHCLK_TIM) == RCC_PERIPHCLK_TIM) || \ + (((__SELECTION__) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) || \ + (((__SELECTION__) & RCC_PERIPHCLK_USART234578) == RCC_PERIPHCLK_USART234578) || \ + (((__SELECTION__) & RCC_PERIPHCLK_USBPHYC) == RCC_PERIPHCLK_USBPHYC) || \ + (((__SELECTION__) & RCC_PERIPHCLK_USBOTGFS) == RCC_PERIPHCLK_USBOTGFS)) + +#define IS_RCC_ADCCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_ADCCLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_ADCCLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_ADCCLKSOURCE_CLKP)) + +#define IS_RCC_ADF1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_ADF1CLKSOURCE_HCLK) || \ + ((__SOURCE__) == RCC_ADF1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_ADF1CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_ADF1CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_ADF1CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_ADF1CLKSOURCE_HSI)) + +#define IS_RCC_CECCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_CECCLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_CECCLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_CECCLKSOURCE_CSI)) + +#define IS_RCC_CKPERCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_CLKPSOURCE_HSI) || \ + ((__SOURCE__) == RCC_CLKPSOURCE_CSI) || \ + ((__SOURCE__) == RCC_CLKPSOURCE_HSE)) + +#define IS_RCC_ETH1REFCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_ETH1REFCLKSOURCE_PHY) || \ + ((__SOURCE__) == RCC_ETH1REFCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_ETH1REFCLKSOURCE_ETH)) + +#define IS_RCC_ETH1PHYCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_ETH1PHYCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_ETH1PHYCLKSOURCE_PLL3S)) + +#define IS_RCC_FDCANCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_FDCANCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_FDCANCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_FDCANCLKSOURCE_PLL2P)) + +#define IS_RCC_FMCCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_FMCCLKSOURCE_HCLK) || \ + ((__SOURCE__) == RCC_FMCCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_FMCCLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_FMCCLKSOURCE_HSI)) + +#define IS_RCC_I2C1_I3C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C1_I3C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C1_I3C1CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I2C1_I3C1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C1_I3C1CLKSOURCE_CSI)) + +#define IS_RCC_I2C23CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C23CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C23CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I2C23CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C23CLKSOURCE_CSI)) + +#define IS_RCC_I3C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I3C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_CSI)) + +#define IS_RCC_LPTIM1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_CLKP)) + +#define IS_RCC_LPTIM23CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM23CLKSOURCE_PCLK4) || \ + ((__SOURCE__) == RCC_LPTIM23CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM23CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM23CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM23CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM23CLKSOURCE_CLKP)) + +#define IS_RCC_LPTIM45CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM45CLKSOURCE_PCLK4) || \ + ((__SOURCE__) == RCC_LPTIM45CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM45CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM45CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM45CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM45CLKSOURCE_CLKP)) + +#define IS_RCC_LPUART1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_LPUART1CLKSOURCE_PCLK4) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_LSE)) + +#define IS_RCC_LTDCCLKSOURCE(__SOURCE__) \ + ((__SOURCE__) == RCC_LTDCCLKSOURCE_PLL3R) + +#define IS_RCC_XSPI1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_XSPI1CLKSOURCE_HCLK) || \ + ((__SOURCE__) == RCC_XSPI1CLKSOURCE_PLL2S) || \ + ((__SOURCE__) == RCC_XSPI1CLKSOURCE_PLL2T)) + +#define IS_RCC_XSPI2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_XSPI2CLKSOURCE_HCLK) || \ + ((__SOURCE__) == RCC_XSPI2CLKSOURCE_PLL2S) || \ + ((__SOURCE__) == RCC_XSPI2CLKSOURCE_PLL2T)) + +#define IS_RCC_PSSICLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_PSSICLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_PSSICLKSOURCE_CLKP)) + +#define IS_RCC_SAI1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SAI1CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_CLKP) || \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_PIN)) + +#define IS_RCC_SAI2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SAI2CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_CLKP) || \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_SPDIF)) + +#define IS_RCC_SDMMC12CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SDMMC12CLKSOURCE_PLL2S) || \ + ((__SOURCE__) == RCC_SDMMC12CLKSOURCE_PLL2T)) + +#define IS_RCC_SPDIFRXCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPDIFRXCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPDIFRXCLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_SPDIFRXCLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_SPDIFRXCLKSOURCE_HSI)) + +#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_SPI23CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI23CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI23CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI23CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_SPI23CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI23CLKSOURCE_CLKP)) + +#define IS_RCC_SPI45CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI45CLKSOURCE_PCLK2) || \ + ((__SOURCE__) == RCC_SPI45CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_SPI45CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_SPI45CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SPI45CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SPI45CLKSOURCE_HSE)) + +#define IS_RCC_SPI6CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI6CLKSOURCE_PCLK4) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_HSE)) + +#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_USART234578CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART234578CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART234578CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART234578CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART234578CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART234578CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_USART234578CLKSOURCE_CSI)) + +#define IS_RCC_USBPHYCCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USBPHYCCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_USBPHYCCLKSOURCE_HSE_DIV2) || \ + ((__SOURCE__) == RCC_USBPHYCCLKSOURCE_PLL3Q)) + +#define IS_RCC_USBOTGFSCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USBOTGFSCLKSOURCE_HSI48) || \ + ((__SOURCE__) == RCC_USBOTGFSCLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USBOTGFSCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_USBOTGFSCLKSOURCE_CLK48)) + +#define IS_RCC_TIMCLKPRESCALER(__VALUE__) \ + (((__VALUE__) == RCC_TIMPRES_DISABLE) || \ + ((__VALUE__) == RCC_TIMPRES_ENABLE)) + +#define IS_RCC_CLOCKPROTECTION(__CLOCK__) \ + ((((__CLOCK__) & RCC_CLOCKPROTECT_FMC) == RCC_CLOCKPROTECT_FMC) || \ + (((__CLOCK__) & RCC_CLOCKPROTECT_XSPI) == RCC_CLOCKPROTECT_XSPI) || \ + (((__CLOCK__) & ~(RCC_CLOCKPROTECT_FMC | RCC_CLOCKPROTECT_XSPI)) == 0U)) + + +#define IS_RCC_CRS_SYNC_SOURCE(__SOURCE__) (((__SOURCE__) == RCC_CRS_SYNC_SOURCE_LSE) || \ + ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_USB_OTG_FS) || \ + ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_USB_OTG_HS) || \ + ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_GPIO)) + +#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__) <= CRS_CFGR_RELOAD) + +#define IS_RCC_CRS_ERRORLIMIT(__VALUE__) ((__VALUE__) <= (CRS_CFGR_FELIM >> CRS_CFGR_FELIM_Pos)) + +#define IS_RCC_CRS_HSI48CALIBRATION(__VALUE__) ((__VALUE__) <= (CRS_CR_TRIM >> CRS_CR_TRIM_Pos)) + +#define IS_RCC_CRS_FREQERRORDIR(__DIR__) (((__DIR__) == RCC_CRS_FREQERRORDIR_UP) || \ + ((__DIR__) == RCC_CRS_FREQERRORDIR_DOWN)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_RCC_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus.h new file mode 100644 index 0000000..e3e7d95 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus.h @@ -0,0 +1,787 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_smbus.h + * @author MCD Application Team + * @brief Header file of SMBUS 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 STM32H7RSxx_HAL_SMBUS_H +#define STM32H7RSxx_HAL_SMBUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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_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 "stm32h7rsxx_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 stm32h7rsxx_hal_smbus.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H7RSxx_HAL_SMBUS_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus_ex.h new file mode 100644 index 0000000..fb431e1 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_smbus_ex.h @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_smbus_ex.h + * @author MCD Application Team + * @brief Header file of SMBUS HAL Extended 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 STM32H7RSxx_HAL_SMBUS_EX_H +#define STM32H7RSxx_HAL_SMBUS_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 stm32h7rsxx_hal_smbus_ex.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_SMBUS_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim.h new file mode 100644 index 0000000..8173a66 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim.h @@ -0,0 +1,2547 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_tim.h + * @author MCD Application Team + * @brief Header file of TIM 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 STM32H7RSxx_HAL_TIM_H +#define STM32H7RSxx_HAL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 */ +/** + * @} + */ + +/** @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_ITR13 TIM_TS_ITR13 /*!< External clock source mode 1 (ITR13) */ +#define TIM_CLOCKSOURCE_ITR14 TIM_TS_ITR14 /*!< External clock source mode 1 (ITR14) */ +/** + * @} + */ + +/** @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_ASYMMETRIC_PWM1 (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2) /*!< Asymmetric PWM mode 1 */ +#define TIM_OCMODE_ASYMMETRIC_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_ITR13 (TIM_SMCR_TS_0 | TIM_SMCR_TS_4) /*!< Internal Trigger 13 (ITR13) */ +#define TIM_TS_ITR14 (TIM_SMCR_TS_1 | TIM_SMCR_TS_4) /*!< Internal Trigger 14 (ITR14) */ +#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_AXISRAM1 SBS_BKLOCKR_ARAM1ECC_BL /*!< Enables and locks the AXIRAM1 ECC double error detection flag connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_ECC_AXISRAM3 SBS_BKLOCKR_ARAM3ECC_BL /*!< Enables and locks the AXIRAM3 ECC double error detection flag connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_ECC_ITCM SBS_BKLOCKR_ITCMECC_BL /*!< Enables and locks the ITCM ECC double error detection flag connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_ECC_DTCM SBS_BKLOCKR_DTCMECC_BL /*!< Enables and locks the DTCM ECC double error detection flag connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_ECC_BACKUP_RAM SBS_BKLOCKR_BKRAMECC_BL /*!< Enables and locks the Backup RAM ECC double error detection flag connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_ECC_FLASH SBS_BKLOCKR_FLASHECC_BL /*!< Enables and locks the FLASH ECC double error detection flag connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_PVD SBS_BKLOCKR_PVD_BL /*!< Enables and locks the PVD signal connection to TIM1/8/15/16/17/20 break inputs */ +#define TIM_BREAK_SYSTEM_LOCKUP SBS_BKLOCKR_CM7LCKUP_BL /*!< Enables and locks the Cortex-M7 lockup signal connection to TIM1/8/15/16/17/20 break inputs */ +/** + * @} + */ + +/** + * @} + */ +/* 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 | \ + TIM_CCER_CC5E | TIM_CCER_CC6E)) +#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)) + +#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) ? \ + ((READ_BIT((__HANDLE__)->Instance->CR1, TIM_CR1_DITHEN) == 0U) ? \ + (((__PERIOD__) > 0U) && ((__PERIOD__) <= 0x0000FFFFU)) : \ + (((__PERIOD__) > 0U) && ((__PERIOD__) <= 0x000FFFEFU))) : \ + ((__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_ITR13) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR14)) + +#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_ASYMMETRIC_PWM1) || \ + ((__MODE__) == TIM_OCMODE_ASYMMETRIC_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_INTERNAL_TRIGGEREVENT_SELECTION(__SELECTION__) (((__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_ITR9)|| \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_ITR13)|| \ + ((__SELECTION__) == TIM_TS_ITR14)|| \ + ((__SELECTION__) == TIM_TS_NONE)) + +#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_AXISRAM1) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_ECC_AXISRAM3) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_ECC_ITCM) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_ECC_DTCM) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_ECC_BACKUP_RAM) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_ECC_FLASH) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_PVD) || \ + ((__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 "stm32h7rsxx_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 /* STM32H7RSxx_HAL_TIM_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim_ex.h new file mode 100644 index 0000000..139f969 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_tim_ex.h @@ -0,0 +1,1124 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_tim_ex.h + * @author MCD Application Team + * @brief Header file of TIM HAL Extended 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 STM32H7RSxx_HAL_TIM_EX_H +#define STM32H7RSxx_HAL_TIM_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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 */ +#define TIM_TIM1_ETR_ADC1_AWD1 (TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM1_ETR is connected to ADC1 AWD1 */ +#define TIM_TIM1_ETR_ADC1_AWD2 (TIM_AF1_ETRSEL_2) /*!< TIM1_ETR is connected to ADC1 AWD2 */ +#define TIM_TIM1_ETR_ADC1_AWD3 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /*!< TIM1_ETR is connected to ADC1 AWD3 */ +#define TIM_TIM1_ETR_ADC2_AWD1 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /*!< TIM1_ETR is connected to ADC2 AWD1 */ +#define TIM_TIM1_ETR_ADC2_AWD2 (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM1_ETR is connected to ADC2 AWD2 */ +#define TIM_TIM1_ETR_ADC2_AWD3 (TIM_AF1_ETRSEL_3) /*!< TIM1_ETR is connected to ADC2 AWD3 */ + +#define TIM_TIM2_ETR_GPIO 0x00000000UL /*!< TIM2_ETR is not connected to I/O */ +#define TIM_TIM2_ETR_DCMIPP_HSYNC (TIM_AF1_ETRSEL_0) /*!< TIM2_ETR is connected to DCMIPP HSYNC */ +#define TIM_TIM2_ETR_LTDC_HSYNC (TIM_AF1_ETRSEL_1) /*!< TIM2_ETR is connected to LTDC HSYNC */ +#define TIM_TIM2_ETR_SAI1_FSA (TIM_AF1_ETRSEL_2) /*!< TIM2_ETR is connected to SAI1 FS_A */ +#define TIM_TIM2_ETR_SAI1_FSB (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /*!< TIM2_ETR is connected to SAI1 FS_B */ +#define TIM_TIM2_ETR_GFXTIM_TE (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /*!< TIM2_ETR is connected to GFXTIM TE */ +#define TIM_TIM2_ETR_DCMIPP_VSYNC (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM2_ETR is connected to DCMIPP VSYNC */ +#define TIM_TIM2_ETR_LTDC_VSYNC (TIM_AF1_ETRSEL_3) /*!< TIM2_ETR is connected to LTDC VSYNC */ +#define TIM_TIM2_ETR_TIM3_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1) /*!< TIM2_ETR is connected to TIM3 ETR */ +#define TIM_TIM2_ETR_TIM4_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM2_ETR is connected to TIM4 ETR */ +#define TIM_TIM2_ETR_TIM5_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2) /*!< TIM2_ETR is connected to TIM5 ETR */ +#define TIM_TIM2_ETR_ETH_PPS (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /*!< TIM2_ETR is connected to ETH PPS */ + +#define TIM_TIM3_ETR_GPIO 0x00000000UL /*!< TIM3_ETR is not connected to I/O */ +#define TIM_TIM3_ETR_DCMIPP_HSYNC (TIM_AF1_ETRSEL_0) /*!< TIM3_ETR is connected to DCMIPP HSYNC */ +#define TIM_TIM3_ETR_LTDC_HSYNC (TIM_AF1_ETRSEL_1) /*!< TIM3_ETR is connected to LTDC HSYNC */ +#define TIM_TIM3_ETR_GFXTIM_TE (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /*!< TIM3_ETR is connected to GFXTIM TE */ +#define TIM_TIM3_ETR_DCMIPP_VSYNC (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM3_ETR is connected to DCMIPP VSYNC */ +#define TIM_TIM3_ETR_LTDC_VSYNC (TIM_AF1_ETRSEL_3) /*!< TIM3_ETR is connected to LTDC VSYNC */ +#define TIM_TIM3_ETR_TIM2_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_0) /*!< TIM3_ETR is connected to TIM2 ETR */ +#define TIM_TIM3_ETR_TIM4_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM3_ETR is connected to TIM4 ETR */ +#define TIM_TIM3_ETR_TIM5_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2) /*!< TIM3_ETR is connected to TIM5 ETR */ +#define TIM_TIM3_ETR_ETH_PPS (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_0) /*!< TIM3_ETR is connected to ETH PPS */ + +#define TIM_TIM4_ETR_GPIO 0x00000000UL /*!< TIM4_ETR is not connected to I/O */ +#define TIM_TIM4_ETR_DCMIPP_HSYNC (TIM_AF1_ETRSEL_0) /*!< TIM4_ETR is connected to DCMIPP HSYNC */ +#define TIM_TIM4_ETR_LTDC_HSYNC (TIM_AF1_ETRSEL_1) /*!< TIM4_ETR is connected to LTDC HSYNC */ +#define TIM_TIM4_ETR_GFXTIM_TE (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /*!< TIM4_ETR is connected to GFXTIM TE */ +#define TIM_TIM4_ETR_DCMIPP_VSYNC (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM4_ETR is connected to DCMIPP VSYNC */ +#define TIM_TIM4_ETR_LTDC_VSYNC (TIM_AF1_ETRSEL_3) /*!< TIM4_ETR is connected to LTDC VSYNC */ +#define TIM_TIM4_ETR_TIM2_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_0) /*!< TIM4_ETR is connected to TIM2 ETR */ +#define TIM_TIM4_ETR_TIM3_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1) /*!< TIM4_ETR is connected to TIM3 ETR */ +#define TIM_TIM4_ETR_TIM5_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_2) /*!< TIM4_ETR is connected to TIM5 ETR */ + +#define TIM_TIM5_ETR_GPIO 0x00000000UL /*!< TIM5_ETR is not connected to I/O */ +#define TIM_TIM5_ETR_SAI2_FSA (TIM_AF1_ETRSEL_0) /*!< TIM5_ETR is connected to SAI2 FS_A */ +#define TIM_TIM5_ETR_SAI2_FSB (TIM_AF1_ETRSEL_1) /*!< TIM5_ETR is connected to SAI2 FS_B */ +#define TIM_TIM5_ETR_DCMIPP_HSYNC (TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM5_ETR is connected to DCMIPP HSYNC */ +#define TIM_TIM5_ETR_LTDC_HSYNC (TIM_AF1_ETRSEL_2) /*!< TIM5_ETR is connected to LTDC HSYNC */ +#define TIM_TIM5_ETR_GFXTIM_TE (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1) /*!< TIM5_ETR is connected to GFXTIM TE */ +#define TIM_TIM5_ETR_DCMIPP_VSYNC (TIM_AF1_ETRSEL_2 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM5_ETR is connected to DCMIPP VSYNC */ +#define TIM_TIM5_ETR_LTDC_VSYNC (TIM_AF1_ETRSEL_3) /*!< TIM4_ETR is connected to LTDC VSYNC */ +#define TIM_TIM5_ETR_TIM2_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_0) /*!< TIM5_ETR is connected to TIM2 ETR */ +#define TIM_TIM5_ETR_TIM3_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1) /*!< TIM5_ETR is connected to TIM3 ETR */ +#define TIM_TIM5_ETR_TIM4_ETR (TIM_AF1_ETRSEL_3 | TIM_AF1_ETRSEL_1 | TIM_AF1_ETRSEL_0) /*!< TIM5_ETR is connected to TIM4 ETR */ +/** + * @} + */ + +/** @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 */ +/** + * @} + */ + +/** @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_TIM2_TI1_GPIO 0x00000000UL /*!< TIM2_TI1 is connected to GPIO */ +#define TIM_TIM2_TI1_ETH_PPS TIM_TISEL_TI1SEL_0 /*!< TIM2 TI1 is connected to ETH1 PPS */ + +#define TIM_TIM3_TI1_GPIO 0x00000000UL /*!< TIM3_TI1 is connected to GPIO */ +#define TIM_TIM3_TI1_ETH_PPS TIM_TISEL_TI1SEL_0 /*!< TIM3 TI1 is connected to ETH1 PPS */ + +#define TIM_TIM9_TI1_GPIO 0x00000000UL /*!< TIM9_TI1 is connected to GPIO */ +#define TIM_TIM9_TI1_MCO1 (TIM_TISEL_TI1SEL_2) /*!< TIM9_TI1 is connected to MCO1 */ +#define TIM_TIM9_TI1_MCO2 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_0) /*!< TIM9_TI1 is connected to MCO2 */ + +#define TIM_TIM12_TI1_GPIO 0x00000000UL /*!< TIM12_TI1 is connected to GPIO */ +#define TIM_TIM12_TI1_SPDIF_FS (TIM_TISEL_TI1SEL_0) /*!< TIM12_TI1 is connected to SPDIFRX FS */ +#define TIM_TIM12_TI1_HSI_1024 (TIM_TISEL_TI1SEL_1) /*!< TIM12_TI1 is connected to HSI/1024 */ +#define TIM_TIM12_TI1_CSI_128 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM12_TI1 is connected to CSI/128 */ +#define TIM_TIM12_TI1_MCO1 (TIM_TISEL_TI1SEL_2) /*!< TIM12_TI1 is connected to MCO1 */ +#define TIM_TIM12_TI1_MCO2 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_0) /*!< TIM12_TI1 is connected to MCO2 */ +#define TIM_TIM12_TI2_GPIO 0x00000000UL /*!< TIM12_TI2 is connected to GPIO */ + +#define TIM_TIM15_TI1_GPIO 0x00000000UL /*!< TIM15_TI1 is connected to GPIO */ +#define TIM_TIM15_TI1_TIM2_CH1 (TIM_TISEL_TI1SEL_0) /*!< TIM15_TI1 is connected to TIM2 CH1 GPIO */ +#define TIM_TIM15_TI1_TIM3_CH1 (TIM_TISEL_TI1SEL_1) /*!< TIM15_TI1 is connected to TIM3 CH1 GPIO */ +#define TIM_TIM15_TI1_TIM4_CH1 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM15_TI1 is connected to TIM4 CH1 GPIO */ +#define TIM_TIM15_TI1_MCO1 (TIM_TISEL_TI1SEL_2) /*!< TIM15_TI1 is connected to MCO1 */ +#define TIM_TIM15_TI1_MCO2 (TIM_TISEL_TI1SEL_2 | TIM_TISEL_TI1SEL_0) /*!< TIM15_TI1 is connected to MCO2 */ +#define TIM_TIM15_TI2_GPIO 0x00000000UL /*!< TIM15_TI2 is connected to GPIO */ +#define TIM_TIM15_TI2_TIM2_CH2 (TIM_TISEL_TI2SEL_0) /*!< TIM15_TI2 is connected to TIM2 CH2 GPIO */ +#define TIM_TIM15_TI2_TIM3_CH2 (TIM_TISEL_TI2SEL_1) /*!< TIM15_TI2 is connected to TIM3 CH2 GPIO */ +#define TIM_TIM15_TI2_TIM4_CH2 (TIM_TISEL_TI2SEL_1 | TIM_TISEL_TI2SEL_0) /*!< TIM15_TI2 is connected to TIM4 CH2 GPIO */ + +#define TIM_TIM16_TI1_GPIO 0x00000000UL /*!< TIM16_TI1 is connected to GPIO */ +#define TIM_TIM16_TI1_RTC_WKUP (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM16_TI1 is connected to RTC Wakeup */ + +#define TIM_TIM17_TI1_GPIO 0x00000000UL /*!< TIM17_TI1 is connected to GPIO */ +#define TIM_TIM17_TI1_SPDIF_FS (TIM_TISEL_TI1SEL_0) /*!< TIM17_TI1 is connected to SPDIFRX FS */ +/** + * @} + */ + +/** @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(INSTANCE, TIM_REMAP) \ + ((((INSTANCE) == TIM1) && (((TIM_REMAP) == TIM_TIM1_ETR_GPIO) || \ + ((TIM_REMAP) == TIM_TIM1_ETR_ADC1_AWD1) || \ + ((TIM_REMAP) == TIM_TIM1_ETR_ADC1_AWD2) || \ + ((TIM_REMAP) == TIM_TIM1_ETR_ADC1_AWD3) || \ + ((TIM_REMAP) == TIM_TIM1_ETR_ADC2_AWD1) || \ + ((TIM_REMAP) == TIM_TIM1_ETR_ADC2_AWD2) || \ + ((TIM_REMAP) == TIM_TIM1_ETR_ADC2_AWD3))) || \ + (((INSTANCE) == TIM2) && (((TIM_REMAP) == TIM_TIM2_ETR_GPIO) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_DCMIPP_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_LTDC_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_SAI1_FSA) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_SAI1_FSB) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_GFXTIM_TE) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_DCMIPP_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_LTDC_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_TIM3_ETR) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_TIM4_ETR) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_TIM5_ETR) || \ + ((TIM_REMAP) == TIM_TIM2_ETR_ETH_PPS))) || \ + (((INSTANCE) == TIM3) && (((TIM_REMAP) == TIM_TIM3_ETR_GPIO) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_DCMIPP_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_LTDC_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_GFXTIM_TE) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_DCMIPP_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_LTDC_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_TIM2_ETR) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_TIM4_ETR) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_TIM5_ETR) || \ + ((TIM_REMAP) == TIM_TIM3_ETR_ETH_PPS))) || \ + (((INSTANCE) == TIM4) && (((TIM_REMAP) == TIM_TIM4_ETR_GPIO) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_DCMIPP_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_LTDC_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_GFXTIM_TE) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_DCMIPP_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_LTDC_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_TIM2_ETR) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_TIM3_ETR) || \ + ((TIM_REMAP) == TIM_TIM4_ETR_TIM5_ETR))) || \ + (((INSTANCE) == TIM5) && (((TIM_REMAP) == TIM_TIM5_ETR_GPIO) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_SAI2_FSA) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_SAI2_FSB) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_DCMIPP_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_LTDC_HSYNC) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_GFXTIM_TE) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_DCMIPP_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_LTDC_VSYNC) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_TIM2_ETR) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_TIM3_ETR) || \ + ((TIM_REMAP) == TIM_TIM5_ETR_TIM4_ETR)))) + +#define IS_TIM_BREAKINPUT(__BREAKINPUT__) (((__BREAKINPUT__) == TIM_BREAKINPUT_BRK) || \ + ((__BREAKINPUT__) == TIM_BREAKINPUT_BRK2)) + +#define IS_TIM_BREAKINPUTSOURCE(__SOURCE__) ((__SOURCE__) == TIM_BREAKINPUTSOURCE_BKIN) + +#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)) + +#define IS_TIM_CLOCKSOURCE_INSTANCE(INSTANCE, __CLOCK__) \ + ((((INSTANCE) == TIM1) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__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_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__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_ITR13) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR14))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__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_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__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_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__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_ITR13))) \ + || \ + (((INSTANCE) == TIM9) && \ + (((__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_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_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_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__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_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__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_ITR13) || \ + ((__SELECTION__) == TIM_TS_ITR14))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__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_ITR0) || \ + ((__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) || \ + ((__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_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__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_ITR13) || \ + ((__SELECTION__) == TIM_TS_ITR14))) \ + || \ + (((INSTANCE) == TIM9) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__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_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__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_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__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_ITR13) || \ + ((__SELECTION__) == TIM_TS_ITR14) || \ + ((__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_ITR13) || \ + ((__SELECTION__) == TIM_TS_ITR14) || \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM9) && \ + (((__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)))) + +#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 /* STM32H7RSxx_HAL_TIM_EX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart.h new file mode 100644 index 0000000..907b32c --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart.h @@ -0,0 +1,1777 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_uart.h + * @author MCD Application Team + * @brief Header file of UART 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 STM32H7RSxx_HAL_UART_H +#define STM32H7RSxx_HAL_UART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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: + @note For 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. + @note For 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_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + UART_CLOCKSOURCE_PCLK4 = 0x02U, /*!< PCLK4 clock source (only used by LPUART1) */ + UART_CLOCKSOURCE_PLL2Q = 0x04U, /*!< PLL2Q clock source */ + UART_CLOCKSOURCE_PLL3Q = 0x08U, /*!< PLL3Q clock source */ + UART_CLOCKSOURCE_HSI = 0x10U, /*!< HSI clock source */ + UART_CLOCKSOURCE_CSI = 0x20U, /*!< CSI clock source */ + UART_CLOCKSOURCE_LSE = 0x40U, /*!< LSE clock source */ + UART_CLOCKSOURCE_UNDEFINED = 0x80U /*!< 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 clock 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 : 256U) + +/** @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 H7RS (i.e. 125 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__) < 15625001U) + +/** @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 "stm32h7rsxx_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 /* STM32H7RSxx_HAL_UART_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart_ex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart_ex.h new file mode 100644 index 0000000..a591a95 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_uart_ex.h @@ -0,0 +1,409 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_uart_ex.h + * @author MCD Application Team + * @brief Header file of UART HAL Extended 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 STM32H7RSxx_HAL_UART_EX_H +#define STM32H7RSxx_HAL_UART_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +/** @addtogroup STM32H7RSxx_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__. + */ +#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART1CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PLL3Q; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if(((__HANDLE__)->Instance == USART2) || \ + ((__HANDLE__)->Instance == USART3) || \ + ((__HANDLE__)->Instance == UART4) || \ + ((__HANDLE__)->Instance == UART5) || \ + ((__HANDLE__)->Instance == UART7) || \ + ((__HANDLE__)->Instance == UART8)) \ + { \ + switch(__HAL_RCC_GET_USART234578_SOURCE()) \ + { \ + case RCC_USART234578CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART234578CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART234578CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PLL3Q; \ + break; \ + case RCC_USART234578CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART234578CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART234578CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == LPUART1) \ + { \ + switch(__HAL_RCC_GET_LPUART1_SOURCE()) \ + { \ + case RCC_LPUART1CLKSOURCE_PCLK4: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PCLK4; \ + break; \ + case RCC_LPUART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_LPUART1CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_PLL3Q; \ + break; \ + case RCC_LPUART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_LPUART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_LPUART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_LSE; \ + break; \ + default: \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = UART_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) + + +/** @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 /* STM32H7RSxx_HAL_UART_EX_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_xspi.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_xspi.h new file mode 100644 index 0000000..6e03c5a --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_hal_xspi.h @@ -0,0 +1,1275 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_xspi.h + * @author MCD Application Team + * @brief Header file of XSPI 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 STM32H7RSxx_HAL_XSPI_H +#define STM32H7RSxx_HAL_XSPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal_def.h" + +#if defined(XSPI) || defined(XSPI1) || defined(XSPI2) + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup XSPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup XSPI_Exported_Types XSPI Exported Types + * @{ + */ + +/** + * @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 XSPI, 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; /*!< This parameter is deprecated and is not used on STM32H7RSxx devices */ + 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 MaxTran; /*!< It enables the communication regulation feature. The chip select is + released every MaxTran+1 bytes when the other XSPI request the access + to the bus. + This parameter can be a value between 0 and 255U */ + 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 */ + uint32_t MemorySelect; /*!< It indicates if the output of nCS. + This parameter can be a value of @ref XSPI_MemorySelect */ +} 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 */ +} 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 */ + 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 */ +} 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; + +/** + * @brief HAL XSPI IO Manager Configuration structure definition + */ +typedef struct +{ + uint32_t nCSOverride; /*!< It indicates Chip select selector override setting for XSPI. + This parameter can be a value @ref XSPIM_MemorySelect_Override */ + uint32_t IOPort; /*!< It indicates which port of the XSPI IO Manager is used for the instance. + This parameter can be a value of @ref XSPI_IO_Manger_IOPort */ + uint32_t Req2AckTime; /*!< It indicates the minimum switching duration (in number of clock cycles) + expected if some signals are multiplexed in the XSPI IO Manager with the + other XSPI. + This parameter can be a value between 1 and 256 */ +} XSPIM_CfgTypeDef; + +#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) */ +/** + * @brief HAL XSPI High-speed interface calibration structure definition + */ +typedef struct +{ + uint32_t DelayValueType; /*!< It indicates which calibration is concerned by the configuration. + This parameter can be a value of @ref XSPI_DelayType */ + uint32_t FineCalibrationUnit; /*!< It indicates the fine calibration value of the delay. + This parameter can be a value between 0 and 0x7FU */ + uint32_t CoarseCalibrationUnit; /*!< It indicates the coarse calibration value of the delay. + This parameter can be a value between 0 and 0x1FU */ + uint32_t MaxCalibration; /*!< It indicates that the calibration is outside the range of DLL master. + It applies only when the DelayValueType is HAL_XSPI_CAL_FULL_CYCLE_DELAY. + This parameter can be a value of @ref XSPI_MaxCal */ +} XSPI_HSCalTypeDef; + +/** + * @} + */ + +/* 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 Bytes = 2^( 0+1)) */ +#define HAL_XSPI_SIZE_32B (0x00000001U) /*!< 32 bits ( 4 Bytes = 2^( 1+1)) */ +#define HAL_XSPI_SIZE_64B (0x00000002U) /*!< 64 bits ( 8 Bytes = 2^( 2+1)) */ +#define HAL_XSPI_SIZE_128B (0x00000003U) /*!< 128 bits ( 16 Bytes = 2^( 3+1)) */ +#define HAL_XSPI_SIZE_256B (0x00000004U) /*!< 256 bits ( 32 Bytes = 2^( 4+1)) */ +#define HAL_XSPI_SIZE_512B (0x00000005U) /*!< 512 bits ( 64 Bytes = 2^( 5+1)) */ +#define HAL_XSPI_SIZE_1KB (0x00000006U) /*!< 1 Kbits (128 Bytes = 2^( 6+1)) */ +#define HAL_XSPI_SIZE_2KB (0x00000007U) /*!< 2 Kbits (256 Bytes = 2^( 7+1)) */ +#define HAL_XSPI_SIZE_4KB (0x00000008U) /*!< 4 Kbits (512 Bytes = 2^( 8+1)) */ +#define HAL_XSPI_SIZE_8KB (0x00000009U) /*!< 8 Kbits ( 1 KBytes = 2^( 9+1)) */ +#define HAL_XSPI_SIZE_16KB (0x0000000AU) /*!< 16 Kbits ( 2 KBytes = 2^(10+1)) */ +#define HAL_XSPI_SIZE_32KB (0x0000000BU) /*!< 32 Kbits ( 4 KBytes = 2^(11+1)) */ +#define HAL_XSPI_SIZE_64KB (0x0000000CU) /*!< 64 Kbits ( 8 KBytes = 2^(12+1)) */ +#define HAL_XSPI_SIZE_128KB (0x0000000DU) /*!< 128 Kbits ( 16 KBytes = 2^(13+1)) */ +#define HAL_XSPI_SIZE_256KB (0x0000000EU) /*!< 256 Kbits ( 32 KBytes = 2^(14+1)) */ +#define HAL_XSPI_SIZE_512KB (0x0000000FU) /*!< 512 Kbits ( 64 KBytes = 2^(15+1)) */ +#define HAL_XSPI_SIZE_1MB (0x00000010U) /*!< 1 Mbits (128 KBytes = 2^(16+1)) */ +#define HAL_XSPI_SIZE_2MB (0x00000011U) /*!< 2 Mbits (256 KBytes = 2^(17+1)) */ +#define HAL_XSPI_SIZE_4MB (0x00000012U) /*!< 4 Mbits (512 KBytes = 2^(18+1)) */ +#define HAL_XSPI_SIZE_8MB (0x00000013U) /*!< 8 Mbits ( 1 MBytes = 2^(19+1)) */ +#define HAL_XSPI_SIZE_16MB (0x00000014U) /*!< 16 Mbits ( 2 MBytes = 2^(20+1)) */ +#define HAL_XSPI_SIZE_32MB (0x00000015U) /*!< 32 Mbits ( 4 MBytes = 2^(21+1)) */ +#define HAL_XSPI_SIZE_64MB (0x00000016U) /*!< 64 Mbits ( 8 MBytes = 2^(22+1)) */ +#define HAL_XSPI_SIZE_128MB (0x00000017U) /*!< 128 Mbits ( 16 MBytes = 2^(23+1)) */ +#define HAL_XSPI_SIZE_256MB (0x00000018U) /*!< 256 Mbits ( 32 MBytes = 2^(24+1)) */ +#define HAL_XSPI_SIZE_512MB (0x00000019U) /*!< 512 Mbits ( 64 MBytes = 2^(25+1)) */ +#define HAL_XSPI_SIZE_1GB (0x0000001AU) /*!< 1 Gbits (128 MBytes = 2^(26+1)) */ +#define HAL_XSPI_SIZE_2GB (0x0000001BU) /*!< 2 Gbits (256 MBytes = 2^(27+1)) */ +#define HAL_XSPI_SIZE_4GB (0x0000001CU) /*!< 4 Gbits (512 MBytes = 2^(28+1)) */ +#define HAL_XSPI_SIZE_8GB (0x0000001DU) /*!< 8 Gbits ( 1 GBytes = 2^(29+1)) */ +#define HAL_XSPI_SIZE_16GB (0x0000001EU) /*!< 16 Gbits ( 2 GBytes = 2^(30+1)) */ +#define HAL_XSPI_SIZE_32GB (0x0000001FU) /*!< 32 Gbits ( 4 GBytes = 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 + * @note These constants are deprecated and are not expected to be used anymore. + * @{ + */ +#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 Bytes = 2^(1)) */ +#define HAL_XSPI_BONDARYOF_32B (0x00000002U) /*!< 32 bits ( 4 Bytes = 2^(2)) */ +#define HAL_XSPI_BONDARYOF_64B (0x00000003U) /*!< 64 bits ( 8 Bytes = 2^(3)) */ +#define HAL_XSPI_BONDARYOF_128B (0x00000004U) /*!< 128 bits ( 16 Bytes = 2^(4)) */ +#define HAL_XSPI_BONDARYOF_256B (0x00000005U) /*!< 256 bits ( 32 Bytes = 2^(5)) */ +#define HAL_XSPI_BONDARYOF_512B (0x00000006U) /*!< 512 bits ( 64 Bytes = 2^(6)) */ +#define HAL_XSPI_BONDARYOF_1KB (0x00000007U) /*!< 1 Kbits (128 Bytes = 2^(7)) */ +#define HAL_XSPI_BONDARYOF_2KB (0x00000008U) /*!< 2 Kbits (256 Bytes = 2^(8)) */ +#define HAL_XSPI_BONDARYOF_4KB (0x00000009U) /*!< 4 Kbits (512 Bytes = 2^(9)) */ +#define HAL_XSPI_BONDARYOF_8KB (0x0000000AU) /*!< 8 Kbits ( 1 KBytes = 2^(10)) */ +#define HAL_XSPI_BONDARYOF_16KB (0x0000000BU) /*!< 16 Kbits ( 2 KBytes = 2^(11)) */ +#define HAL_XSPI_BONDARYOF_32KB (0x0000000CU) /*!< 32 Kbits ( 4 KBytes = 2^(12)) */ +#define HAL_XSPI_BONDARYOF_64KB (0x0000000DU) /*!< 64 Kbits ( 8 KBytes = 2^(13)) */ +#define HAL_XSPI_BONDARYOF_128KB (0x0000000EU) /*!< 128 Kbits ( 16 KBytes = 2^(14)) */ +#define HAL_XSPI_BONDARYOF_256KB (0x0000000FU) /*!< 256 Kbits ( 32 KBytes = 2^(15)) */ +#define HAL_XSPI_BONDARYOF_512KB (0x00000010U) /*!< 512 Kbits ( 64 KBytes = 2^(16)) */ +#define HAL_XSPI_BONDARYOF_1MB (0x00000011U) /*!< 1 Mbits (128 KBytes = 2^(17)) */ +#define HAL_XSPI_BONDARYOF_2MB (0x00000012U) /*!< 2 Mbits (256 KBytes = 2^(18)) */ +#define HAL_XSPI_BONDARYOF_4MB (0x00000013U) /*!< 4 Mbits (512 KBytes = 2^(19)) */ +#define HAL_XSPI_BONDARYOF_8MB (0x00000014U) /*!< 8 Mbits ( 1 MBytes = 2^(20)) */ +#define HAL_XSPI_BONDARYOF_16MB (0x00000015U) /*!< 16 Mbits ( 2 MBytes = 2^(21)) */ +#define HAL_XSPI_BONDARYOF_32MB (0x00000016U) /*!< 32 Mbits ( 4 MBytes = 2^(22)) */ +#define HAL_XSPI_BONDARYOF_64MB (0x00000017U) /*!< 64 Mbits ( 8 MBytes = 2^(23)) */ +#define HAL_XSPI_BONDARYOF_128MB (0x00000018U) /*!< 128 Mbits ( 16 MBytes = 2^(24)) */ +#define HAL_XSPI_BONDARYOF_256MB (0x00000019U) /*!< 256 Mbits ( 32 MBytes = 2^(25)) */ +#define HAL_XSPI_BONDARYOF_512MB (0x0000001AU) /*!< 512 Mbits ( 64 MBytes = 2^(26)) */ +#define HAL_XSPI_BONDARYOF_1GB (0x0000001BU) /*!< 1 Gbits (128 MBytes = 2^(27)) */ +#define HAL_XSPI_BONDARYOF_2GB (0x0000001CU) /*!< 2 Gbits (256 MBytes = 2^(28)) */ +#define HAL_XSPI_BONDARYOF_4GB (0x0000001DU) /*!< 4 Gbits (512 MBytes = 2^(29)) */ +#define HAL_XSPI_BONDARYOF_8GB (0x0000001EU) /*!< 8 Gbits ( 1 GBytes = 2^(30)) */ +#define HAL_XSPI_BONDARYOF_16GB (0x0000001FU) /*!< 16 Gbits ( 2 GBytes = 2^(31)) */ +/** + * @} + */ + +/** @defgroup XSPI_MemorySelect XSPI Memory Select + * @{ + */ +#define HAL_XSPI_CSSEL_NCS1 (0x00000000U) /*!< The output of nCS is nCS1 */ +#define HAL_XSPI_CSSEL_NCS2 ((uint32_t)XSPI_CR_CSSEL) /*!< The output of nCS is nCS2 */ +/** + * @} + */ + +/** @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)XSPI_CR_MSEL_0) /*!< Data exchanged over IO[7:4] */ +#define HAL_XSPI_SELECT_IO_11_8 ((uint32_t)XSPI_CR_MSEL_1) /*!< Data exchanged over IO[11:8] */ +#define HAL_XSPI_SELECT_IO_15_12 ((uint32_t)XSPI_CR_MSEL ) /*!< Data exchanged over IO[15:12] */ +#define HAL_XSPI_SELECT_IO_7_0 (0x00000000U) /*!< Data exchanged over IO[7:0] */ +#define HAL_XSPI_SELECT_IO_15_8 ((uint32_t)XSPI_CR_MSEL_1) /*!< Data exchanged over IO[15:8] */ +/** + * @} + */ + +/** @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 */ +#define HAL_XSPI_DATA_16_LINES ((uint32_t)(XSPI_CCR_DMODE_0 | XSPI_CCR_DMODE_2)) /*!< Data on sixteen lines valid for HSPI only */ +/** + * @} + */ + +/** @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_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 */ +/** + * @} + */ + +/** @defgroup XSPI_IO_Manger_IOPort XSPI IO Port + * @{ + */ +#define HAL_XSPIM_IOPORT_1 (0x00000000U) /*!< Port 1 */ +#define HAL_XSPIM_IOPORT_2 (0x00000001U) /*!< Port 2 */ +/** + * @} + */ + + +/** @defgroup XSPI_DelayType XSPI Calibration Delay Type + * @{ + */ +#define HAL_XSPI_CAL_FULL_CYCLE_DELAY (0x00000000U) /*!< Delay value equivalent to full memory-clock cycle */ +#define HAL_XSPI_CAL_FEEDBACK_CLK_DELAY (0x00000001U) /*!< Delay value for the feedback clock when reading without DQS */ +#define HAL_XSPI_CAL_DATA_OUTPUT_DELAY (0x00000002U) /*!< Delay value for output data in DDR mode for write operations */ +#define HAL_XSPI_CAL_DQS_INPUT_DELAY (0x00000003U) /*!< Delay value for DQS input when sampling data for read operations */ +/** + * @} + */ + +/** @defgroup XSPI_MaxCal XSPI Calibration Maximal Value + * @{ + */ +#define HAL_XSPI_MAXCAL_NOT_REACHED (0x00000000U) /*!< Memory-clock perido inside the range of DLL master */ +#define HAL_XSPI_MAXCAL_REACHED ((uint32_t)XSPI_CALFCR_CALMAX) /*!< Memory-clock period outside the range of DLL master (max delay values used) */ +/** + * @} + */ + +/** @defgroup XSPIM_MemorySelect_Override XSPIM Memory Select Override + * @{ + */ +#define HAL_XSPI_CSSEL_OVR_DISABLED (0x00000000U) +#define HAL_XSPI_CSSEL_OVR_NCS1 (0x00000010U) /*!< The chip select signal from XSPI is sent to NCS1 */ +#define HAL_XSPI_CSSEL_OVR_NCS2 (0x00000070U) /*!< The chip select signal from XSPI is sent to NCS2 */ +/** + * @} + */ + +/** + * @} + */ + +/* 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 XSPI Exported Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup XSPI_Exported_Functions_Group1 Initialization/de-initialization functions + * @{ + */ +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 Input and Output operation functions + * @{ + */ +/* XSPI IRQ handler function */ +void HAL_XSPI_IRQHandler(XSPI_HandleTypeDef *hxspi); + +/* XSPI command configuration functions */ +HAL_StatusTypeDef HAL_XSPI_Command(XSPI_HandleTypeDef *hxspi, const XSPI_RegularCmdTypeDef *pCmd, + uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_Command_IT(XSPI_HandleTypeDef *hxspi, const XSPI_RegularCmdTypeDef *pCmd); +HAL_StatusTypeDef HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef *hxspi, const XSPI_HyperbusCfgTypeDef *pCfg, + uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef *hxspi, const XSPI_HyperbusCmdTypeDef *pCmd, + uint32_t Timeout); + +/* XSPI indirect mode functions */ +HAL_StatusTypeDef HAL_XSPI_Transmit(XSPI_HandleTypeDef *hxspi, const uint8_t *pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_Receive(XSPI_HandleTypeDef *hxspi, uint8_t *pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef *hxspi, const uint8_t *pData); +HAL_StatusTypeDef HAL_XSPI_Receive_IT(XSPI_HandleTypeDef *hxspi, uint8_t *pData); +HAL_StatusTypeDef HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef *hxspi, const uint8_t *pData); +HAL_StatusTypeDef HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *pData); + +/* XSPI status flag polling mode functions */ +HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, const XSPI_AutoPollingTypeDef *pCfg, + uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef *hxspi, const XSPI_AutoPollingTypeDef *pCfg); + +/* XSPI memory-mapped mode functions */ +HAL_StatusTypeDef HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef *hxspi, const XSPI_MemoryMappedTypeDef *pCfg); +uint32_t HAL_XSPI_IsMemoryMapped(XSPI_HandleTypeDef *hxspi); + +/* 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 Peripheral Control and State functions + * @{ + */ +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 IO Manager configuration function ************************************/ +/** @addtogroup XSPI_Exported_Functions_Group4 IO Manager configuration function + * @{ + */ +HAL_StatusTypeDef HAL_XSPIM_Config(XSPI_HandleTypeDef *hxspi, const XSPIM_CfgTypeDef *pCfg, uint32_t Timeout); + +/** + * @} + */ + +/* XSPI high-speed interface and calibration functions ***********************/ +/** @addtogroup XSPI_Exported_Functions_Group6 High-speed interface and calibration functions + * @{ + */ +HAL_StatusTypeDef HAL_XSPI_GetDelayValue(XSPI_HandleTypeDef *hxspi, XSPI_HSCalTypeDef *pCfg); +HAL_StatusTypeDef HAL_XSPI_SetDelayValue(XSPI_HandleTypeDef *hxspi, const XSPI_HSCalTypeDef *pCfg); + +/** + * @} + */ + +/** + * @} + */ +/* 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_MAXTRAN(NB_BYTES) ((NB_BYTES) <= 255U) + +#define IS_XSPI_CSSEL(CSSEL) (((CSSEL) == HAL_XSPI_CSSEL_NCS1) || \ + ((CSSEL) == HAL_XSPI_CSSEL_NCS2)) + +#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_11_8) || \ + ((MEMSEL) == HAL_XSPI_SELECT_IO_15_12) || \ + ((MEMSEL) == HAL_XSPI_SELECT_IO_7_0) || \ + ((MEMSEL) == HAL_XSPI_SELECT_IO_15_8)) + +#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(TYPE,MODE) (((TYPE) == (HAL_XSPI_MEMTYPE_HYPERBUS)) ? \ + (((MODE) == HAL_XSPI_DATA_NONE) || \ + ((MODE) == HAL_XSPI_DATA_8_LINES) || \ + ((MODE) == HAL_XSPI_DATA_16_LINES)): \ + (((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) || \ + ((MODE) == HAL_XSPI_DATA_16_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_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) + +#define IS_XSPI_PROG_DATA(SET_DATA, REQ_DATA) ((SET_DATA) == (REQ_DATA)) + +#define IS_XSPI_PROG_ADDR(SET_ADDR, REQ_ADDR) ((SET_ADDR) == (REQ_ADDR)) + +#define IS_XSPIM_IO_PORT(PORT) (((PORT) == HAL_XSPIM_IOPORT_1) || \ + ((PORT) == HAL_XSPIM_IOPORT_2)) + +#define IS_XSPIM_NCS_OVR(PORT) (((PORT) == HAL_XSPI_CSSEL_OVR_DISABLED) || \ + ((PORT) == HAL_XSPI_CSSEL_OVR_NCS1) || \ + ((PORT) == HAL_XSPI_CSSEL_OVR_NCS2)) + +#define IS_XSPIM_REQ2ACKTIME(TIME) (((TIME) >= 1U) && ((TIME) <= 256U)) + +#define IS_XSPI_DELAY_TYPE(TYPE) (((TYPE) == HAL_XSPI_CAL_FULL_CYCLE_DELAY) || \ + ((TYPE) == HAL_XSPI_CAL_FEEDBACK_CLK_DELAY) || \ + ((TYPE) == HAL_XSPI_CAL_DATA_OUTPUT_DELAY) || \ + ((TYPE) == HAL_XSPI_CAL_DQS_INPUT_DELAY)) + +#define IS_XSPI_FINECAL_VALUE(VALUE) ((VALUE) <= 0x7FU) + +#define IS_XSPI_COARSECAL_VALUE(VALUE) ((VALUE) <= 0x1FU) + +/** + @endcond + */ + +/* End of private macros -----------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* XSPI || XSPI1 || XSPI2 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_HAL_XSPI_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_bus.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_bus.h new file mode 100644 index 0000000..728d609 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_bus.h @@ -0,0 +1,2734 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_bus.h + * @author MCD Application Team + * @brief Header file of BUS LL 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. + * + ****************************************************************************** + @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 + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7RSxx_LL_BUS_H +#define STM32H7RSxx_LL_BUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ +#if defined(RCC) + +/** @defgroup BUS_LL BUS + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup BUS_LL_Exported_Constants BUS Exported Constants + * @{ + */ + +/** @defgroup BUS_LL_EC_AHB1_GRP1_PERIPH AHB1 GRP1 PERIPH + * @{ + */ +#define LL_AHB1_GRP1_PERIPH_GPDMA1 RCC_AHB1ENR_GPDMA1EN +#define LL_AHB1_GRP1_PERIPH_ADC12 RCC_AHB1ENR_ADC12EN +#define LL_AHB1_GRP1_PERIPH_ETH1MAC RCC_AHB1ENR_ETH1MACEN +#define LL_AHB1_GRP1_PERIPH_ETH1TX RCC_AHB1ENR_ETH1TXEN +#define LL_AHB1_GRP1_PERIPH_ETH1RX RCC_AHB1ENR_ETH1RXEN +#define LL_AHB1_GRP1_PERIPH_USBOTGHS RCC_AHB1ENR_OTGHSEN +#define LL_AHB1_GRP1_PERIPH_USBOTGFS RCC_AHB1ENR_OTGFSEN +#define LL_AHB1_GRP1_PERIPH_USBPHYC RCC_AHB1ENR_USBPHYCEN +#define LL_AHB1_GRP1_PERIPH_ADF1 RCC_AHB1ENR_ADF1EN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_AHB2_GRP1_PERIPH AHB2 GRP1 PERIPH + * @{ + */ +#define LL_AHB2_GRP1_PERIPH_PSSI RCC_AHB2ENR_PSSIEN +#define LL_AHB2_GRP1_PERIPH_SDMMC2 RCC_AHB2ENR_SDMMC2EN +#define LL_AHB2_GRP1_PERIPH_CORDIC RCC_AHB2ENR_CORDICEN +#define LL_AHB2_GRP1_PERIPH_AHBSRAM1 RCC_AHB2ENR_SRAM1EN +#define LL_AHB2_GRP1_PERIPH_AHBSRAM2 RCC_AHB2ENR_SRAM2EN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_AHB3_GRP1_PERIPH AHB3 GRP1 PERIPH + * @{ + */ +#define LL_AHB3_GRP1_PERIPH_RNG RCC_AHB3ENR_RNGEN +#define LL_AHB3_GRP1_PERIPH_HASH RCC_AHB3ENR_HASHEN +#if defined(CRYP) +#define LL_AHB3_GRP1_PERIPH_CRYP RCC_AHB3ENR_CRYPEN +#endif /* CRYP */ +#if defined(SAES) +#define LL_AHB3_GRP1_PERIPH_SAES RCC_AHB3ENR_SAESEN +#endif /* SAES */ +#define LL_AHB3_GRP1_PERIPH_PKA RCC_AHB3ENR_PKAEN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_AHB4_GRP1_PERIPH AHB4 GRP1 PERIPH + * @{ + */ +#define LL_AHB4_GRP1_PERIPH_GPIOA RCC_AHB4ENR_GPIOAEN +#define LL_AHB4_GRP1_PERIPH_GPIOB RCC_AHB4ENR_GPIOBEN +#define LL_AHB4_GRP1_PERIPH_GPIOC RCC_AHB4ENR_GPIOCEN +#define LL_AHB4_GRP1_PERIPH_GPIOD RCC_AHB4ENR_GPIODEN +#define LL_AHB4_GRP1_PERIPH_GPIOE RCC_AHB4ENR_GPIOEEN +#define LL_AHB4_GRP1_PERIPH_GPIOF RCC_AHB4ENR_GPIOFEN +#define LL_AHB4_GRP1_PERIPH_GPIOG RCC_AHB4ENR_GPIOGEN +#define LL_AHB4_GRP1_PERIPH_GPIOH RCC_AHB4ENR_GPIOHEN +#define LL_AHB4_GRP1_PERIPH_GPIOM RCC_AHB4ENR_GPIOMEN +#define LL_AHB4_GRP1_PERIPH_GPION RCC_AHB4ENR_GPIONEN +#define LL_AHB4_GRP1_PERIPH_GPIOO RCC_AHB4ENR_GPIOOEN +#define LL_AHB4_GRP1_PERIPH_GPIOP RCC_AHB4ENR_GPIOPEN +#define LL_AHB4_GRP1_PERIPH_CRC RCC_AHB4ENR_CRCEN +#define LL_AHB4_GRP1_PERIPH_BKPRAM RCC_AHB4ENR_BKPRAMEN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_AHB5_GRP1_PERIPH AHB5 GRP1 PERIPH + * @{ + */ +#define LL_AHB5_GRP1_PERIPH_HPDMA1 RCC_AHB5ENR_HPDMA1EN +#define LL_AHB5_GRP1_PERIPH_DMA2D RCC_AHB5ENR_DMA2DEN +#define LL_AHB5_GRP1_PERIPH_JPEG RCC_AHB5ENR_JPEGEN +#define LL_AHB5_GRP1_PERIPH_FMC RCC_AHB5ENR_FMCEN +#define LL_AHB5_GRP1_PERIPH_XSPI1 RCC_AHB5ENR_XSPI1EN +#define LL_AHB5_GRP1_PERIPH_XSPI2 RCC_AHB5ENR_XSPI2EN +#define LL_AHB5_GRP1_PERIPH_XSPIM RCC_AHB5ENR_XSPIMEN +#define LL_AHB5_GRP1_PERIPH_SDMMC1 RCC_AHB5ENR_SDMMC1EN +#define LL_AHB5_GRP1_PERIPH_GFXMMU RCC_AHB5ENR_GFXMMUEN +#if defined(GPU2D) +#define LL_AHB5_GRP1_PERIPH_GPU2D RCC_AHB5ENR_GPU2DEN +#endif /* GPU2D */ + +#define LL_AHB5_GRP1_PERIPH_FLASH RCC_AHB5LPENR_FLASHLPEN +#define LL_AHB5_GRP1_PERIPH_AXISRAM RCC_AHB5LPENR_AXISRAMLPEN +#define LL_AHB5_GRP1_PERIPH_DTCM1 RCC_AHB5LPENR_DTCM1LPEN +#define LL_AHB5_GRP1_PERIPH_DTCM2 RCC_AHB5LPENR_DTCM2LPEN +#define LL_AHB5_GRP1_PERIPH_ITCM RCC_AHB5LPENR_ITCMLPEN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB1_GRP1_PERIPH APB1 GRP1 PERIPH + * @{ + */ +#define LL_APB1_GRP1_PERIPH_TIM2 RCC_APB1ENR1_TIM2EN +#define LL_APB1_GRP1_PERIPH_TIM3 RCC_APB1ENR1_TIM3EN +#define LL_APB1_GRP1_PERIPH_TIM4 RCC_APB1ENR1_TIM4EN +#define LL_APB1_GRP1_PERIPH_TIM5 RCC_APB1ENR1_TIM5EN +#define LL_APB1_GRP1_PERIPH_TIM6 RCC_APB1ENR1_TIM6EN +#define LL_APB1_GRP1_PERIPH_TIM7 RCC_APB1ENR1_TIM7EN +#define LL_APB1_GRP1_PERIPH_TIM12 RCC_APB1ENR1_TIM12EN +#define LL_APB1_GRP1_PERIPH_TIM13 RCC_APB1ENR1_TIM13EN +#define LL_APB1_GRP1_PERIPH_TIM14 RCC_APB1ENR1_TIM14EN +#define LL_APB1_GRP1_PERIPH_LPTIM1 RCC_APB1ENR1_LPTIM1EN +#define LL_APB1_GRP1_PERIPH_WWDG RCC_APB1ENR1_WWDGEN +#define LL_APB1_GRP1_PERIPH_SPI2 RCC_APB1ENR1_SPI2EN +#define LL_APB1_GRP1_PERIPH_SPI3 RCC_APB1ENR1_SPI3EN +#define LL_APB1_GRP1_PERIPH_SPDIFRX RCC_APB1ENR1_SPDIFRXEN +#define LL_APB1_GRP1_PERIPH_USART2 RCC_APB1ENR1_USART2EN +#define LL_APB1_GRP1_PERIPH_USART3 RCC_APB1ENR1_USART3EN +#define LL_APB1_GRP1_PERIPH_UART4 RCC_APB1ENR1_UART4EN +#define LL_APB1_GRP1_PERIPH_UART5 RCC_APB1ENR1_UART5EN +#define LL_APB1_GRP1_PERIPH_I2C1 RCC_APB1ENR1_I2C1_I3C1EN +#define LL_APB1_GRP1_PERIPH_I2C2 RCC_APB1ENR1_I2C2EN +#define LL_APB1_GRP1_PERIPH_I2C3 RCC_APB1ENR1_I2C3EN +#define LL_APB1_GRP1_PERIPH_I3C1 RCC_APB1ENR1_I2C1_I3C1EN +#define LL_APB1_GRP1_PERIPH_CEC RCC_APB1ENR1_CECEN +#define LL_APB1_GRP1_PERIPH_UART7 RCC_APB1ENR1_UART7EN +#define LL_APB1_GRP1_PERIPH_UART8 RCC_APB1ENR1_UART8EN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB1_GRP2_PERIPH APB1 GRP2 PERIPH + * @{ + */ +#define LL_APB1_GRP2_PERIPH_CRS RCC_APB1ENR2_CRSEN +#define LL_APB1_GRP2_PERIPH_MDIOS RCC_APB1ENR2_MDIOSEN +#define LL_APB1_GRP2_PERIPH_FDCAN RCC_APB1ENR2_FDCANEN +#define LL_APB1_GRP2_PERIPH_UCPD1 RCC_APB1ENR2_UCPD1EN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB2_GRP1_PERIPH APB2 GRP1 PERIPH + * @{ + */ +#define LL_APB2_GRP1_PERIPH_TIM1 RCC_APB2ENR_TIM1EN +#define LL_APB2_GRP1_PERIPH_USART1 RCC_APB2ENR_USART1EN +#define LL_APB2_GRP1_PERIPH_SPI1 RCC_APB2ENR_SPI1EN +#define LL_APB2_GRP1_PERIPH_SPI4 RCC_APB2ENR_SPI4EN +#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN +#define LL_APB2_GRP1_PERIPH_TIM16 RCC_APB2ENR_TIM16EN +#define LL_APB2_GRP1_PERIPH_TIM17 RCC_APB2ENR_TIM17EN +#define LL_APB2_GRP1_PERIPH_TIM9 RCC_APB2ENR_TIM9EN +#define LL_APB2_GRP1_PERIPH_SPI5 RCC_APB2ENR_SPI5EN +#define LL_APB2_GRP1_PERIPH_SAI1 RCC_APB2ENR_SAI1EN +#define LL_APB2_GRP1_PERIPH_SAI2 RCC_APB2ENR_SAI2EN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB4_GRP1_PERIPH APB4 GRP1 PERIPH + * @{ + */ +#define LL_APB4_GRP1_PERIPH_SBS RCC_APB4ENR_SBSEN +#define LL_APB4_GRP1_PERIPH_LPUART1 RCC_APB4ENR_LPUART1EN +#define LL_APB4_GRP1_PERIPH_SPI6 RCC_APB4ENR_SPI6EN +#define LL_APB4_GRP1_PERIPH_LPTIM2 RCC_APB4ENR_LPTIM2EN +#define LL_APB4_GRP1_PERIPH_LPTIM3 RCC_APB4ENR_LPTIM3EN +#define LL_APB4_GRP1_PERIPH_LPTIM4 RCC_APB4ENR_LPTIM4EN +#define LL_APB4_GRP1_PERIPH_LPTIM5 RCC_APB4ENR_LPTIM5EN +#define LL_APB4_GRP1_PERIPH_VREF RCC_APB4ENR_VREFEN +#define LL_APB4_GRP1_PERIPH_RTCAPB RCC_APB4ENR_RTCAPBEN +#define LL_APB4_GRP1_PERIPH_DTS RCC_APB4ENR_DTSEN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB5_GRP1_PERIPH APB5 GRP1 PERIPH + * @{ + */ +#if defined(LTDC) +#define LL_APB5_GRP1_PERIPH_LTDC RCC_APB5ENR_LTDCEN +#endif /* LTDC */ +#define LL_APB5_GRP1_PERIPH_DCMIPP RCC_APB5ENR_DCMIPPEN +#define LL_APB5_GRP1_PERIPH_GFXTIM RCC_APB5ENR_GFXTIMEN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_CKGA_PERIPH CKGA (AXI Clocks Gating) PERIPH + * @{ + */ +#define LL_CKGA_PERIPH_AXI RCC_CKGDISR_AXICKG +#define LL_CKGA_PERIPH_AHBM RCC_CKGDISR_AHBMCKG +#define LL_CKGA_PERIPH_SDMMC1 RCC_CKGDISR_SDMMC1CKG +#define LL_CKGA_PERIPH_HPDMA1 RCC_CKGDISR_HPDMA1CKG +#define LL_CKGA_PERIPH_CPU RCC_CKGDISR_CPUCKG +#if defined(GPU2D) +#define LL_CKGA_PERIPH_GPU2DS1 RCC_CKGDISR_GPU2DS1CKG +#define LL_CKGA_PERIPH_GPU2DS0 RCC_CKGDISR_GPU2DS0CKG +#define LL_CKGA_PERIPH_GPU2DCL RCC_CKGDISR_GPU2DCLCKG +#endif /* GPU2D */ +#define LL_CKGA_PERIPH_DCMIPP RCC_CKGDISR_DCMIPPCKG +#define LL_CKGA_PERIPH_DMA2D RCC_CKGDISR_DMA2DCKG +#define LL_CKGA_PERIPH_GFXMMUS RCC_CKGDISR_GFXMMUSCKG +#if defined(LTDC) +#define LL_CKGA_PERIPH_LTDC RCC_CKGDISR_LTDCCKG +#endif /* LTDC */ +#define LL_CKGA_PERIPH_GFXMMUM RCC_CKGDISR_GFXMMUMCKG +#define LL_CKGA_PERIPH_AHBS RCC_CKGDISR_AHBSCKG +#define LL_CKGA_PERIPH_FMC RCC_CKGDISR_FMCCKG +#define LL_CKGA_PERIPH_XSPI1 RCC_CKGDISR_XSPI1CKG +#define LL_CKGA_PERIPH_XSPI2 RCC_CKGDISR_XSPI2CKG +#define LL_CKGA_PERIPH_AXIRAM1 RCC_CKGDISR_AXISRAM1CKG +#define LL_CKGA_PERIPH_AXIRAM2 RCC_CKGDISR_AXISRAM2CKG +#define LL_CKGA_PERIPH_AXIRAM3 RCC_CKGDISR_AXISRAM3CKG +#define LL_CKGA_PERIPH_AXIRAM4 RCC_CKGDISR_AXISRAM4CKG +#define LL_CKGA_PERIPH_FLASH RCC_CKGDISR_FLASHCKG +#define LL_CKGA_PERIPH_EXTI RCC_CKGDISR_EXTICKG +#define LL_CKGA_PERIPH_JTAG RCC_CKGDISR_JTAGCKG +/** + * @} + */ + +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup BUS_LL_Exported_Functions BUS Exported Functions + * @{ + */ + +/** @defgroup BUS_LL_EF_AHB1 AHB1 + * @{ + */ + +/** + * @brief Enable AHB1 peripherals clock. + * @rmtoll AHB1ENR GPDMA1EN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ADC12EN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ETH1MACEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ETH1TXEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ETH1RXEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR OTGFSEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR OTGHSEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR USBPHYCEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ADF1EN LL_AHB1_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1TX + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1RX + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @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 ADC12EN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ETH1MACEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ETH1TXEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ETH1RXEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR OTGHSEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR OTGFSEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR USBPHYCEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ADF1EN LL_AHB1_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1TX + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1RX + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_AHB1_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB1ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable AHB1 peripherals clock. + * @rmtoll AHB1ENR GPDMA1EN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ADC12EN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ETH1MACEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ETH1TXEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ETH1RXEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR OTGHSEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR OTGFSEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR USBPHYCEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ADF1EN LL_AHB1_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1TX + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1RX + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @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 ADC12RST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR ETH1RST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR OTGHSRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR OTGFSRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR USBPHYCRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR ADF1RST LL_AHB1_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @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 ADC12RST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR ETH1RST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR OTGHSRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR OTGFSRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR USBPHYCRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR ADF1RST LL_AHB1_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB1RSTR, Periphs); +} + +/** + * @brief Enable AHB1 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB1LPENR GPDMA1LPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ADC12LPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ETH1MACLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ETH1TXLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ETH1RXLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR OTGHSLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR OTGFSLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR USBPHYCLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ADF1LPEN LL_AHB1_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1TX + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1RX + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @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 Disable AHB1 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB1LPENR GPDMA1LPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ADC12LPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ETH1MACLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ETH1TXLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ETH1RXLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR OTGHSLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR OTGHSLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR USBPHYCLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ADF1LPEN LL_AHB1_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_ADC12 + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1MAC + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1TX + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH1RX + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGHS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBOTGFS + * @arg @ref LL_AHB1_GRP1_PERIPH_USBPHYC + * @arg @ref LL_AHB1_GRP1_PERIPH_ADF1 + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB1LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_AHB2 AHB2 + * @{ + */ + +/** + * @brief Enable AHB2 peripherals clock. + * @rmtoll AHB2ENR PSSIEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR SDMMC2EN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR CORDICEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR AHBSRAM1EN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR AHBSRAM2EN LL_AHB2_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM1 + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM2 + * @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 PSSIEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR SDMMC2EN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR CORDICEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR AHBSRAM1EN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR AHBSRAM2EN LL_AHB2_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM1 + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM2 + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_AHB2_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB2ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable AHB2 peripherals clock. + * @rmtoll AHB2ENR PSSIEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR SDMMC2EN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR CORDICEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR AHBSRAM1EN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR AHBSRAM2EN LL_AHB2_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM1 + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM2 + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB2ENR, Periphs); +} + +/** + * @brief Force AHB2 peripherals reset. + * @rmtoll AHB2RSTR PSSIRST LL_AHB2_GRP1_ForceReset\n + * AHB2RSTR SDMMC2RST LL_AHB2_GRP1_ForceReset\n + * AHB2RSTR CORDICRST LL_AHB2_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB2RSTR, Periphs); +} + +/** + * @brief Release AHB2 peripherals reset. + * @rmtoll AHB2RSTR PSSIRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RSTR SDMMC2RST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RSTR CORDICRST LL_AHB2_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB2RSTR, Periphs); +} + +/** + * @brief Enable AHB2 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB2LPENR PSSILPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR SDMMC2LPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR CORDICLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR AHBSRAM1LPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR AHBSRAM2LPEN LL_AHB2_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM1 + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM2 + * @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 Disable AHB2 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB2LPENR PSSILPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR SDMMC2LPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR CORDICLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR AHBSRAM1LPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR AHBSRAM2LPEN LL_AHB2_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_PSSI + * @arg @ref LL_AHB2_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB2_GRP1_PERIPH_CORDIC + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM1 + * @arg @ref LL_AHB2_GRP1_PERIPH_AHBSRAM2 + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB2LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_AHB3 AHB3 + * @{ + */ + +/** + * @brief Enable AHB3 peripherals clock. + * @rmtoll AHB3ENR RNGEN LL_AHB3_GRP1_EnableClock\n + * AHB3ENR HASHEN LL_AHB3_GRP1_EnableClock\n + * AHB3ENR CRYPEN LL_AHB3_GRP1_EnableClock\n + * AHB3ENR SAESEN LL_AHB3_GRP1_EnableClock\n + * AHB3ENR PKAEN LL_AHB3_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB3_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB3ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB3ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB3 peripheral clock is enabled or not + * @rmtoll AHB3ENR RNGEN LL_AHB3_GRP1_IsEnabledClock\n + * AHB3ENR HASHEN LL_AHB3_GRP1_IsEnabledClock\n + * AHB3ENR CRYPEN LL_AHB3_GRP1_IsEnabledClock\n + * AHB3ENR SAESEN LL_AHB3_GRP1_IsEnabledClock\n + * AHB3ENR PKAEN LL_AHB3_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_AHB3_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB3ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable AHB3 peripherals clock. + * @rmtoll AHB3ENR RNGEN LL_AHB3_GRP1_DisableClock\n + * AHB3ENR HASHEN LL_AHB3_GRP1_DisableClock\n + * AHB3ENR CRYPEN LL_AHB3_GRP1_DisableClock\n + * AHB3ENR SAESEN LL_AHB3_GRP1_DisableClock\n + * AHB3ENR PKAEN LL_AHB3_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB3_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB3ENR, Periphs); +} + +/** + * @brief Enable AHB3 peripherals clock. + * @rmtoll AHB3RSTR RNGRST LL_AHB3_GRP1_ForceReset\n + * AHB3RSTR HASHRST LL_AHB3_GRP1_ForceReset\n + * AHB3RSTR CRYPRST LL_AHB3_GRP1_ForceReset\n + * AHB3RSTR SAESRST LL_AHB3_GRP1_ForceReset\n + * AHB3RSTR PKARST LL_AHB3_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB3_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB3RSTR, Periphs); +} + +/** + * @brief Release AHB3 peripherals reset. + * @rmtoll AHB3RSTR RNGRST LL_AHB3_GRP1_ReleaseReset\n + * AHB3RSTR HASHRST LL_AHB3_GRP1_ReleaseReset\n + * AHB3RSTR CRYPRST LL_AHB3_GRP1_ReleaseReset\n + * AHB3RSTR SAESRST LL_AHB3_GRP1_ReleaseReset\n + * AHB3RSTR PKARST LL_AHB3_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB3_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB3RSTR, Periphs); +} + +/** + * @brief Enable AHB3 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB3LPENR RNGLPEN LL_AHB3_GRP1_EnableClockSleep\n + * AHB3LPENR HASHLPEN LL_AHB3_GRP1_EnableClockSleep\n + * AHB3LPENR CRYPLPEN LL_AHB3_GRP1_EnableClockSleep\n + * AHB3LPENR SAESLPEN LL_AHB3_GRP1_EnableClockSleep\n + * AHB3LPENR PKALPEN LL_AHB3_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB3_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB3LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB3LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Disable AHB3 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB3LPENR RNGLPEN LL_AHB3_GRP1_DisableClockSleep\n + * AHB3LPENR HASHLPEN LL_AHB3_GRP1_DisableClockSleep\n + * AHB3LPENR CRYPLPEN LL_AHB3_GRP1_DisableClockSleep\n + * AHB3LPENR SAESLPEN LL_AHB3_GRP1_DisableClockSleep\n + * AHB3LPENR PKALPEN LL_AHB3_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB3_GRP1_PERIPH_RNG + * @arg @ref LL_AHB3_GRP1_PERIPH_HASH + * @arg @ref LL_AHB3_GRP1_PERIPH_CRYP (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB3_GRP1_PERIPH_PKA + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB3_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB3LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_AHB4 AHB4 + * @{ + */ + +/** + * @brief Enable AHB4 peripherals clock. + * @rmtoll AHB4ENR GPIOAEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOBEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOCEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIODEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOEEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOFEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOGEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOHEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOMEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIONEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOOEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR GPIOPEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR CRCEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR BKPRAMEN LL_AHB4_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @arg @ref LL_AHB4_GRP1_PERIPH_BKPRAM + * @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 GPIOAEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOBEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOCEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIODEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOEEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOFEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOGEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOHEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOMEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIONEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOOEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR GPIOPEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR CRCEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR BKPRAMEN LL_AHB4_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @arg @ref LL_AHB4_GRP1_PERIPH_BKPRAM + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_AHB4_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB4ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable AHB4 peripherals clock. + * @rmtoll AHB4ENR GPIOAEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOBEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOCEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIODEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOEEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOFEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOGEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOHEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOMEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIONEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOOEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR GPIOPEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR CRCEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR BKPRAMEN LL_AHB4_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @arg @ref LL_AHB4_GRP1_PERIPH_BKPRAM + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB4ENR, Periphs); +} + +/** + * @brief Force AHB4 peripherals reset. + * @rmtoll AHB4RSTR GPIOARST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOBRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOCRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIODRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOERST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOFRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOGRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOHRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOMRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIONRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOORST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR GPIOPRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR CRCRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR BKPRAMRST LL_AHB4_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @arg @ref LL_AHB4_GRP1_PERIPH_BKPRAM + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB4RSTR, Periphs); +} + +/** + * @brief Release AHB4 peripherals reset. + * @rmtoll AHB4RSTR GPIOARST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOBRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOCRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIODRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOERST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOFRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOGRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOHRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOMRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIONRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOORST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR GPIOPRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR CRCRST LL_AHB4_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB4RSTR, Periphs); +} + +/** + * @brief Enable AHB4 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB4LPENR GPIOALPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOBLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOCLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIODLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOELPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOFLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOGLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOHLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOMLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIONLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOOLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR GPIOPLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR CRCLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR BKPRAMLPEN LL_AHB4_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @arg @ref LL_AHB4_GRP1_PERIPH_BKPRAM + * @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 Disable AHB4 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB4LPENR GPIOALPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOBLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOCLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIODLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOELPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOFLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOGLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOHLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOMLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIONLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOOLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR GPIOPLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR CRCLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR BKPRAMLPEN LL_AHB4_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOE + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOG + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOM + * @arg @ref LL_AHB4_GRP1_PERIPH_GPION + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOO + * @arg @ref LL_AHB4_GRP1_PERIPH_GPIOP + * @arg @ref LL_AHB4_GRP1_PERIPH_CRC + * @arg @ref LL_AHB4_GRP1_PERIPH_BKPRAM + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB4LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_AHB5 AHB5 + * @{ + */ + +/** + * @brief Enable AHB5 peripherals clock. + * @rmtoll AHB5ENR HPDMA1EN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR DMA2DEN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR JPEGEN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR FMCEN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR XSPI1EN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR XSPI2EN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR XSPIMEN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR SDMMC1EN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR GFXMMUEN LL_AHB5_GRP1_EnableClock\n + * AHB5ENR GPU2DEN LL_AHB5_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB5_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB5ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB5ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB5 peripheral clock is enabled or not + * @rmtoll AHB5ENR HPDMA1EN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR DMA2DEN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR JPEGEN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR FMCEN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR XSPI1EN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR XSPI2EN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR XSPIMEN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR SDMMC1EN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR GFXMMUEN LL_AHB5_GRP1_IsEnabledClock\n + * AHB5ENR GPU2DEN LL_AHB5_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * + * (*) value not defined in all devices. + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_AHB5_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB5ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable AHB5 peripherals clock. + * @rmtoll AHB5ENR HPDMA1EN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR DMA2DEN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR JPEGEN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR FMCEN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR XSPI1EN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR XSPI2EN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR XSPIMEN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR SDMMC1EN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR GFXMMUEN LL_AHB5_GRP1_DisableClock\n + * AHB5ENR GPU2DEN LL_AHB5_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB5_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB5ENR, Periphs); +} + +/** + * @brief Force AHB5 peripherals reset. + * @rmtoll AHB5RSTR HPDMA1RST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR DMA2DRST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR JPEGRST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR FMCRST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR XSPI1RST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR XSPI2RST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR XSPIMRST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR SDMMC1RST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR GFXMMURST LL_AHB5_GRP1_ForceReset\n + * AHB5RSTR GPU2DRST LL_AHB5_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB5_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB5RSTR, Periphs); +} + +/** + * @brief Release AHB5 peripherals reset. + * @rmtoll AHB5RSTR HPDMA1RST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR DMA2DRST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR JPEGRST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR FMCRST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR XSPI1RST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR XSPI2RST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR XSPIMRST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR SDMMC1RST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR GFXMMURST LL_AHB5_GRP1_ReleaseReset\n + * AHB5RSTR GPU2DRST LL_AHB5_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB5_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB5RSTR, Periphs); +} + +/** + * @brief Enable AHB5 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB5LPENR HPDMA1LPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR DMA2DLPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR JPEGLPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR FMCLPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR XSPI1LPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR XSPI2LPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR XSPIMLPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR SDMMC1LPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR GFXMMULPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR GPU2DLPEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR AXISRAMPLEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR DTCM1PLEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR DTCM2PLEN LL_AHB5_GRP1_EnableClockSleep\n + * AHB5LPENR ITCMPLEN LL_AHB5_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_AXISRAM + * @arg @ref LL_AHB5_GRP1_PERIPH_DTCM1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DTCM2 + * @arg @ref LL_AHB5_GRP1_PERIPH_ITCM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB5_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB5LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB5LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Disable AHB5 peripherals clock during Low Power (Sleep) mode. + * @rmtoll AHB5LPENR HPDMA1LPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR DMA2DLPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR FLASHLPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR JPEGLPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR FMCLPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR XSPI1LPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR XSPI2LPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR XSPIMLPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR SDMMC1LPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR GFXMMULPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR GPU2DLPEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR AXISRAMPLEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR DTCM1PLEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR DTCM2PLEN LL_AHB5_GRP1_DisableClockSleep\n + * AHB5LPENR ITCMPLEN LL_AHB5_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB5_GRP1_PERIPH_HPDMA1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DMA2D + * @arg @ref LL_AHB5_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB5_GRP1_PERIPH_JPEG (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_FMC + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI1 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPI2 + * @arg @ref LL_AHB5_GRP1_PERIPH_XSPIM + * @arg @ref LL_AHB5_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB5_GRP1_PERIPH_GFXMMU (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_GPU2D (*) + * @arg @ref LL_AHB5_GRP1_PERIPH_AXISRAM + * @arg @ref LL_AHB5_GRP1_PERIPH_DTCM1 + * @arg @ref LL_AHB5_GRP1_PERIPH_DTCM2 + * @arg @ref LL_AHB5_GRP1_PERIPH_ITCM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_AHB5_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB5LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_APB1 APB1 + * @{ + */ + +/** + * @brief Enable APB1 peripherals clock. + * @rmtoll APB1ENR1 TIM2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM3EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM4EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM5EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM6EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM7EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM12EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM13EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 TIM14EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 LPTIM1EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 WWDGEN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 SPI2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 SPI3EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 SPDIFRXEN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 USART2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 USART3EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 UART4EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 UART5EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 I2C1EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 I2C2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 I2C3EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 I3C1EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 CECEN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 UART7EN LL_APB1_GRP1_EnableClock\n + * APB1ENR1 UART8EN LL_APB1_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @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_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1ENR1, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1ENR1, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB1 peripheral clock is enabled or not + * @rmtoll APB1ENR1 TIM2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM4EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM5EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM6EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM7EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM12EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM13EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 TIM14EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 LPTIM1EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 WWDGEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 SPI2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 SPI3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 SPDIFRXEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 USART2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 USART3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 UART4EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 UART5EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 I2C1EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 I2C2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 I2C3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 I3C1EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 CECEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 UART7EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR1 UART8EN LL_APB1_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @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_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_APB1_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB1ENR1, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable APB1 peripherals clock. + * @rmtoll APB1ENR1 TIM2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM3EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM4EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM5EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM6EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM7EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM12EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM13EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 TIM14EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 LPTIM1EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 SPI2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 SPI3EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 SPDIFRXEN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 USART2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 USART3EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 UART4EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 UART5EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 I2C1EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 I2C2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 I2C3EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 I3C1EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 CECEN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 UART7EN LL_APB1_GRP1_DisableClock\n + * APB1ENR1 UART8EN LL_APB1_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1ENR1, Periphs); +} + +/** + * @brief Force APB1 peripherals reset. + * @rmtoll APB1RSTR1 TIM2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM3RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM4RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM5RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM6RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM7RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM12RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM13RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 TIM14RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 LPTIM1RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 WWDGRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 SPI2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 SPI3RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 SPDIFRXRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 USART2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 USART3RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 UART4RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 UART5RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 I2C1RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 I2C2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 I2C3RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 I3C1RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 CECRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 UART7RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR1 UART8RST LL_APB1_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @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_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB1RSTR1, Periphs); +} + +/** + * @brief Release APB1 peripherals reset. + * @rmtoll APB1RSTR1 TIM2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM3RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM4RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM5RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM6RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM7RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM12RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM13RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 TIM14RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 LPTIM1RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 WWDGRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 SPI2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 SPI3RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 SPDIFRXRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 USART2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 USART3RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 UART4RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 UART5RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 I2C1RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 I2C2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 I2C3RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 I3C1RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 CECRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 UART7RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR1 UART8RST LL_APB1_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @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_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1RSTR1, Periphs); +} + +/** + * @brief Enable APB1 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB1LPENR1 TIM2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM4LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM5LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM6LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM7LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM12LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM13LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 TIM14LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 LPTIM1LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 WWDGLPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 SPI2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 SPI3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 SPDIFRXLPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 USART2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 USART3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 UART4LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 UART5LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 I2C1LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 I2C2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 I2C3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 I3C1LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 CECLPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 DAC12LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 UART7LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LPENR1 UART8LPEN LL_APB1_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @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_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1LPENR1, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1LPENR1, Periphs); + (void)tmpreg; +} + +/** + * @brief Disable APB1 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB1LPENR1 TIM2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM4LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM5LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM6LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM7LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM12LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM13LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 TIM14LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 LPTIM1LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 WWDGLPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 SPI2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 SPI3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 SPDIFRXLPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 USART2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 USART3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 UART4LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 UART5LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 I2C1LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 I2C2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 I2C3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 I3C1LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 CECLPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 UART7LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LPENR1 UART8LPEN LL_APB1_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @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_LPTIM1 + * @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_SPDIFRX + * @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_I2C3 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1LPENR1, Periphs); +} + +/** + * @brief Enable APB1 peripherals clock. + * @rmtoll APB1ENR2 CRSEN LL_APB1_GRP2_EnableClock\n + * APB1ENR2 MDIOSEN LL_APB1_GRP2_EnableClock\n + * APB1ENR2 FDCANEN LL_APB1_GRP2_EnableClock\n + * APB1ENR2 UCPD1EN LL_APB1_GRP2_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1ENR2, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1ENR2, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB1 peripheral clock is enabled or not + * @rmtoll APB1ENR2 CRSEN LL_APB1_GRP2_IsEnabledClock\n + * APB1ENR2 MDIOSEN LL_APB1_GRP2_IsEnabledClock\n + * APB1ENR2 FDCANEN LL_APB1_GRP2_IsEnabledClock\n + * APB1ENR2 UCPD1EN LL_APB1_GRP2_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_APB1_GRP2_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB1ENR2, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable APB1 peripherals clock. + * @rmtoll APB1ENR2 CRSEN LL_APB1_GRP2_DisableClock\n + * APB1ENR2 MDIOSEN LL_APB1_GRP2_DisableClock\n + * APB1ENR2 FDCANEN LL_APB1_GRP2_DisableClock\n + * APB1ENR2 UCPD1EN LL_APB1_GRP2_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1ENR2, Periphs); +} + +/** + * @brief Force APB1 peripherals reset. + * @rmtoll APB1RSTR2 CRSRST LL_APB1_GRP2_ForceReset\n + * APB1ENR2 MDIOSRST LL_APB1_GRP2_ForceReset\n + * APB1ENR2 FDCANRST LL_APB1_GRP2_ForceReset\n + * APB1ENR2 UCPD1RST LL_APB1_GRP2_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB1RSTR2, Periphs); +} + +/** + * @brief Release APB1 peripherals reset. + * @rmtoll APB1RSTR2 CRSRST LL_APB1_GRP2_ReleaseReset\n + * APB1ENR2 MDIOSRST LL_APB1_GRP2_ReleaseReset\n + * APB1ENR2 FDCANRST LL_APB1_GRP2_ReleaseReset\n + * APB1ENR2 UCPD1RST LL_APB1_GRP2_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1RSTR2, Periphs); +} + +/** + * @brief Enable APB1 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB1LPENR2 CRSLPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1LPENR2 MDIOSLPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1LPENR2 FDCANLPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1LPENR2 UCPD1LPEN LL_APB1_GRP2_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1LPENR2, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1LPENR2, Periphs); + (void)tmpreg; +} + +/** + * @brief Disable APB1 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB1LPENR2 CRSLPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1LPENR2 MDIOSLPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1LPENR2 FDCANLPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1LPENR2 UCPD1LPEN LL_APB1_GRP2_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_CRS + * @arg @ref LL_APB1_GRP2_PERIPH_MDIOS + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1LPENR2, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_APB2 APB2 + * @{ + */ + +/** + * @brief Enable APB2 peripherals clock. + * @rmtoll APB2ENR TIM1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR USART1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SPI1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SPI4EN 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 TIM9EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SPI5EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SAI1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SAI2EN LL_APB2_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @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 USART1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SPI1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SPI4EN 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 TIM9EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SPI5EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SAI1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SAI2EN LL_APB2_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_APB2_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB2ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable APB2 peripherals clock. + * @rmtoll APB2ENR TIM1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR USART1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SPI1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SPI4EN 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 TIM9EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SPI5EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SAI1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SAI2EN LL_APB2_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @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 USART1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SPI1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SPI4RST 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 TIM9RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SPI5RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SAI1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SAI2RST LL_APB2_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @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 USART1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SPI1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SPI4RST 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 TIM9RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SPI5RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SAI1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SAI2RST LL_APB2_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB2RSTR, Periphs); +} + +/** + * @brief Enable APB2 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB2LPENR TIM1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR USART1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SPI1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SPI4LPEN 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 TIM9LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SPI5LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SAI1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SAI2LPEN LL_APB2_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @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 Disable APB2 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB2LPENR TIM1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR USART1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SPI1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SPI4LPEN 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 TIM9LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SPI5LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SAI1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SAI2LPEN LL_APB2_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 + * @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_TIM9 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI5 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB2LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_APB4 APB4 + * @{ + */ + +/** + * @brief Enable APB4 peripherals clock. + * @rmtoll APB4ENR SBSEN LL_APB4_GRP1_EnableClock\n + * APB4ENR LPUART1EN LL_APB4_GRP1_EnableClock\n + * APB4ENR SPI6EN LL_APB4_GRP1_EnableClock\n + * APB4ENR LPTIM2EN LL_APB4_GRP1_EnableClock\n + * APB4ENR LPTIM3EN LL_APB4_GRP1_EnableClock\n + * APB4ENR LPTIM4EN LL_APB4_GRP1_EnableClock\n + * APB4ENR LPTIM5EN LL_APB4_GRP1_EnableClock\n + * APB4ENR VREFEN LL_APB4_GRP1_EnableClock\n + * APB4ENR RTCAPBEN LL_APB4_GRP1_EnableClock\n + * APB4ENR DTSEN LL_APB4_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_RTCAPB + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval None + */ +__STATIC_INLINE void LL_APB4_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB4ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB4ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB4 peripheral clock is enabled or not + * @rmtoll APB4ENR SBSEN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR LPUART1EN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR SPI6EN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR LPTIM2EN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR LPTIM3EN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR LPTIM4EN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR LPTIM5EN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR VREFEN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR RTCAPBEN LL_APB4_GRP1_IsEnabledClock\n + * APB4ENR DTSEN LL_APB4_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_RTCAPB + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_APB4_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB4ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable APB4 peripherals clock. + * @rmtoll APB4ENR SBSEN LL_APB4_GRP1_DisableClock\n + * APB4ENR LPUART1EN LL_APB4_GRP1_DisableClock\n + * APB4ENR SPI6EN LL_APB4_GRP1_DisableClock\n + * APB4ENR LPTIM2EN LL_APB4_GRP1_DisableClock\n + * APB4ENR LPTIM3EN LL_APB4_GRP1_DisableClock\n + * APB4ENR LPTIM4EN LL_APB4_GRP1_DisableClock\n + * APB4ENR LPTIM5EN LL_APB4_GRP1_DisableClock\n + * APB4ENR VREFEN LL_APB4_GRP1_DisableClock\n + * APB4ENR RTCAPBEN LL_APB4_GRP1_DisableClock\n + * APB4ENR DTSEN LL_APB4_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_RTCAPB + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval None + */ +__STATIC_INLINE void LL_APB4_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB4ENR, Periphs); +} + +/** + * @brief Force APB4 peripherals reset. + * @rmtoll APB4RSTR SBSRST LL_APB4_GRP1_ForceReset\n + * APB4RSTR LPUART1RST LL_APB4_GRP1_ForceReset\n + * APB4RSTR SPI6RST LL_APB4_GRP1_ForceReset\n + * APB4RSTR LPTIM2RST LL_APB4_GRP1_ForceReset\n + * APB4RSTR LPTIM3RST LL_APB4_GRP1_ForceReset\n + * APB4RSTR LPTIM4RST LL_APB4_GRP1_ForceReset\n + * APB4RSTR LPTIM5RST LL_APB4_GRP1_ForceReset\n + * APB4RSTR VREFRST LL_APB4_GRP1_ForceReset\n + * APB4RSTR DTSRST LL_APB4_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval None + */ +__STATIC_INLINE void LL_APB4_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB4RSTR, Periphs); +} + +/** + * @brief Release APB4 peripherals reset. + * @rmtoll APB4RSTR SBSRST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR LPUART1RST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR SPI6RST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR LPTIM2RST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR LPTIM3RST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR LPTIM4RST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR LPTIM5RST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR VREFRST LL_APB4_GRP1_ReleaseReset\n + * APB4RSTR DTSRST LL_APB4_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval None + */ +__STATIC_INLINE void LL_APB4_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB4RSTR, Periphs); +} + +/** + * @brief Enable APB4 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB4LPENR SBSLPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR LPUART1LPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR SPI6LPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR LPTIM2LPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR LPTIM3LPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR LPTIM4LPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR LPTIM5LPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR VREFLPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR RTCAPBLPEN LL_APB4_GRP1_EnableClockSleep\n + * APB4LPENR DTSLPEN LL_APB4_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_RTCAPB + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval None + */ +__STATIC_INLINE void LL_APB4_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB4LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB4LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Disable APB4 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB4LPENR SBSLPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR LPUART1LPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR SPI6LPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR LPTIM2LPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR LPTIM3LPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR LPTIM4LPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR LPTIM5LPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR VREFLPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR RTCAPBLPEN LL_APB4_GRP1_DisableClockSleep\n + * APB4LPENR DTSLPEN LL_APB4_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB4_GRP1_PERIPH_SBS + * @arg @ref LL_APB4_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB4_GRP1_PERIPH_SPI6 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM2 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM3 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM4 + * @arg @ref LL_APB4_GRP1_PERIPH_LPTIM5 + * @arg @ref LL_APB4_GRP1_PERIPH_VREF + * @arg @ref LL_APB4_GRP1_PERIPH_RTCAPB + * @arg @ref LL_APB4_GRP1_PERIPH_DTS + * @retval None + */ +__STATIC_INLINE void LL_APB4_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB4LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_APB5 APB5 + * @{ + */ + +/** + * @brief Enable APB5 peripherals clock. + * @rmtoll APB5ENR LTDCEN LL_APB5_GRP1_EnableClock\n + * APB5ENR DCMIPPEN LL_APB5_GRP1_EnableClock\n + * APB5ENR GFXTIMEN LL_APB5_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_APB5_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB5ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB5ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB5 peripheral clock is enabled or not + * @rmtoll APB5ENR LTDCEN LL_APB5_GRP1_IsEnabledClock\n + * APB5ENR DCMIPPEN LL_APB5_GRP1_IsEnabledClock\n + * APB5ENR GFXTIMEN LL_APB5_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_APB5_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB5ENR, Periphs) == Periphs) ? 1U : 0U); +} + +/** + * @brief Disable APB5 peripherals clock. + * @rmtoll APB5ENR LTDCEN LL_APB5_GRP1_DisableClock\n + * APB5ENR DCMIPPEN LL_APB5_GRP1_DisableClock\n + * APB5ENR GFXTIMEN LL_APB5_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_APB5_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB5ENR, Periphs); +} + +/** + * @brief Force APB5 peripherals reset. + * @rmtoll APB5RSTR LTDCRST LL_APB5_GRP1_ForceReset\n + * APB5RSTR DCMIPPRST LL_APB5_GRP1_ForceReset\n + * APB5RSTR GFXTIMRST LL_APB5_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_APB5_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB5RSTR, Periphs); +} + +/** + * @brief Release APB5 peripherals reset. + * @rmtoll APB5RSTR LTDCRST LL_APB5_GRP1_ReleaseReset\n + * APB5RSTR DCMIPPRST LL_APB5_GRP1_ForceReset\n + * APB5RSTR GFXTIMRST LL_APB5_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_APB5_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB5RSTR, Periphs); +} + +/** + * @brief Enable APB5 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB5LPENR LTDCLPEN LL_APB5_GRP1_EnableClockSleep\n + * APB5LPENR DCMIPPLPEN LL_APB5_GRP1_EnableClockSleep\n + * APB5LPENR GFXTIMLPEN LL_APB5_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_APB5_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB5LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB5LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Disable APB5 peripherals clock during Low Power (Sleep) mode. + * @rmtoll APB5LPENR LTDCLPEN LL_APB5_GRP1_DisableClockSleep\n + * APB5LPENR DCMIPPLPEN LL_APB5_GRP1_DisableClockSleep\n + * APB5LPENR GFXTIMLPEN LL_APB5_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB5_GRP1_PERIPH_LTDC (*) + * @arg @ref LL_APB5_GRP1_PERIPH_DCMIPP + * @arg @ref LL_APB5_GRP1_PERIPH_GFXTIM + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_APB5_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB5LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_CKGA CKGA (AXI Clocks Gating) + * @{ + */ + +/** + * @brief Enable clock gating for AXI bus peripherals. + * @rmtoll CKGDISR AXICKG LL_CKGA_Enable\n + * CKGDISR AHBMCKG LL_CKGA_Enable\n + * CKGDISR SDMMC1CKG LL_CKGA_Enable\n + * CKGDISR HPDMA1CKG LL_CKGA_Enable\n + * CKGDISR CPUCKG LL_CKGA_Enable\n + * CKGDISR GPU2DS0CKG LL_CKGA_Enable\n + * CKGDISR GPU2DS1CKG LL_CKGA_Enable\n + * CKGDISR GPUCLCKG LL_CKGA_Enable\n + * CKGDISR DCMIPPCKG LL_CKGA_Enable\n + * CKGDISR DMA2DCKG LL_CKGA_Enable\n + * CKGDISR GFXMMUSCKG LL_CKGA_Enable\n + * CKGDISR LTDCCKG LL_CKGA_Enable\n + * CKGDISR GFXMMUMCKG LL_CKGA_Enable\n + * CKGDISR AHBSCKG LL_CKGA_Enable\n + * CKGDISR FMCCKG LL_CKGA_Enable\n + * CKGDISR XSPI2CKG LL_CKGA_Enable\n + * CKGDISR XSPI1CKG LL_CKGA_Enable\n + * CKGDISR AXIRAM1CKG LL_CKGA_Enable\n + * CKGDISR AXIRAM2CKG LL_CKGA_Enable\n + * CKGDISR AXIRAM3CKG LL_CKGA_Enable\n + * CKGDISR AXIRAM4CKG LL_CKGA_Enable\n + * CKGDISR FLASHCKG LL_CKGA_Enable\n + * CKGDISR EXTICKG LL_CKGA_Enable\n + * CKGDISR JTAGCKG LL_CKGA_Enable + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_CKGA_PERIPH_AXI + * @arg @ref LL_CKGA_PERIPH_AHBM + * @arg @ref LL_CKGA_PERIPH_AHBS + * @arg @ref LL_CKGA_PERIPH_SDMMC1 + * @arg @ref LL_CKGA_PERIPH_HPDMA1 + * @arg @ref LL_CKGA_PERIPH_CPU + * @arg @ref LL_CKGA_PERIPH_GPU2DS0 (*) + * @arg @ref LL_CKGA_PERIPH_GPU2DS1 (*) + * @arg @ref LL_CKGA_PERIPH_GPU2DCL (*) + * @arg @ref LL_CKGA_PERIPH_DMA2D + * @arg @ref LL_CKGA_PERIPH_DCMIPP + * @arg @ref LL_CKGA_PERIPH_LTDC (*) + * @arg @ref LL_CKGA_PERIPH_FLASH + * @arg @ref LL_CKGA_PERIPH_XSPI2 + * @arg @ref LL_CKGA_PERIPH_XSPI1 + * @arg @ref LL_CKGA_PERIPH_FMC + * @arg @ref LL_CKGA_PERIPH_AXIRAM1 + * @arg @ref LL_CKGA_PERIPH_AXIRAM2 + * @arg @ref LL_CKGA_PERIPH_AXIRAM3 + * @arg @ref LL_CKGA_PERIPH_AXIRAM4 + * @arg @ref LL_CKGA_PERIPH_GFXMMUM + * @arg @ref LL_CKGA_PERIPH_GFXMMUS + * @arg @ref LL_CKGA_PERIPH_EXTI + * @arg @ref LL_CKGA_PERIPH_JTAG + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_CKGA_Enable(uint32_t Periphs) +{ + CLEAR_BIT(RCC->CKGDISR, Periphs); +} + +/** + * @brief Check if AXI bus peripherals clock gating is enabled or not + * @rmtoll CKGDISR AXICKG LL_CKGA_IsEnabledClock\n + * CKGDISR AHBMCKG LL_CKGA_IsEnabledClock\n + * CKGDISR SDMMC1CKG LL_CKGA_IsEnabledClock\n + * CKGDISR HPDMA1CKG LL_CKGA_IsEnabledClock\n + * CKGDISR CPUCKG LL_CKGA_IsEnabledClock\n + * CKGDISR GPU2DS0CKG LL_CKGA_IsEnabledClock\n + * CKGDISR GPU2DS1CKG LL_CKGA_IsEnabledClock\n + * CKGDISR GPU2DCLCKG LL_CKGA_IsEnabledClock\n + * CKGDISR DCMIPPCKG LL_CKGA_IsEnabledClock\n + * CKGDISR DMA2DCKG LL_CKGA_IsEnabledClock\n + * CKGDISR GFXMMUSCKG LL_CKGA_IsEnabledClock\n + * CKGDISR LTDCCKG LL_CKGA_IsEnabledClock\n + * CKGDISR GFXMMUMCKG LL_CKGA_IsEnabledClock\n + * CKGDISR AHBSCKG LL_CKGA_IsEnabledClock\n + * CKGDISR FMCCKG LL_CKGA_IsEnabledClock\n + * CKGDISR XSPI2CKG LL_CKGA_IsEnabledClock\n + * CKGDISR XSPI1CKG LL_CKGA_IsEnabledClock\n + * CKGDISR AXIRAM1CKG LL_CKGA_IsEnabledClock\n + * CKGDISR AXIRAM2CKG LL_CKGA_IsEnabledClock\n + * CKGDISR AXIRAM3CKG LL_CKGA_IsEnabledClock\n + * CKGDISR AXIRAM4CKG LL_CKGA_IsEnabledClock\n + * CKGDISR FLASHCKG LL_CKGA_IsEnabledClock\n + * CKGDISR EXTICKG LL_CKGA_IsEnabledClock\n + * CKGDISR JTAGCKG LL_CKGA_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_CKGA_PERIPH_AXI + * @arg @ref LL_CKGA_PERIPH_AHBM + * @arg @ref LL_CKGA_PERIPH_AHBS + * @arg @ref LL_CKGA_PERIPH_SDMMC1 + * @arg @ref LL_CKGA_PERIPH_HPDMA1 + * @arg @ref LL_CKGA_PERIPH_CPU + * @arg @ref LL_CKGA_PERIPH_GPU2DS0 (*) + * @arg @ref LL_CKGA_PERIPH_GPU2DS1 (*) + * @arg @ref LL_CKGA_PERIPH_GPU2DCL (*) + * @arg @ref LL_CKGA_PERIPH_DMA2D + * @arg @ref LL_CKGA_PERIPH_DCMIPP + * @arg @ref LL_CKGA_PERIPH_LTDC (*) + * @arg @ref LL_CKGA_PERIPH_FLASH + * @arg @ref LL_CKGA_PERIPH_XSPI2 + * @arg @ref LL_CKGA_PERIPH_XSPI1 + * @arg @ref LL_CKGA_PERIPH_FMC + * @arg @ref LL_CKGA_PERIPH_AXIRAM1 + * @arg @ref LL_CKGA_PERIPH_AXIRAM2 + * @arg @ref LL_CKGA_PERIPH_AXIRAM3 + * @arg @ref LL_CKGA_PERIPH_AXIRAM4 + * @arg @ref LL_CKGA_PERIPH_GFXMMUM + * @arg @ref LL_CKGA_PERIPH_GFXMMUS + * @arg @ref LL_CKGA_PERIPH_EXTI + * @arg @ref LL_CKGA_PERIPH_JTAG + * + * (*) value not defined in all devices. + * @retval uint32_t + */ +__STATIC_INLINE uint32_t LL_CKGA_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->CKGDISR, Periphs) == 0U) ? 1U : 0U); +} + +/** + * @brief Disable clock gating for AXI bus peripherals. + * @rmtoll CKGDISR AXICKG LL_CKGA_Disable\n + * CKGDISR AHBMCKG LL_CKGA_Disable\n + * CKGDISR SDMMC1CKG LL_CKGA_Disable\n + * CKGDISR HPDMA1CKG LL_CKGA_Disable\n + * CKGDISR CPUCKG LL_CKGA_Disable\n + * CKGDISR GPU2DS0CKG LL_CKGA_Disable\n + * CKGDISR GPU2DS1CKG LL_CKGA_Disable\n + * CKGDISR GPUCLCKG LL_CKGA_Disable\n + * CKGDISR DCMIPPCKG LL_CKGA_Disable\n + * CKGDISR DMA2DCKG LL_CKGA_Disable\n + * CKGDISR GFXMMUSCKG LL_CKGA_Disable\n + * CKGDISR LTDCCKG LL_CKGA_Disable\n + * CKGDISR GFXMMUMCKG LL_CKGA_Disable\n + * CKGDISR AHBSCKG LL_CKGA_Disable\n + * CKGDISR FMCCKG LL_CKGA_Disable\n + * CKGDISR XSPI2CKG LL_CKGA_Disable\n + * CKGDISR XSPI1CKG LL_CKGA_Disable\n + * CKGDISR AXIRAM1CKG LL_CKGA_Disable\n + * CKGDISR AXIRAM2CKG LL_CKGA_Disable\n + * CKGDISR AXIRAM3CKG LL_CKGA_Disable\n + * CKGDISR AXIRAM4CKG LL_CKGA_Disable\n + * CKGDISR FLASHCKG LL_CKGA_Disable\n + * CKGDISR EXTICKG LL_CKGA_Disable\n + * CKGDISR JTAGCKG LL_CKGA_Disable + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_CKGA_PERIPH_AXI + * @arg @ref LL_CKGA_PERIPH_AHBM + * @arg @ref LL_CKGA_PERIPH_AHBS + * @arg @ref LL_CKGA_PERIPH_SDMMC1 + * @arg @ref LL_CKGA_PERIPH_HPDMA1 + * @arg @ref LL_CKGA_PERIPH_CPU + * @arg @ref LL_CKGA_PERIPH_GPU2DS0 + * @arg @ref LL_CKGA_PERIPH_GPU2DS1 + * @arg @ref LL_CKGA_PERIPH_GPU2DCL + * @arg @ref LL_CKGA_PERIPH_DMA2D + * @arg @ref LL_CKGA_PERIPH_DCMIPP + * @arg @ref LL_CKGA_PERIPH_LTDC + * @arg @ref LL_CKGA_PERIPH_FLASH + * @arg @ref LL_CKGA_PERIPH_XSPI2 + * @arg @ref LL_CKGA_PERIPH_XSPI1 + * @arg @ref LL_CKGA_PERIPH_FMC + * @arg @ref LL_CKGA_PERIPH_AXIRAM1 + * @arg @ref LL_CKGA_PERIPH_AXIRAM2 + * @arg @ref LL_CKGA_PERIPH_AXIRAM3 + * @arg @ref LL_CKGA_PERIPH_AXIRAM4 + * @arg @ref LL_CKGA_PERIPH_GFXMMUM + * @arg @ref LL_CKGA_PERIPH_GFXMMUS + * @arg @ref LL_CKGA_PERIPH_EXTI + * @arg @ref LL_CKGA_PERIPH_JTAG + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_CKGA_Disable(uint32_t Periphs) +{ + SET_BIT(RCC->CKGDISR, Periphs); +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(RCC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_BUS_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_cortex.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_cortex.h new file mode 100644 index 0000000..7db4eff --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_cortex.h @@ -0,0 +1,714 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX LL 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. + * + ****************************************************************************** + @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 + (+) API to configure the region of MPU + (+) API to configure the attributes region of MPU + + @endverbatim + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7RSxx_LL_CORTEX_H +#define STM32H7RSxx_LL_CORTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +/** @defgroup CORTEX_LL CORTEX + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CORTEX_LL_Exported_Constants CORTEX LL Exported Constants + * @{ + */ + +/** @defgroup CORTEX_LL_EC_CLKSOURCE_HCLK CORTEX LL SYSTICK Clock Source + * @{ + */ +#define LL_SYSTICK_CLKSOURCE_HCLK_DIV8 0U /*!< 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 CORTEX LL 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 */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_CTRL_HFNMI_PRIVDEF CORTEX LL MPU HFNMI and PRIVILEGED Access control + * @{ + */ +#define LL_MPU_CTRL_HFNMI_PRIVDEF_NONE 0U /*!< Disable NMI and privileged SW access */ +#define LL_MPU_CTRL_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk /*!< Enables the operation of MPU during hard fault, NMI, and FAULTMASK handlers */ +#define LL_MPU_CTRL_PRIVILEGED_DEFAULT MPU_CTRL_PRIVDEFENA_Msk /*!< Enable privileged software access to default memory map */ +#define LL_MPU_CTRL_HFNMI_PRIVDEF (MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk) /*!< Enable NMI and privileged SW access */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_REGION CORTEX LL MPU Region Number + * @{ + */ +#define LL_MPU_REGION_NUMBER0 0U /*!< REGION Number 0 */ +#define LL_MPU_REGION_NUMBER1 1U /*!< REGION Number 1 */ +#define LL_MPU_REGION_NUMBER2 2U /*!< REGION Number 2 */ +#define LL_MPU_REGION_NUMBER3 3U /*!< REGION Number 3 */ +#define LL_MPU_REGION_NUMBER4 4U /*!< REGION Number 4 */ +#define LL_MPU_REGION_NUMBER5 5U /*!< REGION Number 5 */ +#define LL_MPU_REGION_NUMBER6 6U /*!< REGION Number 6 */ +#define LL_MPU_REGION_NUMBER7 7U /*!< REGION Number 7 */ +#define LL_MPU_REGION_NUMBER8 8U /*!< REGION Number 8 */ +#define LL_MPU_REGION_NUMBER9 9U /*!< REGION Number 9 */ +#define LL_MPU_REGION_NUMBER10 10U /*!< REGION Number 10 */ +#define LL_MPU_REGION_NUMBER11 11U /*!< REGION Number 11 */ +#define LL_MPU_REGION_NUMBER12 12U /*!< REGION Number 12 */ +#define LL_MPU_REGION_NUMBER13 13U /*!< REGION Number 13 */ +#define LL_MPU_REGION_NUMBER14 14U /*!< REGION Number 14 */ +#define LL_MPU_REGION_NUMBER15 15U /*!< REGION Number 15 */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_REGION_SIZE CORTEX LL MPU Region Size + * @{ + */ +#define LL_MPU_REGION_SIZE_32B (0x04UL << MPU_RASR_SIZE_Pos) /*!< 32B Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_64B (0x05UL << MPU_RASR_SIZE_Pos) /*!< 64B Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_128B (0x06UL << MPU_RASR_SIZE_Pos) /*!< 128B Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_256B (0x07UL << MPU_RASR_SIZE_Pos) /*!< 256B Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_512B (0x08UL << MPU_RASR_SIZE_Pos) /*!< 512B Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_1KB (0x09UL << MPU_RASR_SIZE_Pos) /*!< 1KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_2KB (0x0AUL << MPU_RASR_SIZE_Pos) /*!< 2KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_4KB (0x0BUL << MPU_RASR_SIZE_Pos) /*!< 4KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_8KB (0x0CUL << MPU_RASR_SIZE_Pos) /*!< 8KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_16KB (0x0DUL << MPU_RASR_SIZE_Pos) /*!< 16KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_32KB (0x0EUL << MPU_RASR_SIZE_Pos) /*!< 32KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_64KB (0x0FUL << MPU_RASR_SIZE_Pos) /*!< 64KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_128KB (0x10UL << MPU_RASR_SIZE_Pos) /*!< 128KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_256KB (0x11UL << MPU_RASR_SIZE_Pos) /*!< 256KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_512KB (0x12UL << MPU_RASR_SIZE_Pos) /*!< 512KB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_1MB (0x13UL << MPU_RASR_SIZE_Pos) /*!< 1MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_2MB (0x14UL << MPU_RASR_SIZE_Pos) /*!< 2MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_4MB (0x15UL << MPU_RASR_SIZE_Pos) /*!< 4MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_8MB (0x16UL << MPU_RASR_SIZE_Pos) /*!< 8MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_16MB (0x17UL << MPU_RASR_SIZE_Pos) /*!< 16MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_32MB (0x18UL << MPU_RASR_SIZE_Pos) /*!< 32MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_64MB (0x19UL << MPU_RASR_SIZE_Pos) /*!< 64MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_128MB (0x1AUL << MPU_RASR_SIZE_Pos) /*!< 128MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_256MB (0x1BUL << MPU_RASR_SIZE_Pos) /*!< 256MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_512MB (0x1CUL << MPU_RASR_SIZE_Pos) /*!< 512MB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_1GB (0x1DUL << MPU_RASR_SIZE_Pos) /*!< 1GB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_2GB (0x1EUL << MPU_RASR_SIZE_Pos) /*!< 2GB Size of the MPU protection region */ +#define LL_MPU_REGION_SIZE_4GB (0x1FUL << MPU_RASR_SIZE_Pos) /*!< 4GB Size of the MPU protection region */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_REGION_PRIVILEDGES CORTEX LL MPU Region Privileges + * @{ + */ +#define LL_MPU_REGION_NO_ACCESS (0U << MPU_RASR_AP_Pos) /*!< No access*/ +#define LL_MPU_REGION_PRIV_RW (1U << MPU_RASR_AP_Pos) /*!< RW privileged (privileged access only)*/ +#define LL_MPU_REGION_PRIV_RW_URO (2U << MPU_RASR_AP_Pos) /*!< RW privileged - RO user (Write in a user program generates a fault) */ +#define LL_MPU_REGION_FULL_ACCESS (3U << MPU_RASR_AP_Pos) /*!< RW privileged & user (Full access) */ +#define LL_MPU_REGION_PRIV_RO (5U << MPU_RASR_AP_Pos) /*!< RO privileged (privileged read only)*/ +#define LL_MPU_REGION_PRIV_RO_URO (6U << MPU_RASR_AP_Pos) /*!< RO privileged & user (read only) */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_TEX CORTEX LL MPU TEX Level + * @{ + */ +#define LL_MPU_TEX_LEVEL0 (0U << MPU_RASR_TEX_Pos) /*!< b000 for TEX bits */ +#define LL_MPU_TEX_LEVEL1 (1U << MPU_RASR_TEX_Pos) /*!< b001 for TEX bits */ +#define LL_MPU_TEX_LEVEL2 (2U << MPU_RASR_TEX_Pos) /*!< b010 for TEX bits */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_INSTRUCTION_ACCESS CORTEX LL MPU Instruction Access + * @{ + */ +#define LL_MPU_INSTRUCTION_ACCESS_ENABLE 0U /*!< Instruction fetches enabled */ +#define LL_MPU_INSTRUCTION_ACCESS_DISABLE MPU_RASR_XN_Msk /*!< Instruction fetches disabled*/ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_SHAREABLE_ACCESS CORTEX LL MPU Shareable Access + * @{ + */ +#define LL_MPU_ACCESS_SHAREABLE MPU_RASR_S_Msk /*!< Shareable memory attribute */ +#define LL_MPU_ACCESS_NOT_SHAREABLE 0U /*!< Not Shareable memory attribute */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_CACHEABLE_ACCESS CORTEX LL MPU Cacheable Access + * @{ + */ +#define LL_MPU_ACCESS_CACHEABLE MPU_RASR_C_Msk /*!< Cacheable memory attribute */ +#define LL_MPU_ACCESS_NOT_CACHEABLE 0U /*!< Not Cacheable memory attribute */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_BUFFERABLE_ACCESS CORTEX LL MPU Bufferable Access + * @{ + */ +#define LL_MPU_ACCESS_BUFFERABLE MPU_RASR_B_Msk /*!< Bufferable memory attribute */ +#define LL_MPU_ACCESS_NOT_BUFFERABLE 0U /*!< Not Bufferable memory attribute */ +/** + * @} + */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CORTEX_LL_Exported_Functions CORTEX LL Exported Functions + * @{ + */ + +/** @defgroup CORTEX_LL_EF_SYSTICK CORTEX LL 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) +{ + MODIFY_REG(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK, Source); +} + +/** + * @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, 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, 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, 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, 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, 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, SCB_SCR_SEVONPEND_Msk); +} + +/** + * @brief Clear pending events. + * @retval None + */ +__STATIC_INLINE void LL_LPM_ClearEvent(void) +{ + __SEV(); + __WFE(); +} +/** + * @} + */ + +/** @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 + * @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 + * @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 + * @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 + * @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-M7 + */ +__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 0xC27 for Cortex-M7 + */ +__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(); /* Force any outstanding transfers to complete before enabling MPU */ + + /* Enable the MPU*/ + WRITE_REG(MPU->CTRL, (MPU_Control | MPU_CTRL_ENABLE_Msk)); + + /* Ensure MPU settings take effects */ + __DSB(); + __ISB(); +} + +/** + * @brief Disable MPU + * @rmtoll MPU_CTRL ENABLE LL_MPU_Disable + * @retval None + */ +__STATIC_INLINE void LL_MPU_Disable(void) +{ + /* Make sure outstanding transfers are done */ + __DMB(); + + /* Disable the MPU and clear the control register */ + WRITE_REG(MPU->CTRL, 0U); +} + +/** + * @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); +} + +/** + * @brief Enable a MPU region + * @rmtoll MPU_RASR 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 + * @arg @ref LL_MPU_REGION_NUMBER12 + * @arg @ref LL_MPU_REGION_NUMBER13 + * @arg @ref LL_MPU_REGION_NUMBER14 + * @arg @ref LL_MPU_REGION_NUMBER15 + * @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->RASR, MPU_RASR_ENABLE_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 + * @arg @ref LL_MPU_REGION_NUMBER12 + * @arg @ref LL_MPU_REGION_NUMBER13 + * @arg @ref LL_MPU_REGION_NUMBER14 + * @arg @ref LL_MPU_REGION_NUMBER15 + * @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->RASR, MPU_RASR_ENABLE_Msk) == (MPU_RASR_ENABLE_Msk)) ? 1UL : 0UL); +} + +/** + * @brief Configure and enable a MPU region + * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegion\n + * MPU_RBAR REGION LL_MPU_ConfigRegion\n + * MPU_RBAR ADDR LL_MPU_ConfigRegion\n + * MPU_RASR XN LL_MPU_ConfigRegion\n + * MPU_RASR AP LL_MPU_ConfigRegion\n + * MPU_RASR S LL_MPU_ConfigRegion\n + * MPU_RASR C LL_MPU_ConfigRegion\n + * MPU_RASR B LL_MPU_ConfigRegion\n + * MPU_RASR SIZE LL_MPU_ConfigRegion + * @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 + * @arg @ref LL_MPU_REGION_NUMBER12 + * @arg @ref LL_MPU_REGION_NUMBER13 + * @arg @ref LL_MPU_REGION_NUMBER14 + * @arg @ref LL_MPU_REGION_NUMBER15 + * @param Address Value of region base address + * @param SubRegionDisable Sub-region disable value between Min_Data = 0x00 and Max_Data = 0xFF + * @param Attributes This parameter can be a combination of the following values: + * @arg @ref LL_MPU_REGION_SIZE_32B or @ref LL_MPU_REGION_SIZE_64B or @ref LL_MPU_REGION_SIZE_128B + * or @ref LL_MPU_REGION_SIZE_256B or @ref LL_MPU_REGION_SIZE_512B + * or @ref LL_MPU_REGION_SIZE_1KB or @ref LL_MPU_REGION_SIZE_2KB or @ref LL_MPU_REGION_SIZE_4KB + * or @ref LL_MPU_REGION_SIZE_8KB or @ref LL_MPU_REGION_SIZE_16KB + * or @ref LL_MPU_REGION_SIZE_32KB or @ref LL_MPU_REGION_SIZE_64KB or @ref LL_MPU_REGION_SIZE_128KB + * or @ref LL_MPU_REGION_SIZE_256KB or @ref LL_MPU_REGION_SIZE_512KB + * or @ref LL_MPU_REGION_SIZE_1MB or @ref LL_MPU_REGION_SIZE_2MB or @ref LL_MPU_REGION_SIZE_4MB + * or @ref LL_MPU_REGION_SIZE_8MB or @ref LL_MPU_REGION_SIZE_16MB + * or @ref LL_MPU_REGION_SIZE_32MB or @ref LL_MPU_REGION_SIZE_64MB or @ref LL_MPU_REGION_SIZE_128MB + * or @ref LL_MPU_REGION_SIZE_256MB or @ref LL_MPU_REGION_SIZE_512MB + * or @ref LL_MPU_REGION_SIZE_1GB or @ref LL_MPU_REGION_SIZE_2GB or @ref LL_MPU_REGION_SIZE_4GB + * @arg @ref LL_MPU_REGION_NO_ACCESS or @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_PRIV_RW_URO + * or @ref LL_MPU_REGION_FULL_ACCESS or @ref LL_MPU_REGION_PRIV_RO or @ref LL_MPU_REGION_PRIV_RO_URO + * @arg @ref LL_MPU_TEX_LEVEL0 or @ref LL_MPU_TEX_LEVEL1 or @ref LL_MPU_TEX_LEVEL2 + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_SHAREABLE or @ref LL_MPU_ACCESS_NOT_SHAREABLE + * @arg @ref LL_MPU_ACCESS_CACHEABLE or @ref LL_MPU_ACCESS_NOT_CACHEABLE + * @arg @ref LL_MPU_ACCESS_BUFFERABLE or @ref LL_MPU_ACCESS_NOT_BUFFERABLE + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigRegion(uint32_t Region, uint32_t SubRegionDisable, uint32_t Address, + uint32_t Attributes) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + + /* Set base address */ + WRITE_REG(MPU->RBAR, (Address & 0xFFFFFFE0U)); + + /* Configure MPU */ + WRITE_REG(MPU->RASR, (MPU_RASR_ENABLE_Msk | Attributes | (SubRegionDisable << MPU_RASR_SRD_Pos))); +} + +/** + * @brief Disable a MPU region + * @rmtoll MPU_RNR REGION LL_MPU_DisableRegion\n + * MPU_RASR 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 + * @arg @ref LL_MPU_REGION_NUMBER12 + * @arg @ref LL_MPU_REGION_NUMBER13 + * @arg @ref LL_MPU_REGION_NUMBER14 + * @arg @ref LL_MPU_REGION_NUMBER15 + * @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->RASR, MPU_RASR_ENABLE_Msk); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_CORTEX_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crc.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crc.h new file mode 100644 index 0000000..732c98e --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crc.h @@ -0,0 +1,461 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_crc.h + * @author MCD Application Team + * @brief Header file of CRC LL 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 STM32H7RSxx_LL_CRC_H +#define STM32H7RSxx_LL_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_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 /* STM32H7RSxx_LL_CRC_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crs.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crs.h new file mode 100644 index 0000000..6e4deb3 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_crs.h @@ -0,0 +1,786 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_crs.h + * @author MCD Application Team + * @brief Header file of CRS LL 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 STM32H7RSxx_LL_CRS_H +#define STM32H7RSxx_LL_CRS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +#if defined(CRS) + +/** @defgroup CRS_LL CRS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* 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_OTG_FS CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source OTG_FS SOF (default) */ +#define LL_CRS_SYNC_SOURCE_OTG_HS (CRS_CFGR_SYNCSRC_1 | CRS_CFGR_SYNCSRC_0) /*!< Synchro Signal source OTG_HS SOF */ +/** + * @} + */ + +/** @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_CR_TRIM_Pos); +} + +/** + * @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_CR_TRIM_Pos); +} + +/** + * @brief Set counter reload value + * @rmtoll CFGR RELOAD LL_CRS_SetReloadCounter + * @param Value a number between Min_Data = 0 and Max_Data = 65535 (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 = 65535 (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_CFGR_FELIM_Pos); +} + +/** + * @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_CFGR_FELIM_Pos); +} + +/** + * @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_OTG_FS + * @arg @ref LL_CRS_SYNC_SOURCE_OTG_HS + * @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_OTG_FS + * @arg @ref LL_CRS_SYNC_SOURCE_OTG_HS + */ +__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 = 255 + * @param ReloadValue a number between Min_Data = 0 and Max_Data = 65535 (0xFFFF) + * @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_OTG_FS or @ref LL_CRS_SYNC_SOURCE_OTG_HS + * @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 << CRS_CR_TRIM_Pos); + MODIFY_REG(CRS->CFGR, + CRS_CFGR_RELOAD | CRS_CFGR_FELIM | CRS_CFGR_SYNCDIV | CRS_CFGR_SYNCSRC | CRS_CFGR_SYNCPOL, + ReloadValue | (ErrorLimitValue << CRS_CFGR_FELIM_Pos) | 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_ISR_FECAP_Pos); +} + +/** + * @} + */ + +/** @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 /* STM32H7RSxx_LL_CRS_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma.h new file mode 100644 index 0000000..559dc8f --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma.h @@ -0,0 +1,6677 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_dma.h + * @author MCD Application Team + * @brief Header file of DMA LL 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. + * + ****************************************************************************** + @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 STM32H7RSxx_LL_DMA_H +#define STM32H7RSxx_LL_DMA_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +#if (defined (GPDMA1) || defined (HPDMA1)) + +/** @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) +#define DMA_CHANNEL8_OFFSET (0x00000450UL) +#define DMA_CHANNEL9_OFFSET (0x000004D0UL) +#define DMA_CHANNEL10_OFFSET (0x00000550UL) +#define DMA_CHANNEL11_OFFSET (0x000005D0UL) +#define DMA_CHANNEL12_OFFSET (0x00000650UL) +#define DMA_CHANNEL13_OFFSET (0x000006D0UL) +#define DMA_CHANNEL14_OFFSET (0x00000750UL) +#define DMA_CHANNEL15_OFFSET (0x000007D0UL) + +/* 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, + DMA_CHANNEL8_OFFSET, DMA_CHANNEL9_OFFSET, DMA_CHANNEL10_OFFSET, DMA_CHANNEL11_OFFSET, + DMA_CHANNEL12_OFFSET, DMA_CHANNEL13_OFFSET, DMA_CHANNEL14_OFFSET, DMA_CHANNEL15_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 DestWordExchange; /*!< This field specify the destination word exchange. + Programming this field is mandatory for all available HPDMA channels. + This parameter can be a value of @ref DMA_LL_EC_DEST_WORD_EXCHANGE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestWordExchange(). */ + + 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. + + */ + 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 DestWordExchange; /*!< This field specify the destination word exchange. + This parameter can be a value of @ref DMA_LL_EC_DEST_WORD_EXCHANGE. */ + + 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. */ + + 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_LL_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 & HPDMA linear addressing channels, the maximum node size is : + * (4 Bytes * 6 registers = 24 Bytes). + */ +typedef struct +{ + __IO uint32_t LinkRegisters[8U]; + +} LL_DMA_LinkNodeTypeDef; +/** + * @} + */ + +#endif /* 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 /* 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 /* 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_WORD_EXCHANGE Destination Word Exchange + * @{ + */ +#define LL_DMA_DEST_WORD_PRESERVE 0x00000000U /*!< No destination Word exchange when destination data width + is double-word */ +#define LL_DMA_DEST_WORD_EXCHANGE DMA_CTR1_DWX /*!< Destination Word exchange when destination data width + is double-word */ +/** + * @} + */ + +/** @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 */ +#define LL_DMA_DEST_DATAWIDTH_DOUBLEWORD DMA_CTR1_DDW_LOG2 /*!< Destination Data Width : DoubleWord */ +/** + * @} + */ + +/** @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 */ +#define LL_DMA_SRC_DATAWIDTH_DOUBLEWORD DMA_CTR1_SDW_LOG2 /*!< Source Data Width : DoubleWord */ +/** + * @} + */ + +/** @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 */ +/** + * @} + */ + +/** @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 */ +#define LL_DMA_HPDMA_LINEAR_NODE 0x04U /*!< HPDMA node : linear addressing node */ +#define LL_DMA_HPDMA_2D_NODE 0x08U /*!< HPDMA 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 + * @{ + */ +/* HPDMA1 requests */ +#define LL_HPDMA1_REQUEST_JPEG_RX 0U /*!< HPDMA1 HW request is JPEG_RX */ +#define LL_HPDMA1_REQUEST_JPEG_TX 1U /*!< HPDMA1 HW request is JPEG_TX */ +#define LL_HPDMA1_REQUEST_XSPI1 2U /*!< HPDMA1 HW request is XSPI1 */ +#define LL_HPDMA1_REQUEST_XSPI2 3U /*!< HPDMA1 HW request is XSPI2 */ +#define LL_HPDMA1_REQUEST_SPI3_RX 4U /*!< HPDMA1 HW request is SPI3_RX */ +#define LL_HPDMA1_REQUEST_SPI3_TX 5U /*!< HPDMA1 HW request is SPI3_TX */ +#define LL_HPDMA1_REQUEST_SPI4_RX 6U /*!< HPDMA1 HW request is SPI4_RX */ +#define LL_HPDMA1_REQUEST_SPI4_TX 7U /*!< HPDMA1 HW request is SPI4_TX */ +#define LL_HPDMA1_REQUEST_ADC1 8U /*!< HPDMA1 HW request is ADC1 */ +#define LL_HPDMA1_REQUEST_ADC2 9U /*!< HPDMA1 HW request is ADC2 */ +#define LL_HPDMA1_REQUEST_ADF1_FLT0 10U /*!< HPDMA1 HW request is ADF1_FLT0 */ +#define LL_HPDMA1_REQUEST_UART4_RX 11U /*!< HPDMA1 HW request is UART4_RX */ +#define LL_HPDMA1_REQUEST_UART4_TX 12U /*!< HPDMA1 HW request is UART4_TX */ +#define LL_HPDMA1_REQUEST_UART5_RX 13U /*!< HPDMA1 HW request is UART5_RX */ +#define LL_HPDMA1_REQUEST_UART5_TX 14U /*!< HPDMA1 HW request is UART5_TX */ +#define LL_HPDMA1_REQUEST_UART7_RX 15U /*!< HPDMA1 HW request is UART7_RX */ +#define LL_HPDMA1_REQUEST_UART7_TX 16U /*!< HPDMA1 HW request is UART7_TX */ +#define LL_HPDMA1_REQUEST_LPTIM2_IC1 17U /*!< HPDMA1 HW request is LPTIM2_IC1 */ +#define LL_HPDMA1_REQUEST_LPTIM2_IC2 18U /*!< HPDMA1 HW request is LPTIM2_IC2 */ +#define LL_HPDMA1_REQUEST_LPTIM2_UE 19U /*!< HPDMA1 HW request is LPTIM2_UE */ + +/* GPDMA1 requests */ +#define LL_GPDMA1_REQUEST_ADC1 0U /*!< GPDMA1 HW request is ADC1 */ +#define LL_GPDMA1_REQUEST_ADC2 1U /*!< GPDMA1 HW request is ADC2 */ +#define LL_GPDMA1_REQUEST_CRYP_IN 2U /*!< GPDMA1 HW request is CRYP_IN */ +#define LL_GPDMA1_REQUEST_CRYP_OUT 3U /*!< GPDMA1 HW request is CRYP_OUT */ +#define LL_GPDMA1_REQUEST_SAES_IN 4U /*!< GPDMA1 HW request is SAES_IN */ +#define LL_GPDMA1_REQUEST_SAES_OUT 5U /*!< GPDMA1 HW request is SAES_OUT */ +#define LL_GPDMA1_REQUEST_HASH_IN 6U /*!< GPDMA1 HW request is HASH_IN */ +#define LL_GPDMA1_REQUEST_TIM1_CH1 7U /*!< GPDMA1 HW request is TIM1_CH1 */ +#define LL_GPDMA1_REQUEST_TIM1_CH2 8U /*!< GPDMA1 HW request is TIM1_CH2 */ +#define LL_GPDMA1_REQUEST_TIM1_CH3 9U /*!< GPDMA1 HW request is TIM1_CH3 */ +#define LL_GPDMA1_REQUEST_TIM1_CH4 10U /*!< GPDMA1 HW request is TIM1_CH4 */ +#define LL_GPDMA1_REQUEST_TIM1_UP 11U /*!< GPDMA1 HW request is TIM1_UP */ +#define LL_GPDMA1_REQUEST_TIM1_TRIG 12U /*!< GPDMA1 HW request is TIM1_TRIG */ +#define LL_GPDMA1_REQUEST_TIM1_COM 13U /*!< GPDMA1 HW request is TIM1_COM */ +#define LL_GPDMA1_REQUEST_TIM2_CH1 14U /*!< GPDMA1 HW request is TIM2_CH1 */ +#define LL_GPDMA1_REQUEST_TIM2_CH2 15U /*!< GPDMA1 HW request is TIM2_CH2 */ +#define LL_GPDMA1_REQUEST_TIM2_CH3 16U /*!< GPDMA1 HW request is TIM2_CH3 */ +#define LL_GPDMA1_REQUEST_TIM2_CH4 17U /*!< GPDMA1 HW request is TIM2_CH4 */ +#define LL_GPDMA1_REQUEST_TIM2_UP 18U /*!< GPDMA1 HW request is TIM2_UP */ +#define LL_GPDMA1_REQUEST_TIM2_TRIG 19U /*!< GPDMA1 HW request is TIM2_TRIG */ +#define LL_GPDMA1_REQUEST_TIM3_CH1 20U /*!< GPDMA1 HW request is TIM3_CH1 */ +#define LL_GPDMA1_REQUEST_TIM3_CH2 21U /*!< GPDMA1 HW request is TIM3_CH2 */ +#define LL_GPDMA1_REQUEST_TIM3_CH3 22U /*!< GPDMA1 HW request is TIM3_CH3 */ +#define LL_GPDMA1_REQUEST_TIM3_CH4 23U /*!< GPDMA1 HW request is TIM3_CH4 */ +#define LL_GPDMA1_REQUEST_TIM3_UP 24U /*!< GPDMA1 HW request is TIM3_UP */ +#define LL_GPDMA1_REQUEST_TIM3_TRIG 25U /*!< GPDMA1 HW request is TIM3_TRIG */ +#define LL_GPDMA1_REQUEST_TIM4_CH1 26U /*!< GPDMA1 HW request is TIM4_CH1 */ +#define LL_GPDMA1_REQUEST_TIM4_CH2 27U /*!< GPDMA1 HW request is TIM4_CH2 */ +#define LL_GPDMA1_REQUEST_TIM4_CH3 28U /*!< GPDMA1 HW request is TIM4_CH3 */ +#define LL_GPDMA1_REQUEST_TIM4_CH4 29U /*!< GPDMA1 HW request is TIM4_CH4 */ +#define LL_GPDMA1_REQUEST_TIM4_UP 30U /*!< GPDMA1 HW request is TIM4_UP */ +#define LL_GPDMA1_REQUEST_TIM4_TRIG 31U /*!< GPDMA1 HW request is TIM4_TRIG */ +#define LL_GPDMA1_REQUEST_TIM5_CH1 32U /*!< GPDMA1 HW request is TIM5_CH1 */ +#define LL_GPDMA1_REQUEST_TIM5_CH2 33U /*!< GPDMA1 HW request is TIM5_CH2 */ +#define LL_GPDMA1_REQUEST_TIM5_CH3 34U /*!< GPDMA1 HW request is TIM5_CH3 */ +#define LL_GPDMA1_REQUEST_TIM5_CH4 35U /*!< GPDMA1 HW request is TIM5_CH4 */ +#define LL_GPDMA1_REQUEST_TIM5_UP 36U /*!< GPDMA1 HW request is TIM5_UP */ +#define LL_GPDMA1_REQUEST_TIM5_TRIG 37U /*!< GPDMA1 HW request is TIM5_TRIG */ +#define LL_GPDMA1_REQUEST_TIM6_UP 38U /*!< GPDMA1 HW request is TIM6_UP */ +#define LL_GPDMA1_REQUEST_TIM7_UP 39U /*!< GPDMA1 HW request is TIM7_UP */ +#define LL_GPDMA1_REQUEST_TIM15_CH1 40U /*!< GPDMA1 HW request is TIM15_CH1 */ +#define LL_GPDMA1_REQUEST_TIM15_CH2 41U /*!< GPDMA1 HW request is TIM15_CH2 */ +#define LL_GPDMA1_REQUEST_TIM15_UP 42U /*!< GPDMA1 HW request is TIM15_UP */ +#define LL_GPDMA1_REQUEST_TIM15_TRIG 43U /*!< GPDMA1 HW request is TIM15_TRIG */ +#define LL_GPDMA1_REQUEST_TIM15_COM 44U /*!< GPDMA1 HW request is TIM15_COM */ +#define LL_GPDMA1_REQUEST_TIM16_CH1 45U /*!< GPDMA1 HW request is TIM16_CH1 */ +#define LL_GPDMA1_REQUEST_TIM16_UP 46U /*!< GPDMA1 HW request is TIM16_UP */ +#define LL_GPDMA1_REQUEST_TIM16_COM 47U /*!< GPDMA1 HW request is TIM16_COM */ +#define LL_GPDMA1_REQUEST_TIM17_CH1 48U /*!< GPDMA1 HW request is TIM17_CH1 */ +#define LL_GPDMA1_REQUEST_TIM17_UP 49U /*!< GPDMA1 HW request is TIM17_UP */ +#define LL_GPDMA1_REQUEST_TIM17_COM 50U /*!< GPDMA1 HW request is TIM17_COM */ +#define LL_GPDMA1_REQUEST_SPI1_RX 51U /*!< GPDMA1 HW request is SPI1_RX */ +#define LL_GPDMA1_REQUEST_SPI1_TX 52U /*!< GPDMA1 HW request is SPI1_TX */ +#define LL_GPDMA1_REQUEST_SPI2_RX 53U /*!< GPDMA1 HW request is SPI2_RX */ +#define LL_GPDMA1_REQUEST_SPI2_TX 54U /*!< GPDMA1 HW request is SPI2_TX */ +#define LL_GPDMA1_REQUEST_SPI3_RX 55U /*!< GPDMA1 HW request is SPI3_RX */ +#define LL_GPDMA1_REQUEST_SPI3_TX 56U /*!< GPDMA1 HW request is SPI3_TX */ +#define LL_GPDMA1_REQUEST_SPI4_RX 57U /*!< GPDMA1 HW request is SPI4_RX */ +#define LL_GPDMA1_REQUEST_SPI4_TX 58U /*!< GPDMA1 HW request is SPI4_TX */ +#define LL_GPDMA1_REQUEST_SPI5_RX 59U /*!< GPDMA1 HW request is SPI5_RX */ +#define LL_GPDMA1_REQUEST_SPI5_TX 60U /*!< GPDMA1 HW request is SPI5_TX */ +#define LL_GPDMA1_REQUEST_SPI6_RX 61U /*!< GPDMA1 HW request is SPI6_RX */ +#define LL_GPDMA1_REQUEST_SPI6_TX 62U /*!< GPDMA1 HW request is SPI6_TX */ +#define LL_GPDMA1_REQUEST_SAI1_A 63U /*!< GPDMA1 HW request is SAI1_A */ +#define LL_GPDMA1_REQUEST_SAI1_B 64U /*!< GPDMA1 HW request is SAI1_B */ +#define LL_GPDMA1_REQUEST_SAI2_A 65U /*!< GPDMA1 HW request is SAI2_A */ +#define LL_GPDMA1_REQUEST_SAI2_B 66U /*!< GPDMA1 HW request is SAI2_B */ +#define LL_GPDMA1_REQUEST_I2C1_RX 67U /*!< GPDMA1 HW request is I2C1_RX */ +#define LL_GPDMA1_REQUEST_I2C1_TX 68U /*!< GPDMA1 HW request is I2C1_TX */ +#define LL_GPDMA1_REQUEST_I2C2_RX 69U /*!< GPDMA1 HW request is I2C2_RX */ +#define LL_GPDMA1_REQUEST_I2C2_TX 70U /*!< GPDMA1 HW request is I2C2_TX */ +#define LL_GPDMA1_REQUEST_I2C3_RX 71U /*!< GPDMA1 HW request is I2C3_RX */ +#define LL_GPDMA1_REQUEST_I2C3_TX 72U /*!< GPDMA1 HW request is I2C3_TX */ +#define LL_GPDMA1_REQUEST_USART1_RX 73U /*!< GPDMA1 HW request is USART1_RX */ +#define LL_GPDMA1_REQUEST_USART1_TX 74U /*!< GPDMA1 HW request is USART1_TX */ +#define LL_GPDMA1_REQUEST_USART2_RX 75U /*!< GPDMA1 HW request is USART2_RX */ +#define LL_GPDMA1_REQUEST_USART2_TX 76U /*!< GPDMA1 HW request is USART2_TX */ +#define LL_GPDMA1_REQUEST_USART3_RX 77U /*!< GPDMA1 HW request is USART3_RX */ +#define LL_GPDMA1_REQUEST_USART3_TX 78U /*!< GPDMA1 HW request is USART3_TX */ +#define LL_GPDMA1_REQUEST_UART4_RX 79U /*!< GPDMA1 HW request is UART4_RX */ +#define LL_GPDMA1_REQUEST_UART4_TX 80U /*!< GPDMA1 HW request is UART4_TX */ +#define LL_GPDMA1_REQUEST_UART5_RX 81U /*!< GPDMA1 HW request is UART5_RX */ +#define LL_GPDMA1_REQUEST_UART5_TX 82U /*!< GPDMA1 HW request is UART5_TX */ +#define LL_GPDMA1_REQUEST_UART7_RX 83U /*!< GPDMA1 HW request is UART7_RX */ +#define LL_GPDMA1_REQUEST_UART7_TX 84U /*!< GPDMA1 HW request is UART7_TX */ +#define LL_GPDMA1_REQUEST_UART8_RX 85U /*!< GPDMA1 HW request is UART8_RX */ +#define LL_GPDMA1_REQUEST_UART8_TX 86U /*!< GPDMA1 HW request is UART8_TX */ +#define LL_GPDMA1_REQUEST_CORDIC_READ 87U /*!< GPDMA1 HW request is CORDIC_READ */ +#define LL_GPDMA1_REQUEST_CORDIC_WRITE 88U /*!< GPDMA1 HW request is CORDIC_WRITE */ +#define LL_GPDMA1_REQUEST_LPTIM1_IC1 89U /*!< GPDMA1 HW request is LPTIM1_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM1_IC2 90U /*!< GPDMA1 HW request is LPTIM1_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM1_UE 91U /*!< GPDMA1 HW request is LPTIM1_UE */ +#define LL_GPDMA1_REQUEST_LPTIM2_IC1 92U /*!< GPDMA1 HW request is LPTIM2_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM2_IC2 93U /*!< GPDMA1 HW request is LPTIM2_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM2_UE 94U /*!< GPDMA1 HW request is LPTIM2_UE */ +#define LL_GPDMA1_REQUEST_SPDIF_RX_DT 95U /*!< GPDMA1 HW request is SPDIF_RX_DT */ +#define LL_GPDMA1_REQUEST_SPDIF_RX_CS 96U /*!< GPDMA1 HW request is SPDIF_RX_CS */ +#define LL_GPDMA1_REQUEST_ADF1_FLT0 97U /*!< GPDMA1 HW request is ADF1_FLT0 */ +#define LL_GPDMA1_REQUEST_UCPD1_TX 98U /*!< GPDMA1 HW request is UCPD1_TX */ +#define LL_GPDMA1_REQUEST_UCPD1_RX 99U /*!< GPDMA1 HW request is USBPD_RX */ +#define LL_GPDMA1_REQUEST_PSSI 100U /*!< GPDMA1 HW request is PSSI */ +#define LL_GPDMA1_REQUEST_LPUART1_RX 101U /*!< GPDMA1 HW request is LPUART1_RX */ +#define LL_GPDMA1_REQUEST_LPUART1_TX 102U /*!< GPDMA1 HW request is LPUART1_TX */ +#define LL_GPDMA1_REQUEST_LPTIM3_IC1 103U /*!< GPDMA1 HW request is LPTIM3_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM3_IC2 104U /*!< GPDMA1 HW request is LPTIM3_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM3_UE 105U /*!< GPDMA1 HW request is LPTIM3_UE */ +#define LL_GPDMA1_REQUEST_I3C1_RX 106U /*!< GPDMA1 HW request is I3C1_RX */ +#define LL_GPDMA1_REQUEST_I3C1_TX 107U /*!< GPDMA1 HW request is I3C1_TX */ +#define LL_GPDMA1_REQUEST_I3C1_TC 108U /*!< GPDMA1 HW request is I3C1_TC */ +#define LL_GPDMA1_REQUEST_I3C1_RS 109U /*!< GPDMA1 HW request is I3C1_RS */ + +/** + * @} + */ + +/** @defgroup DMA_LL_EC_TRIGGER_SELECTION Trigger Selection + * @{ + */ +/* HPDMA1 triggers */ +#define LL_HPDMA1_TRIGGER_DCMIPP_EVT_FRAMEEND 0U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_FRAMEEND */ +#define LL_HPDMA1_TRIGGER_DCMIPP_EVT_HSYNC 1U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_HSYNC */ +#define LL_HPDMA1_TRIGGER_DCMIPP_EVT_LINEEND 2U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_LINEEND */ +#define LL_HPDMA1_TRIGGER_DCMIPP_EVT_VSYNC 3U /*!< HPDMA1 HW Trigger signal is DCMIPP_EVT_VSYNC */ +#define LL_HPDMA1_TRIGGER_DMA2D_CTC_FLAG 4U /*!< HPDMA1 HW Trigger signal is DMA2D_CTC_FLAG */ +#define LL_HPDMA1_TRIGGER_DMA2D_TC_FLAG 5U /*!< HPDMA1 HW Trigger signal is DMA2D_TC_FLAG */ +#define LL_HPDMA1_TRIGGER_DMA2D_TW_FLAG 6U /*!< HPDMA1 HW Trigger signal is DMA2D_TW_FLAG */ +#define LL_HPDMA1_TRIGGER_JPEG_EOC_FLAG 7U /*!< HPDMA1 HW Trigger signal is JPEG_EOC_FLAG */ +#define LL_HPDMA1_TRIGGER_JPEG_IFNF_FLAG 8U /*!< HPDMA1 HW Trigger signal is JPEG_IFNF_FLAG */ +#define LL_HPDMA1_TRIGGER_JPEG_IFT_FLAG 9U /*!< HPDMA1 HW Trigger signal is JPEG_IFT_FLAG */ +#define LL_HPDMA1_TRIGGER_JPEG_OFNE_FLAG 10U /*!< HPDMA1 HW Trigger signal is JPEG_OFNE_FLAG */ +#define LL_HPDMA1_TRIGGER_JPEG_OFT_FLAG 11U /*!< HPDMA1 HW Trigger signal is JPEG_OFT_FLAG */ +#define LL_HPDMA1_TRIGGER_LCD 12U /*!< HPDMA1 HW Trigger signal is LCD */ +#define LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG0 13U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG0 */ +#define LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG1 14U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG1 */ +#define LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG2 15U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG2 */ +#define LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG3 16U /*!< HPDMA1 HW Trigger signal is GPU2D1_GP_FLAG3 */ +#define LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_4 17U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_4 */ +#define LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_3 18U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_3 */ +#define LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_2 19U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_2 */ +#define LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_1 20U /*!< HPDMA1 HW Trigger signal is GFXTIM_0_EVT_1 */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH0_TCF 21U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH0_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH1_TCF 22U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH2_TCF 23U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH2_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH3_TCF 24U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH3_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH4_TCF 25U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH4_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH5_TCF 26U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH5_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH6_TCF 27U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH6_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH7_TCF 28U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH7_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH8_TCF 29U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH8_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH9_TCF 30U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH9_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH10_TCF 31U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH10_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH11_TCF 32U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH11_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH12_TCF 33U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH12_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH13_TCF 34U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH13_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH14_TCF 35U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH14_TCF */ +#define LL_HPDMA1_TRIGGER_GPDMA1_CH15_TCF 36U /*!< HPDMA1 HW Trigger signal is GPDMA1_CH15_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH0_TCF 37U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH0_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH1_TCF 38U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH1_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH2_TCF 39U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH2_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH3_TCF 40U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH3_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH4_TCF 41U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH4_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH5_TCF 42U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH5_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH6_TCF 43U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH6_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH7_TCF 44U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH7_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH8_TCF 45U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH8_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH9_TCF 46U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH9_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH10_TCF 47U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH10_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH11_TCF 48U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH11_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH12_TCF 49U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH12_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH13_TCF 50U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH13_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH14_TCF 51U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH14_TCF */ +#define LL_HPDMA1_TRIGGER_HPDMA1_CH15_TCF 52U /*!< HPDMA1 HW Trigger signal is HPDMA1_CH15_TCF */ + +/* GPDMA1 triggers */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH0_TCF 0U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH0_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH1_TCF 1U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH1_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH2_TCF 2U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH2_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH3_TCF 3U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH3_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH4_TCF 4U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH4_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH5_TCF 5U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH5_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH6_TCF 6U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH6_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH7_TCF 7U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH7_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH8_TCF 8U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH8_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH9_TCF 9U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH9_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH10_TCF 10U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH10_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH11_TCF 11U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH11_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH12_TCF 12U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH12_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH13_TCF 13U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH13_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH14_TCF 14U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH14_TCF */ +#define LL_GPDMA1_TRIGGER_HPDMA1_CH15_TCF 15U /*!< GPDMA1 HW Trigger signal is HPDMA1_CH15_TCF */ +#define LL_GPDMA1_TRIGGER_LPTIM1_CH1 16U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM1_CH2 17U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH2 */ +#define LL_GPDMA1_TRIGGER_LPTIM2_CH1 18U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM2_CH2 19U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH2 */ +#define LL_GPDMA1_TRIGGER_LPTIM3_CH1 20U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM3_CH2 21U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH2 */ +#define LL_GPDMA1_TRIGGER_LPTIM4_OUT 22U /*!< GPDMA1 HW Trigger signal is LPTIM4_OUT */ +#define LL_GPDMA1_TRIGGER_LPTIM5_OUT 23U /*!< GPDMA1 HW Trigger signal is LPTIM5_OUT */ +#define LL_GPDMA1_TRIGGER_EXTIT0_SYNC 24U /*!< GPDMA1 HW Trigger signal is EXTIT0_SYNC */ +#define LL_GPDMA1_TRIGGER_RTC_WKUP 25U /*!< GPDMA1 HW Trigger signal is RTC_WKUP */ +#define LL_GPDMA1_TRIGGER_LPUART1_IT_R_WUP_ASYNC 26U /*!< GPDMA1 HW Trigger signal is R_WUP_ASYNC */ +#define LL_GPDMA1_TRIGGER_LPUART1_IT_T_WUP_ASYNC 27U /*!< GPDMA1 HW Trigger signal is T_WUP_ASYNC */ +#define LL_GPDMA1_TRIGGER_SPI6_IT_OR_SPI6_AIT_SYNC 28U /*!< GPDMA1 HW Trigger signal is SPI6_OR_SPI6_AIT_SYNC */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH0_TCF 29U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH1_TCF 30U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH2_TCF 31U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH2_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH3_TCF 32U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH3_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH4_TCF 33U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH4_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH5_TCF 34U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH5_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH6_TCF 35U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH6_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH7_TCF 36U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH7_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH8_TCF 37U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH8_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH9_TCF 38U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH9_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH10_TCF 39U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH10_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH11_TCF 40U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH11_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH12_TCF 41U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH12_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH13_TCF 42U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH13_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH14_TCF 43U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH14_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH15_TCF 44U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH15_TCF */ +#define LL_GPDMA1_TRIGGER_TIM1_TRGO 45U /*!< GPDMA1 HW Trigger signal is TIM1_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM1_TRGO2 46U /*!< GPDMA1 HW Trigger signal is TIM1_TRGO2 */ +#define LL_GPDMA1_TRIGGER_TIM2_TRGO 47U /*!< GPDMA1 HW Trigger signal is TIM2_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM3_TRGO 48U /*!< GPDMA1 HW Trigger signal is TIM3_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM4_TRGO 49U /*!< GPDMA1 HW Trigger signal is TIM4_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM5_TRGO 50U /*!< GPDMA1 HW Trigger signal is TIM5_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM6_TRGO 51U /*!< GPDMA1 HW Trigger signal is TIM6_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM7_TRGO 52U /*!< GPDMA1 HW Trigger signal is TIM7_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM9_TRGO 53U /*!< GPDMA1 HW Trigger signal is TIM9_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM12_TRGO 54U /*!< GPDMA1 HW Trigger signal is TIM12_TRGO */ +#define LL_GPDMA1_TRIGGER_TIM15_TRGO 55U /*!< GPDMA1 HW Trigger signal is TIM15_TRGO */ +/** + * @} + */ + +/** + * @} + */ + +/* 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_Channel15)) ? HPDMA1 : 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)HPDMA1_Channel0)) ? LL_DMA_CHANNEL_0 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel0)) ? LL_DMA_CHANNEL_0 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel7)) ? LL_DMA_CHANNEL_7 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel7)) ? LL_DMA_CHANNEL_7 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel8)) ? LL_DMA_CHANNEL_8 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel8)) ? LL_DMA_CHANNEL_8 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel9)) ? LL_DMA_CHANNEL_9 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel9)) ? LL_DMA_CHANNEL_9 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel10)) ? LL_DMA_CHANNEL_10 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel10)) ? LL_DMA_CHANNEL_10 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel11)) ? LL_DMA_CHANNEL_11 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel11)) ? LL_DMA_CHANNEL_11 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel12)) ? LL_DMA_CHANNEL_12 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel12)) ? LL_DMA_CHANNEL_12 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel13)) ? LL_DMA_CHANNEL_13 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel13)) ? LL_DMA_CHANNEL_13 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)HPDMA1_Channel14)) ? LL_DMA_CHANNEL_14 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel14)) ? LL_DMA_CHANNEL_14 : \ + LL_DMA_CHANNEL_15) + +/** + * @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)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_0))) \ + ? HPDMA1_Channel0 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_0))) \ + ? GPDMA1_Channel0 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? HPDMA1_Channel1 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? GPDMA1_Channel1 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? HPDMA1_Channel2 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? GPDMA1_Channel2 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? HPDMA1_Channel3 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? GPDMA1_Channel3 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? HPDMA1_Channel4 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? GPDMA1_Channel4 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? HPDMA1_Channel5 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? GPDMA1_Channel5 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? HPDMA1_Channel6 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? GPDMA1_Channel6 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_7))) \ + ? HPDMA1_Channel7 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_7))) \ + ? GPDMA1_Channel7 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_8))) \ + ? HPDMA1_Channel8 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_8))) \ + ? GPDMA1_Channel8 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_9))) \ + ? HPDMA1_Channel9 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_9))) \ + ? GPDMA1_Channel9 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_10)))\ + ? HPDMA1_Channel10 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_10)))\ + ? GPDMA1_Channel10 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_11)))\ + ? HPDMA1_Channel11 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_11)))\ + ? GPDMA1_Channel11 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_12)))\ + ? HPDMA1_Channel12 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_12)))\ + ? GPDMA1_Channel12 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_13)))\ + ? HPDMA1_Channel13 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_13)))\ + ? GPDMA1_Channel13 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_14)))\ + ? HPDMA1_Channel14 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_14)))\ + ? GPDMA1_Channel14 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)HPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_15)))\ + ? HPDMA1_Channel15 : GPDMA1_Channel15) + +/** + * @} + */ + +/** + * @} + */ + +/* 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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 DWX 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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_WORD_PRESERVE or @ref LL_DMA_DEST_WORD_EXCHANGE + * @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 or @ref LL_DMA_DEST_DATAWIDTH_DOUBLEWORD + * @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 or @ref LL_DMA_SRC_DATAWIDTH_DOUBLEWORD + *@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_DWX | 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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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)); +} + +/** + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 word exchange. + * @rmtoll CTR1 DWX LL_DMA_SetDestWordExchange + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @param DestWordExchange This parameter can be one of the following values: + * @arg @ref LL_DMA_DEST_WORD_PRESERVE + * @arg @ref LL_DMA_DEST_WORD_EXCHANGE + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestWordExchange(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestWordExchange) +{ + 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_DWX, + DestWordExchange); +} + +/** + * @brief Get destination word exchange. + * @rmtoll CTR1 DWX LL_DMA_GetDestWordExchange + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DEST_WORD_PRESERVE + * @arg @ref LL_DMA_DEST_WORD_EXCHANGE + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestWordExchange(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_DWX)); +} + +/** + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_DEST_DATAWIDTH_DOUBLEWORD + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_DEST_DATAWIDTH_DOUBLEWORD + */ +__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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_SRC_DATAWIDTH_DOUBLEWORD + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_SRC_DATAWIDTH_DOUBLEWORD + */ +__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\n + * CTR2 PFREQ 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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_HWREQUEST_SINGLEBURST or @ref LL_DMA_HWREQUEST_BLK + * @arg @ref LL_DMA_TRIG_POLARITY_MASKED 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 + * @arg @ref LL_DMA_NORMAL or @ref LL_DMA_PFCTRL + *@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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @param Request This parameter can be one of the following values: + * @arg @ref LL_HPDMA1_REQUEST_JPEG_RX + * @arg @ref LL_HPDMA1_REQUEST_JPEG_TX + * @arg @ref LL_HPDMA1_REQUEST_XSPI1 + * @arg @ref LL_HPDMA1_REQUEST_XSPI2 + * @arg @ref LL_HPDMA1_REQUEST_SPI3_RX + * @arg @ref LL_HPDMA1_REQUEST_SPI3_TX + * @arg @ref LL_HPDMA1_REQUEST_SPI4_RX + * @arg @ref LL_HPDMA1_REQUEST_SPI4_TX + * @arg @ref LL_HPDMA1_REQUEST_ADC1 + * @arg @ref LL_HPDMA1_REQUEST_ADC2 + * @arg @ref LL_HPDMA1_REQUEST_ADF1_FLT0 + * @arg @ref LL_HPDMA1_REQUEST_UART4_RX + * @arg @ref LL_HPDMA1_REQUEST_UART4_TX + * @arg @ref LL_HPDMA1_REQUEST_UART5_RX + * @arg @ref LL_HPDMA1_REQUEST_UART5_TX + * @arg @ref LL_HPDMA1_REQUEST_UART7_RX + * @arg @ref LL_HPDMA1_REQUEST_UART7_TX + * @arg @ref LL_HPDMA1_REQUEST_LPTIM2_IC1 + * @arg @ref LL_HPDMA1_REQUEST_LPTIM2_IC2 + * @arg @ref LL_HPDMA1_REQUEST_LPTIM2_UE + * @arg @ref LL_GPDMA1_REQUEST_ADC1 + * @arg @ref LL_GPDMA1_REQUEST_ADC2 + * @arg @ref LL_GPDMA1_REQUEST_CRYP_IN + * @arg @ref LL_GPDMA1_REQUEST_CRYP_OUT + * @arg @ref LL_GPDMA1_REQUEST_SAES_IN + * @arg @ref LL_GPDMA1_REQUEST_SAES_OUT + * @arg @ref LL_GPDMA1_REQUEST_HASH_IN + * @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_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_TIM2_TRIG + * @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_TIM4_TRIG + * @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_TIM6_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM7_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM15_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM15_CH2 + * @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_TIM16_COM + * @arg @ref LL_GPDMA1_REQUEST_TIM17_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM17_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM17_COM + * @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_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_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_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_CORDIC_READ + * @arg @ref LL_GPDMA1_REQUEST_CORDIC_WRITE + * @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_SPDIF_RX_DT + * @arg @ref LL_GPDMA1_REQUEST_SPDIF_RX_CS + * @arg @ref LL_GPDMA1_REQUEST_ADF1_FLT0 + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_TX + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_RX + * @arg @ref LL_GPDMA1_REQUEST_PSSI + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_RX + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_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_I3C1_RX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TC + * @arg @ref LL_GPDMA1_REQUEST_I3C1_RS + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_HPDMA1_REQUEST_JPEG_RX + * @arg @ref LL_HPDMA1_REQUEST_JPEG_TX + * @arg @ref LL_HPDMA1_REQUEST_XSPI1 + * @arg @ref LL_HPDMA1_REQUEST_XSPI2 + * @arg @ref LL_HPDMA1_REQUEST_SPI3_RX + * @arg @ref LL_HPDMA1_REQUEST_SPI3_TX + * @arg @ref LL_HPDMA1_REQUEST_SPI4_RX + * @arg @ref LL_HPDMA1_REQUEST_SPI4_TX + * @arg @ref LL_HPDMA1_REQUEST_ADC1 + * @arg @ref LL_HPDMA1_REQUEST_ADC2 + * @arg @ref LL_HPDMA1_REQUEST_ADF1_FLT0 + * @arg @ref LL_HPDMA1_REQUEST_UART4_RX + * @arg @ref LL_HPDMA1_REQUEST_UART4_TX + * @arg @ref LL_HPDMA1_REQUEST_UART5_RX + * @arg @ref LL_HPDMA1_REQUEST_UART5_TX + * @arg @ref LL_HPDMA1_REQUEST_UART7_RX + * @arg @ref LL_HPDMA1_REQUEST_UART7_TX + * @arg @ref LL_HPDMA1_REQUEST_LPTIM2_IC1 + * @arg @ref LL_HPDMA1_REQUEST_LPTIM2_IC2 + * @arg @ref LL_HPDMA1_REQUEST_LPTIM2_UE + * @arg @ref LL_GPDMA1_REQUEST_ADC1 + * @arg @ref LL_GPDMA1_REQUEST_ADC2 + * @arg @ref LL_GPDMA1_REQUEST_CRYP_IN + * @arg @ref LL_GPDMA1_REQUEST_CRYP_OUT + * @arg @ref LL_GPDMA1_REQUEST_SAES_IN + * @arg @ref LL_GPDMA1_REQUEST_SAES_OUT + * @arg @ref LL_GPDMA1_REQUEST_HASH_IN + * @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_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_TIM2_TRIG + * @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_TIM4_TRIG + * @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_TIM6_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM7_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM15_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM15_CH2 + * @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_TIM16_COM + * @arg @ref LL_GPDMA1_REQUEST_TIM17_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM17_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM17_COM + * @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_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_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_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_CORDIC_READ + * @arg @ref LL_GPDMA1_REQUEST_CORDIC_WRITE + * @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_SPDIF_RX_DT + * @arg @ref LL_GPDMA1_REQUEST_SPDIF_RX_CS + * @arg @ref LL_GPDMA1_REQUEST_ADF1_FLT0 + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_TX + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_RX + * @arg @ref LL_GPDMA1_REQUEST_PSSI + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_RX + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_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_I3C1_RX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TC + * @arg @ref LL_GPDMA1_REQUEST_I3C1_RS + */ +__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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @param Trigger This parameter can be one of the following values: + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_FRAMEEND + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_HSYNC + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_LINEEND + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_VSYNC + * @arg @ref LL_HPDMA1_TRIGGER_DMA2D_CTC_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_DMA2D_TC_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_DMA2D_TW_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_EOC_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_IFNF_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_IFT_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_OFNE_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_OFT_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_LCD + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG0 + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG1 + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG2 + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG3 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_4 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_3 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_2 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_1 + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH0_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH1_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH2_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH3_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH4_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH5_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH6_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH7_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH8_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH9_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH10_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH11_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH12_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH13_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH14_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH15_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH0_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH1_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH2_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH3_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH4_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH5_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH6_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH7_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH8_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH9_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH10_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH11_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH12_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH13_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH14_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH15_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH1_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH2_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH3_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH4_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH5_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH6_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH7_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH8_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH9_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH10_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH11_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH12_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH13_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH14_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH15_TCF + * @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_LPTIM3_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM4_OUT + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_OUT + * @arg @ref LL_GPDMA1_TRIGGER_EXTIT0_SYNC + * @arg @ref LL_GPDMA1_TRIGGER_RTC_WKUP + * @arg @ref LL_GPDMA1_TRIGGER_LPUART1_IT_R_WUP_ASYNC + * @arg @ref LL_GPDMA1_TRIGGER_LPUART1_IT_T_WUP_ASYNC + * @arg @ref LL_GPDMA1_TRIGGER_SPI6_IT_OR_SPI6_AIT_SYNC + * @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_GPDMA1_CH8_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH9_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH10_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH11_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH12_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH13_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH14_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH15_TCF + * @arg @ref LL_GPDMA1_TRIGGER_TIM1_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM1_TRGO2 + * @arg @ref LL_GPDMA1_TRIGGER_TIM2_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM3_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM4_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM5_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM6_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM7_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM9_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM12_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM15_TRGO + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_FRAMEEND + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_HSYNC + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_LINEEND + * @arg @ref LL_HPDMA1_TRIGGER_DCMIPP_EVT_VSYNC + * @arg @ref LL_HPDMA1_TRIGGER_DMA2D_CTC_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_DMA2D_TC_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_DMA2D_TW_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_EOC_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_IFNF_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_IFT_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_OFNE_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_JPEG_OFT_FLAG + * @arg @ref LL_HPDMA1_TRIGGER_LCD + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG0 + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG1 + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG2 + * @arg @ref LL_HPDMA1_TRIGGER_GPU2D1_GP_FLAG3 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_4 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_3 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_2 + * @arg @ref LL_HPDMA1_TRIGGER_GFXTIM_0_EVT_1 + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH0_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH1_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH2_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH3_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH4_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH5_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH6_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH7_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH8_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH9_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH10_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH11_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH12_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH13_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH14_TCF + * @arg @ref LL_HPDMA1_TRIGGER_GPDMA1_CH15_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH0_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH1_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH2_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH3_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH4_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH5_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH6_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH7_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH8_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH9_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH10_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH11_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH12_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH13_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH14_TCF + * @arg @ref LL_HPDMA1_TRIGGER_HPDMA1_CH15_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH1_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH2_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH3_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH4_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH5_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH6_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH7_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH8_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH9_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH10_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH11_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH12_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH13_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH14_TCF + * @arg @ref LL_GPDMA1_TRIGGER_HPDMA1_CH15_TCF + * @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_LPTIM3_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM4_OUT + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_OUT + * @arg @ref LL_GPDMA1_TRIGGER_EXTIT0_SYNC + * @arg @ref LL_GPDMA1_TRIGGER_RTC_WKUP + * @arg @ref LL_GPDMA1_TRIGGER_LPUART1_IT_R_WUP_ASYNC + * @arg @ref LL_GPDMA1_TRIGGER_LPUART1_IT_T_WUP_ASYNC + * @arg @ref LL_GPDMA1_TRIGGER_SPI6_IT_OR_SPI6_AIT_SYNC + * @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_GPDMA1_CH8_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH9_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH10_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH11_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH12_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH13_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH14_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH15_TCF + * @arg @ref LL_GPDMA1_TRIGGER_TIM1_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM1_TRGO2 + * @arg @ref LL_GPDMA1_TRIGGER_TIM2_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM3_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM4_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM5_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM6_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM7_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM9_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM12_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM15_TRGO + */ +__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 (HW request peripheral flow control mode supported on GPDMA1) + * @arg @ref LL_DMA_CHANNEL_15 (HW request peripheral flow control mode supported on GPDMA1 & HPDMA1) + * @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 (HW request peripheral flow control mode supported on GPDMA1) + * @arg @ref LL_DMA_CHANNEL_15 (HW request peripheral flow control mode supported on GPDMA1 & HPDMA1) + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @param BlkDataLength Block transfer length + Value between 0 to 0x0000FFFF + * @param BlkRptCount Block repeat counter + * Value between 0 to 0x000007FF + *@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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @param BlkRptCount Block repeat counter + * Value between 0 to 0x000007FF + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @retval Between 0 to 0x000007FF + */ +__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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 by increment of 4 Bytes. + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @param LinkedListAddrOffset Between 0 to 0x0000FFFC by increment of 4 Bytes. + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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); +} + + +/** + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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); +} + + +/** + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannelLockAttribute(DMA_TypeDef *DMAx, uint32_t Channel) +{ + SET_BIT(DMAx->RCFGLOCKR, (DMA_RCFGLOCKR_LOCK0 << (Channel & 0x0000000FU))); +} + + +/** + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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); +} + +/** + * @} + */ + +/** @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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); +} + +/** + * @} + */ + +/** @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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 + * @arg @ref LL_DMA_CHANNEL_8 + * @arg @ref LL_DMA_CHANNEL_9 + * @arg @ref LL_DMA_CHANNEL_10 + * @arg @ref LL_DMA_CHANNEL_11 + * @arg @ref LL_DMA_CHANNEL_12 + * @arg @ref LL_DMA_CHANNEL_13 + * @arg @ref LL_DMA_CHANNEL_14 + * @arg @ref LL_DMA_CHANNEL_15 + * @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(const 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 /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* GPDMA1 || HPDMA1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H7RSxx_LL_DMA_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma2d.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma2d.h new file mode 100644 index 0000000..6e7a4a8 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_dma2d.h @@ -0,0 +1,2230 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_dma2d.h + * @author MCD Application Team + * @brief Header file of DMA2D LL 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 STM32H7RSxx_LL_DMA2D_H +#define STM32H7RSxx_LL_DMA2D_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +#if defined (DMA2D) + +/** @defgroup DMA2D_LL DMA2D + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup DMA2D_LL_Private_Macros DMA2D Private Macros + * @{ + */ + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup DMA2D_LL_ES_Init_Struct DMA2D Exported Init structures + * @{ + */ + +/** + * @brief LL DMA2D Init Structure Definition + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the DMA2D transfer mode. + - This parameter can be one value of @ref DMA2D_LL_EC_MODE. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetMode(). */ + + uint32_t ColorMode; /*!< Specifies the color format of the output image. + - This parameter can be one value of @ref DMA2D_LL_EC_OUTPUT_COLOR_MODE. + + This parameter can be modified afterwards using, + unitary function @ref LL_DMA2D_SetOutputColorMode(). */ + + uint32_t OutputBlue; /*!< Specifies the Blue value of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if RGB888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if RGB565 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputGreen; /*!< Specifies the Green value of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if RGB888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x3F if RGB565 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + + This parameter can be modified afterwards + using unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputRed; /*!< Specifies the Red value of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if RGB888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if RGB565 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + + This parameter can be modified afterwards + using unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputAlpha; /*!< Specifies the Alpha channel of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x01 if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + - This parameter is not considered if RGB888 or RGB565 color mode is selected. + + This parameter can be modified afterwards using, + unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputMemoryAddress; /*!< Specifies the memory address. + - This parameter must be a number between: + Min_Data = 0x0000 and Max_Data = 0xFFFFFFFF. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputMemAddr(). */ + + uint32_t OutputSwapMode; /*!< Specifies the output swap mode color format of the output image. + - This parameter can be one value of @ref DMA2D_LL_EC_OUTPUT_SWAP_MODE. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputSwapMode(). */ + + uint32_t LineOffsetMode; /*!< Specifies the output line offset mode. + - This parameter can be one value of @ref DMA2D_LL_EC_LINE_OFFSET_MODE. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetLineOffsetMode(). */ + + uint32_t LineOffset; /*!< Specifies the output line offset value. + - This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetLineOffset(). */ + + uint32_t NbrOfLines; /*!< Specifies the number of lines of the area to be transferred. + - This parameter must be a number between: + Min_Data = 0x0000 and Max_Data = 0xFFFF. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetNbrOfLines(). */ + + uint32_t NbrOfPixelsPerLines; /*!< Specifies the number of pixels per lines of the area to be transferred. + - This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. + + This parameter can be modified afterwards using, + unitary function @ref LL_DMA2D_SetNbrOfPixelsPerLines(). */ + + uint32_t AlphaInversionMode; /*!< Specifies the output alpha inversion mode. + - This parameter can be one value of @ref DMA2D_LL_EC_ALPHA_INVERSION. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputAlphaInvMode(). */ + + uint32_t RBSwapMode; /*!< Specifies the output Red Blue swap mode. + - This parameter can be one value of @ref DMA2D_LL_EC_RED_BLUE_SWAP. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputRBSwapMode(). */ + +} LL_DMA2D_InitTypeDef; + +/** + * @brief LL DMA2D Layer Configuration Structure Definition + */ +typedef struct +{ + uint32_t MemoryAddress; /*!< Specifies the foreground or background memory address. + - This parameter must be a number between: + Min_Data = 0x0000 and Max_Data = 0xFFFFFFFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetMemAddr() for foreground layer, + - @ref LL_DMA2D_BGND_SetMemAddr() for background layer. */ + + uint32_t LineOffset; /*!< Specifies the foreground or background line offset value. + - This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetLineOffset() for foreground layer, + - @ref LL_DMA2D_BGND_SetLineOffset() for background layer. */ + + uint32_t ColorMode; /*!< Specifies the foreground or background color mode. + - This parameter can be one value of @ref DMA2D_LL_EC_INPUT_COLOR_MODE. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetColorMode() for foreground layer, + - @ref LL_DMA2D_BGND_SetColorMode() for background layer. */ + + uint32_t CLUTColorMode; /*!< Specifies the foreground or background CLUT color mode. + - This parameter can be one value of @ref DMA2D_LL_EC_CLUT_COLOR_MODE. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetCLUTColorMode() for foreground layer, + - @ref LL_DMA2D_BGND_SetCLUTColorMode() for background layer. */ + + uint32_t CLUTSize; /*!< Specifies the foreground or background CLUT size. + - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetCLUTSize() for foreground layer, + - @ref LL_DMA2D_BGND_SetCLUTSize() for background layer. */ + + uint32_t AlphaMode; /*!< Specifies the foreground or background alpha mode. + - This parameter can be one value of @ref DMA2D_LL_EC_ALPHA_MODE. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetAlphaMode() for foreground layer, + - @ref LL_DMA2D_BGND_SetAlphaMode() for background layer. */ + + uint32_t Alpha; /*!< Specifies the foreground or background Alpha value. + - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetAlpha() for foreground layer, + - @ref LL_DMA2D_BGND_SetAlpha() for background layer. */ + + uint32_t Blue; /*!< Specifies the foreground or background Blue color value. + - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetBlueColor() for foreground layer, + - @ref LL_DMA2D_BGND_SetBlueColor() for background layer. */ + + uint32_t Green; /*!< Specifies the foreground or background Green color value. + - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetGreenColor() for foreground layer, + - @ref LL_DMA2D_BGND_SetGreenColor() for background layer. */ + + uint32_t Red; /*!< Specifies the foreground or background Red color value. + - This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetRedColor() for foreground layer, + - @ref LL_DMA2D_BGND_SetRedColor() for background layer. */ + + uint32_t CLUTMemoryAddress; /*!< Specifies the foreground or background CLUT memory address. + - This parameter must be a number between: + Min_Data = 0x0000 and Max_Data = 0xFFFFFFFF. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetCLUTMemAddr() for foreground layer, + - @ref LL_DMA2D_BGND_SetCLUTMemAddr() for background layer. */ + + uint32_t AlphaInversionMode; /*!< Specifies the foreground or background alpha inversion mode. + - This parameter can be one value of @ref DMA2D_LL_EC_ALPHA_INVERSION. + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetAlphaInvMode() for foreground layer, + - @ref LL_DMA2D_BGND_SetAlphaInvMode() for background layer. */ + + uint32_t RBSwapMode; /*!< Specifies the foreground or background Red Blue swap mode. + This parameter can be one value of @ref DMA2D_LL_EC_RED_BLUE_SWAP . + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetRBSwapMode() for foreground layer, + - @ref LL_DMA2D_BGND_SetRBSwapMode() for background layer. */ + + uint32_t ChromaSubSampling; /*!< Configure the chroma sub-sampling mode for the YCbCr color mode + This parameter is applicable for foreground layer only. + This parameter can be one value of @ref DMA2D_LL_CHROMA_SUB_SAMPLING + + This parameter can be modified afterwards using unitary functions + - @ref LL_DMA2D_FGND_SetChrSubSampling() for foreground layer. */ + +} LL_DMA2D_LayerCfgTypeDef; + +/** + * @brief LL DMA2D Output Color Structure Definition + */ +typedef struct +{ + uint32_t ColorMode; /*!< Specifies the color format of the output image. + - This parameter can be one value of @ref DMA2D_LL_EC_OUTPUT_COLOR_MODE. + + This parameter can be modified afterwards using + unitary function @ref LL_DMA2D_SetOutputColorMode(). */ + + uint32_t OutputBlue; /*!< Specifies the Blue value of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if RGB888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if RGB565 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + + This parameter can be modified afterwards using, + unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputGreen; /*!< Specifies the Green value of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between + Min_Data = 0x00 and Max_Data = 0xFF if RGB888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x3F if RGB565 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputRed; /*!< Specifies the Red value of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if RGB888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if RGB565 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x1F if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + + uint32_t OutputAlpha; /*!< Specifies the Alpha channel of the output image. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0xFF if ARGB8888 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x01 if ARGB1555 color mode is selected. + - This parameter must be a number between: + Min_Data = 0x00 and Max_Data = 0x0F if ARGB4444 color mode is selected. + - This parameter is not considered if RGB888 or RGB565 color mode is selected. + + This parameter can be modified afterwards, + using unitary function @ref LL_DMA2D_SetOutputColor() or configuration + function @ref LL_DMA2D_ConfigOutputColor(). */ + +} LL_DMA2D_ColorTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DMA2D_LL_Exported_Constants DMA2D Exported Constants + * @{ + */ + +/** @defgroup DMA2D_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_DMA2D_ReadReg function + * @{ + */ +#define LL_DMA2D_FLAG_CEIF DMA2D_ISR_CEIF /*!< Configuration Error Interrupt Flag */ +#define LL_DMA2D_FLAG_CTCIF DMA2D_ISR_CTCIF /*!< CLUT Transfer Complete Interrupt Flag */ +#define LL_DMA2D_FLAG_CAEIF DMA2D_ISR_CAEIF /*!< CLUT Access Error Interrupt Flag */ +#define LL_DMA2D_FLAG_TWIF DMA2D_ISR_TWIF /*!< Transfer Watermark Interrupt Flag */ +#define LL_DMA2D_FLAG_TCIF DMA2D_ISR_TCIF /*!< Transfer Complete Interrupt Flag */ +#define LL_DMA2D_FLAG_TEIF DMA2D_ISR_TEIF /*!< Transfer Error Interrupt Flag */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_DMA2D_ReadReg and LL_DMA2D_WriteReg functions + * @{ + */ +#define LL_DMA2D_IT_CEIE DMA2D_CR_CEIE /*!< Configuration Error Interrupt */ +#define LL_DMA2D_IT_CTCIE DMA2D_CR_CTCIE /*!< CLUT Transfer Complete Interrupt */ +#define LL_DMA2D_IT_CAEIE DMA2D_CR_CAEIE /*!< CLUT Access Error Interrupt */ +#define LL_DMA2D_IT_TWIE DMA2D_CR_TWIE /*!< Transfer Watermark Interrupt */ +#define LL_DMA2D_IT_TCIE DMA2D_CR_TCIE /*!< Transfer Complete Interrupt */ +#define LL_DMA2D_IT_TEIE DMA2D_CR_TEIE /*!< Transfer Error Interrupt */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_MODE Mode + * @{ + */ +#define LL_DMA2D_MODE_M2M 0x00000000U /*!< DMA2D memory to memory transfer mode */ +#define LL_DMA2D_MODE_M2M_PFC DMA2D_CR_MODE_0 /*!< DMA2D memory to memory with pixel format conversion transfer mode */ +#define LL_DMA2D_MODE_M2M_BLEND DMA2D_CR_MODE_1 /*!< DMA2D memory to memory with blending transfer mode */ +#define LL_DMA2D_MODE_R2M (DMA2D_CR_MODE_0|DMA2D_CR_MODE_1) /*!< DMA2D register to memory transfer mode */ +#define LL_DMA2D_MODE_M2M_BLEND_FIXED_COLOR_FG DMA2D_CR_MODE_2 /*!< DMA2D memory to memory with blending transfer mode and fixed color foreground */ +#define LL_DMA2D_MODE_M2M_BLEND_FIXED_COLOR_BG (DMA2D_CR_MODE_0|DMA2D_CR_MODE_2) /*!< DMA2D memory to memory with blending transfer mode and fixed color background */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_OUTPUT_COLOR_MODE Output Color Mode + * @{ + */ +#define LL_DMA2D_OUTPUT_MODE_ARGB8888 0x00000000U /*!< ARGB8888 */ +#define LL_DMA2D_OUTPUT_MODE_RGB888 DMA2D_OPFCCR_CM_0 /*!< RGB888 */ +#define LL_DMA2D_OUTPUT_MODE_RGB565 DMA2D_OPFCCR_CM_1 /*!< RGB565 */ +#define LL_DMA2D_OUTPUT_MODE_ARGB1555 (DMA2D_OPFCCR_CM_0|DMA2D_OPFCCR_CM_1) /*!< ARGB1555 */ +#define LL_DMA2D_OUTPUT_MODE_ARGB4444 DMA2D_OPFCCR_CM_2 /*!< ARGB4444 */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_INPUT_COLOR_MODE Input Color Mode + * @{ + */ +#define LL_DMA2D_INPUT_MODE_ARGB8888 0x00000000U /*!< ARGB8888 */ +#define LL_DMA2D_INPUT_MODE_RGB888 DMA2D_FGPFCCR_CM_0 /*!< RGB888 */ +#define LL_DMA2D_INPUT_MODE_RGB565 DMA2D_FGPFCCR_CM_1 /*!< RGB565 */ +#define LL_DMA2D_INPUT_MODE_ARGB1555 (DMA2D_FGPFCCR_CM_0|DMA2D_FGPFCCR_CM_1) /*!< ARGB1555 */ +#define LL_DMA2D_INPUT_MODE_ARGB4444 DMA2D_FGPFCCR_CM_2 /*!< ARGB4444 */ +#define LL_DMA2D_INPUT_MODE_L8 (DMA2D_FGPFCCR_CM_0|DMA2D_FGPFCCR_CM_2) /*!< L8 */ +#define LL_DMA2D_INPUT_MODE_AL44 (DMA2D_FGPFCCR_CM_1|DMA2D_FGPFCCR_CM_2) /*!< AL44 */ +#define LL_DMA2D_INPUT_MODE_AL88 (DMA2D_FGPFCCR_CM_0|DMA2D_FGPFCCR_CM_1|DMA2D_FGPFCCR_CM_2) /*!< AL88 */ +#define LL_DMA2D_INPUT_MODE_L4 DMA2D_FGPFCCR_CM_3 /*!< L4 */ +#define LL_DMA2D_INPUT_MODE_A8 (DMA2D_FGPFCCR_CM_0|DMA2D_FGPFCCR_CM_3) /*!< A8 */ +#define LL_DMA2D_INPUT_MODE_A4 (DMA2D_FGPFCCR_CM_1|DMA2D_FGPFCCR_CM_3) /*!< A4 */ +#define LL_DMA2D_INPUT_MODE_YCBCR (DMA2D_FGPFCCR_CM_0|DMA2D_FGPFCCR_CM_1|DMA2D_FGPFCCR_CM_3) /*!< YCbCr */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_ALPHA_MODE Alpha Mode + * @{ + */ +#define LL_DMA2D_ALPHA_MODE_NO_MODIF 0x00000000U /*!< No modification of the alpha channel value */ +#define LL_DMA2D_ALPHA_MODE_REPLACE DMA2D_FGPFCCR_AM_0 /*!< Replace original alpha channel value by + programmed alpha value */ +#define LL_DMA2D_ALPHA_MODE_COMBINE DMA2D_FGPFCCR_AM_1 /*!< Replace original alpha channel value by + programmed alpha value with, + original alpha channel value */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_OUTPUT_SWAP_MODE Swap Mode + * @{ + */ +#define LL_DMA2D_SWAP_MODE_REGULAR 0x00000000U /*!< Regular order */ +#define LL_DMA2D_SWAP_MODE_TWO_BY_TWO DMA2D_OPFCCR_SB /*!< Bytes swapped two by two */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_RED_BLUE_SWAP Red Blue Swap + * @{ + */ +#define LL_DMA2D_RB_MODE_REGULAR 0x00000000U /*!< RGB or ARGB */ +#define LL_DMA2D_RB_MODE_SWAP DMA2D_FGPFCCR_RBS /*!< BGR or ABGR */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_ALPHA_INVERSION Alpha Inversion + * @{ + */ +#define LL_DMA2D_ALPHA_REGULAR 0x00000000U /*!< Regular alpha */ +#define LL_DMA2D_ALPHA_INVERTED DMA2D_FGPFCCR_AI /*!< Inverted alpha */ +/** + * @} + */ + + +/** @defgroup DMA2D_LL_EC_LINE_OFFSET_MODE Line Offset Mode + * @{ + */ +#define LL_DMA2D_LINE_OFFSET_PIXELS 0x00000000U /*!< Line offsets are expressed in pixels */ +#define LL_DMA2D_LINE_OFFSET_BYTES DMA2D_CR_LOM /*!< Line offsets are expressed in bytes */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_EC_CLUT_COLOR_MODE CLUT Color Mode + * @{ + */ +#define LL_DMA2D_CLUT_COLOR_MODE_ARGB8888 0x00000000U /*!< ARGB8888 */ +#define LL_DMA2D_CLUT_COLOR_MODE_RGB888 DMA2D_FGPFCCR_CCM /*!< RGB888 */ +/** + * @} + */ + +/** @defgroup DMA2D_LL_CHROMA_SUB_SAMPLING Chroma Sub Sampling + * @{ + */ +#define LL_DMA2D_CSS_444 0x00000000U /*!< No chroma sub-sampling 4:4:4 */ +#define LL_DMA2D_CSS_422 DMA2D_FGPFCCR_CSS_0 /*!< chroma sub-sampling 4:2:2 */ +#define LL_DMA2D_CSS_420 DMA2D_FGPFCCR_CSS_1 /*!< chroma sub-sampling 4:2:0 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DMA2D_LL_Exported_Macros DMA2D Exported Macros + * @{ + */ + +/** @defgroup DMA2D_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in DMA2D register. + * @param __INSTANCE__ DMA2D Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DMA2D_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG((__INSTANCE__)->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DMA2D register. + * @param __INSTANCE__ DMA2D Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DMA2D_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DMA2D_LL_Exported_Functions DMA2D Exported Functions + * @{ + */ + +/** @defgroup DMA2D_LL_EF_Configuration Configuration Functions + * @{ + */ + +/** + * @brief Start a DMA2D transfer. + * @rmtoll CR START LL_DMA2D_Start + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_Start(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_START); +} + +/** + * @brief Indicate if a DMA2D transfer is ongoing. + * @rmtoll CR START LL_DMA2D_IsTransferOngoing + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsTransferOngoing(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_START) == (DMA2D_CR_START)) ? 1UL : 0UL); +} + +/** + * @brief Suspend DMA2D transfer. + * @note This API can be used to suspend automatic foreground or background CLUT loading. + * @rmtoll CR SUSP LL_DMA2D_Suspend + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_Suspend(DMA2D_TypeDef *DMA2Dx) +{ + MODIFY_REG(DMA2Dx->CR, DMA2D_CR_SUSP | DMA2D_CR_START, DMA2D_CR_SUSP); +} + +/** + * @brief Resume DMA2D transfer. + * @note This API can be used to resume automatic foreground or background CLUT loading. + * @rmtoll CR SUSP LL_DMA2D_Resume + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_Resume(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_SUSP | DMA2D_CR_START); +} + +/** + * @brief Indicate if DMA2D transfer is suspended. + * @note This API can be used to indicate whether or not automatic foreground or + * background CLUT loading is suspended. + * @rmtoll CR SUSP LL_DMA2D_IsSuspended + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsSuspended(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_SUSP) == (DMA2D_CR_SUSP)) ? 1UL : 0UL); +} + +/** + * @brief Abort DMA2D transfer. + * @note This API can be used to abort automatic foreground or background CLUT loading. + * @rmtoll CR ABORT LL_DMA2D_Abort + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_Abort(DMA2D_TypeDef *DMA2Dx) +{ + MODIFY_REG(DMA2Dx->CR, DMA2D_CR_ABORT | DMA2D_CR_START, DMA2D_CR_ABORT); +} + +/** + * @brief Indicate if DMA2D transfer is aborted. + * @note This API can be used to indicate whether or not automatic foreground or + * background CLUT loading is aborted. + * @rmtoll CR ABORT LL_DMA2D_IsAborted + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsAborted(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_ABORT) == (DMA2D_CR_ABORT)) ? 1UL : 0UL); +} + +/** + * @brief Set DMA2D mode. + * @rmtoll CR MODE LL_DMA2D_SetMode + * @param DMA2Dx DMA2D Instance + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_MODE_M2M + * @arg @ref LL_DMA2D_MODE_M2M_PFC + * @arg @ref LL_DMA2D_MODE_M2M_BLEND + * @arg @ref LL_DMA2D_MODE_R2M + * @arg @ref LL_DMA2D_MODE_M2M_BLEND_FIXED_COLOR_FG + * @arg @ref LL_DMA2D_MODE_M2M_BLEND_FIXED_COLOR_BG + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetMode(DMA2D_TypeDef *DMA2Dx, uint32_t Mode) +{ + MODIFY_REG(DMA2Dx->CR, DMA2D_CR_MODE, Mode); +} + +/** + * @brief Return DMA2D mode + * @rmtoll CR MODE LL_DMA2D_GetMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_MODE_M2M + * @arg @ref LL_DMA2D_MODE_M2M_PFC + * @arg @ref LL_DMA2D_MODE_M2M_BLEND + * @arg @ref LL_DMA2D_MODE_R2M + * @arg @ref LL_DMA2D_MODE_M2M_BLEND_FIXED_COLOR_FG + * @arg @ref LL_DMA2D_MODE_M2M_BLEND_FIXED_COLOR_BG + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->CR, DMA2D_CR_MODE)); +} + +/** + * @brief Set DMA2D output color mode. + * @rmtoll OPFCCR CM LL_DMA2D_SetOutputColorMode + * @param DMA2Dx DMA2D Instance + * @param ColorMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_OUTPUT_MODE_ARGB8888 + * @arg @ref LL_DMA2D_OUTPUT_MODE_RGB888 + * @arg @ref LL_DMA2D_OUTPUT_MODE_RGB565 + * @arg @ref LL_DMA2D_OUTPUT_MODE_ARGB1555 + * @arg @ref LL_DMA2D_OUTPUT_MODE_ARGB4444 + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetOutputColorMode(DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode) +{ + MODIFY_REG(DMA2Dx->OPFCCR, DMA2D_OPFCCR_CM, ColorMode); +} + +/** + * @brief Return DMA2D output color mode. + * @rmtoll OPFCCR CM LL_DMA2D_GetOutputColorMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_OUTPUT_MODE_ARGB8888 + * @arg @ref LL_DMA2D_OUTPUT_MODE_RGB888 + * @arg @ref LL_DMA2D_OUTPUT_MODE_RGB565 + * @arg @ref LL_DMA2D_OUTPUT_MODE_ARGB1555 + * @arg @ref LL_DMA2D_OUTPUT_MODE_ARGB4444 + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetOutputColorMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->OPFCCR, DMA2D_OPFCCR_CM)); +} + +/** + * @brief Set DMA2D output Red Blue swap mode. + * @rmtoll OPFCCR RBS LL_DMA2D_SetOutputRBSwapMode + * @param DMA2Dx DMA2D Instance + * @param RBSwapMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_RB_MODE_REGULAR + * @arg @ref LL_DMA2D_RB_MODE_SWAP + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetOutputRBSwapMode(DMA2D_TypeDef *DMA2Dx, uint32_t RBSwapMode) +{ + MODIFY_REG(DMA2Dx->OPFCCR, DMA2D_OPFCCR_RBS, RBSwapMode); +} + +/** + * @brief Return DMA2D output Red Blue swap mode. + * @rmtoll OPFCCR RBS LL_DMA2D_GetOutputRBSwapMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_RB_MODE_REGULAR + * @arg @ref LL_DMA2D_RB_MODE_SWAP + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetOutputRBSwapMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->OPFCCR, DMA2D_OPFCCR_RBS)); +} + +/** + * @brief Set DMA2D output alpha inversion mode. + * @rmtoll OPFCCR AI LL_DMA2D_SetOutputAlphaInvMode + * @param DMA2Dx DMA2D Instance + * @param AlphaInversionMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_REGULAR + * @arg @ref LL_DMA2D_ALPHA_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetOutputAlphaInvMode(DMA2D_TypeDef *DMA2Dx, uint32_t AlphaInversionMode) +{ + MODIFY_REG(DMA2Dx->OPFCCR, DMA2D_OPFCCR_AI, AlphaInversionMode); +} + +/** + * @brief Return DMA2D output alpha inversion mode. + * @rmtoll OPFCCR AI LL_DMA2D_GetOutputAlphaInvMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_REGULAR + * @arg @ref LL_DMA2D_ALPHA_INVERTED + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetOutputAlphaInvMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->OPFCCR, DMA2D_OPFCCR_AI)); +} + + +/** + * @brief Set DMA2D output swap mode. + * @rmtoll OPFCCR SB LL_DMA2D_SetOutputSwapMode + * @param DMA2Dx DMA2D Instance + * @param OutputSwapMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_SWAP_MODE_REGULAR + * @arg @ref LL_DMA2D_SWAP_MODE_TWO_BY_TWO + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetOutputSwapMode(DMA2D_TypeDef *DMA2Dx, uint32_t OutputSwapMode) +{ + MODIFY_REG(DMA2Dx->OPFCCR, DMA2D_OPFCCR_SB, OutputSwapMode); +} + +/** + * @brief Return DMA2D output swap mode. + * @rmtoll OPFCCR SB LL_DMA2D_GetOutputSwapMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_SWAP_MODE_REGULAR + * @arg @ref LL_DMA2D_SWAP_MODE_TWO_BY_TWO + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetOutputSwapMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->OPFCCR, DMA2D_OPFCCR_SB)); +} + +/** + * @brief Set DMA2D line offset mode. + * @rmtoll CR LOM LL_DMA2D_SetLineOffsetMode + * @param DMA2Dx DMA2D Instance + * @param LineOffsetMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_LINE_OFFSET_PIXELS + * @arg @ref LL_DMA2D_LINE_OFFSET_BYTES + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetLineOffsetMode(DMA2D_TypeDef *DMA2Dx, uint32_t LineOffsetMode) +{ + MODIFY_REG(DMA2Dx->CR, DMA2D_CR_LOM, LineOffsetMode); +} + +/** + * @brief Return DMA2D line offset mode. + * @rmtoll CR LOM LL_DMA2D_GetLineOffsetMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_LINE_OFFSET_PIXELS + * @arg @ref LL_DMA2D_LINE_OFFSET_BYTES + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetLineOffsetMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->CR, DMA2D_CR_LOM)); +} + +/** + * @brief Set DMA2D line offset, expressed on 14 bits ([13:0] bits). + * @rmtoll OOR LO LL_DMA2D_SetLineOffset + * @param DMA2Dx DMA2D Instance + * @param LineOffset Value between Min_Data=0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetLineOffset(DMA2D_TypeDef *DMA2Dx, uint32_t LineOffset) +{ + MODIFY_REG(DMA2Dx->OOR, DMA2D_OOR_LO, LineOffset); +} + +/** + * @brief Return DMA2D line offset, expressed on 14 bits ([13:0] bits). + * @rmtoll OOR LO LL_DMA2D_GetLineOffset + * @param DMA2Dx DMA2D Instance + * @retval Line offset value between Min_Data=0 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetLineOffset(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->OOR, DMA2D_OOR_LO)); +} + +/** + * @brief Set DMA2D number of pixels per lines, expressed on 14 bits ([13:0] bits). + * @rmtoll NLR PL LL_DMA2D_SetNbrOfPixelsPerLines + * @param DMA2Dx DMA2D Instance + * @param NbrOfPixelsPerLines Value between Min_Data=0 and Max_Data=0x3FFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetNbrOfPixelsPerLines(DMA2D_TypeDef *DMA2Dx, uint32_t NbrOfPixelsPerLines) +{ + MODIFY_REG(DMA2Dx->NLR, DMA2D_NLR_PL, (NbrOfPixelsPerLines << DMA2D_NLR_PL_Pos)); +} + +/** + * @brief Return DMA2D number of pixels per lines, expressed on 14 bits ([13:0] bits) + * @rmtoll NLR PL LL_DMA2D_GetNbrOfPixelsPerLines + * @param DMA2Dx DMA2D Instance + * @retval Number of pixels per lines value between Min_Data=0 and Max_Data=0x3FFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetNbrOfPixelsPerLines(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->NLR, DMA2D_NLR_PL) >> DMA2D_NLR_PL_Pos); +} + +/** + * @brief Set DMA2D number of lines, expressed on 16 bits ([15:0] bits). + * @rmtoll NLR NL LL_DMA2D_SetNbrOfLines + * @param DMA2Dx DMA2D Instance + * @param NbrOfLines Value between Min_Data=0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetNbrOfLines(DMA2D_TypeDef *DMA2Dx, uint32_t NbrOfLines) +{ + MODIFY_REG(DMA2Dx->NLR, DMA2D_NLR_NL, NbrOfLines); +} + +/** + * @brief Return DMA2D number of lines, expressed on 16 bits ([15:0] bits). + * @rmtoll NLR NL LL_DMA2D_GetNbrOfLines + * @param DMA2Dx DMA2D Instance + * @retval Number of lines value between Min_Data=0 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetNbrOfLines(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->NLR, DMA2D_NLR_NL)); +} + +/** + * @brief Set DMA2D output memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll OMAR MA LL_DMA2D_SetOutputMemAddr + * @param DMA2Dx DMA2D Instance + * @param OutputMemoryAddress Value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetOutputMemAddr(DMA2D_TypeDef *DMA2Dx, uint32_t OutputMemoryAddress) +{ + LL_DMA2D_WriteReg(DMA2Dx, OMAR, OutputMemoryAddress); +} + +/** + * @brief Get DMA2D output memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll OMAR MA LL_DMA2D_GetOutputMemAddr + * @param DMA2Dx DMA2D Instance + * @retval Output memory address value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetOutputMemAddr(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(LL_DMA2D_ReadReg(DMA2Dx, OMAR)); +} + +/** + * @brief Set DMA2D output color, expressed on 32 bits ([31:0] bits). + * @note Output color format depends on output color mode, ARGB8888, RGB888, + * RGB565, ARGB1555 or ARGB4444. + * @note LL_DMA2D_ConfigOutputColor() API may be used instead if colors values formatting + * with respect to color mode is not done by the user code. + * @rmtoll OCOLR BLUE LL_DMA2D_SetOutputColor\n + * OCOLR GREEN LL_DMA2D_SetOutputColor\n + * OCOLR RED LL_DMA2D_SetOutputColor\n + * OCOLR ALPHA LL_DMA2D_SetOutputColor + * @param DMA2Dx DMA2D Instance + * @param OutputColor Value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetOutputColor(DMA2D_TypeDef *DMA2Dx, uint32_t OutputColor) +{ + WRITE_REG(DMA2Dx->OCOLR, OutputColor); +} + +/** + * @brief Get DMA2D output color, expressed on 32 bits ([31:0] bits). + * @note Alpha channel and red, green, blue color values must be retrieved from the returned + * value based on the output color mode (ARGB8888, RGB888, RGB565, ARGB1555 or ARGB4444) + * as set by @ref LL_DMA2D_SetOutputColorMode. + * @rmtoll OCOLR BLUE LL_DMA2D_GetOutputColor\n + * OCOLR GREEN LL_DMA2D_GetOutputColor\n + * OCOLR RED LL_DMA2D_GetOutputColor\n + * OCOLR ALPHA LL_DMA2D_GetOutputColor + * @param DMA2Dx DMA2D Instance + * @retval Output color value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetOutputColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->OCOLR, \ + (DMA2D_OCOLR_BLUE_1 | DMA2D_OCOLR_GREEN_1 | DMA2D_OCOLR_RED_1 | DMA2D_OCOLR_ALPHA_1))); +} + +/** + * @brief Set DMA2D line watermark, expressed on 16 bits ([15:0] bits). + * @rmtoll LWR LW LL_DMA2D_SetLineWatermark + * @param DMA2Dx DMA2D Instance + * @param LineWatermark Value between Min_Data=0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetLineWatermark(DMA2D_TypeDef *DMA2Dx, uint32_t LineWatermark) +{ + MODIFY_REG(DMA2Dx->LWR, DMA2D_LWR_LW, LineWatermark); +} + +/** + * @brief Return DMA2D line watermark, expressed on 16 bits ([15:0] bits). + * @rmtoll LWR LW LL_DMA2D_GetLineWatermark + * @param DMA2Dx DMA2D Instance + * @retval Line watermark value between Min_Data=0 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetLineWatermark(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->LWR, DMA2D_LWR_LW)); +} + +/** + * @brief Set DMA2D dead time, expressed on 8 bits ([7:0] bits). + * @rmtoll AMTCR DT LL_DMA2D_SetDeadTime + * @param DMA2Dx DMA2D Instance + * @param DeadTime Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_SetDeadTime(DMA2D_TypeDef *DMA2Dx, uint32_t DeadTime) +{ + MODIFY_REG(DMA2Dx->AMTCR, DMA2D_AMTCR_DT, (DeadTime << DMA2D_AMTCR_DT_Pos)); +} + +/** + * @brief Return DMA2D dead time, expressed on 8 bits ([7:0] bits). + * @rmtoll AMTCR DT LL_DMA2D_GetDeadTime + * @param DMA2Dx DMA2D Instance + * @retval Dead time value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_GetDeadTime(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->AMTCR, DMA2D_AMTCR_DT) >> DMA2D_AMTCR_DT_Pos); +} + +/** + * @brief Enable DMA2D dead time functionality. + * @rmtoll AMTCR EN LL_DMA2D_EnableDeadTime + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableDeadTime(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->AMTCR, DMA2D_AMTCR_EN); +} + +/** + * @brief Disable DMA2D dead time functionality. + * @rmtoll AMTCR EN LL_DMA2D_DisableDeadTime + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableDeadTime(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->AMTCR, DMA2D_AMTCR_EN); +} + +/** + * @brief Indicate if DMA2D dead time functionality is enabled. + * @rmtoll AMTCR EN LL_DMA2D_IsEnabledDeadTime + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledDeadTime(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->AMTCR, DMA2D_AMTCR_EN) == (DMA2D_AMTCR_EN)) ? 1UL : 0UL); +} + +/** @defgroup DMA2D_LL_EF_FGND_Configuration Foreground Configuration Functions + * @{ + */ + +/** + * @brief Set DMA2D foreground memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll FGMAR MA LL_DMA2D_FGND_SetMemAddr + * @param DMA2Dx DMA2D Instance + * @param MemoryAddress Value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetMemAddr(DMA2D_TypeDef *DMA2Dx, uint32_t MemoryAddress) +{ + LL_DMA2D_WriteReg(DMA2Dx, FGMAR, MemoryAddress); +} + +/** + * @brief Get DMA2D foreground memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll FGMAR MA LL_DMA2D_FGND_GetMemAddr + * @param DMA2Dx DMA2D Instance + * @retval Foreground memory address value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetMemAddr(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(LL_DMA2D_ReadReg(DMA2Dx, FGMAR)); +} + +/** + * @brief Enable DMA2D foreground CLUT loading. + * @rmtoll FGPFCCR START LL_DMA2D_FGND_EnableCLUTLoad + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_EnableCLUTLoad(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_START); +} + +/** + * @brief Indicate if DMA2D foreground CLUT loading is enabled. + * @rmtoll FGPFCCR START LL_DMA2D_FGND_IsEnabledCLUTLoad + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_IsEnabledCLUTLoad(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_START) == (DMA2D_FGPFCCR_START)) ? 1UL : 0UL); +} + +/** + * @brief Set DMA2D foreground color mode. + * @rmtoll FGPFCCR CM LL_DMA2D_FGND_SetColorMode + * @param DMA2Dx DMA2D Instance + * @param ColorMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB8888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB565 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB1555 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB4444 + * @arg @ref LL_DMA2D_INPUT_MODE_L8 + * @arg @ref LL_DMA2D_INPUT_MODE_AL44 + * @arg @ref LL_DMA2D_INPUT_MODE_AL88 + * @arg @ref LL_DMA2D_INPUT_MODE_L4 + * @arg @ref LL_DMA2D_INPUT_MODE_A8 + * @arg @ref LL_DMA2D_INPUT_MODE_A4 + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetColorMode(DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CM, ColorMode); +} + +/** + * @brief Return DMA2D foreground color mode. + * @rmtoll FGPFCCR CM LL_DMA2D_FGND_GetColorMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB8888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB565 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB1555 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB4444 + * @arg @ref LL_DMA2D_INPUT_MODE_L8 + * @arg @ref LL_DMA2D_INPUT_MODE_AL44 + * @arg @ref LL_DMA2D_INPUT_MODE_AL88 + * @arg @ref LL_DMA2D_INPUT_MODE_L4 + * @arg @ref LL_DMA2D_INPUT_MODE_A8 + * @arg @ref LL_DMA2D_INPUT_MODE_A4 + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetColorMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CM)); +} + +/** + * @brief Set DMA2D foreground alpha mode. + * @rmtoll FGPFCCR AM LL_DMA2D_FGND_SetAlphaMode + * @param DMA2Dx DMA2D Instance + * @param AphaMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_MODE_NO_MODIF + * @arg @ref LL_DMA2D_ALPHA_MODE_REPLACE + * @arg @ref LL_DMA2D_ALPHA_MODE_COMBINE + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetAlphaMode(DMA2D_TypeDef *DMA2Dx, uint32_t AphaMode) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_AM, AphaMode); +} + +/** + * @brief Return DMA2D foreground alpha mode. + * @rmtoll FGPFCCR AM LL_DMA2D_FGND_GetAlphaMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_MODE_NO_MODIF + * @arg @ref LL_DMA2D_ALPHA_MODE_REPLACE + * @arg @ref LL_DMA2D_ALPHA_MODE_COMBINE + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetAlphaMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_AM)); +} + +/** + * @brief Set DMA2D foreground alpha value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGPFCCR ALPHA LL_DMA2D_FGND_SetAlpha + * @param DMA2Dx DMA2D Instance + * @param Alpha Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetAlpha(DMA2D_TypeDef *DMA2Dx, uint32_t Alpha) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_ALPHA, (Alpha << DMA2D_FGPFCCR_ALPHA_Pos)); +} + +/** + * @brief Return DMA2D foreground alpha value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGPFCCR ALPHA LL_DMA2D_FGND_GetAlpha + * @param DMA2Dx DMA2D Instance + * @retval Alpha value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetAlpha(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_ALPHA) >> DMA2D_FGPFCCR_ALPHA_Pos); +} + +/** + * @brief Set DMA2D foreground Red Blue swap mode. + * @rmtoll FGPFCCR RBS LL_DMA2D_FGND_SetRBSwapMode + * @param DMA2Dx DMA2D Instance + * @param RBSwapMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_RB_MODE_REGULAR + * @arg @ref LL_DMA2D_RB_MODE_SWAP + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetRBSwapMode(DMA2D_TypeDef *DMA2Dx, uint32_t RBSwapMode) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_RBS, RBSwapMode); +} + +/** + * @brief Return DMA2D foreground Red Blue swap mode. + * @rmtoll FGPFCCR RBS LL_DMA2D_FGND_GetRBSwapMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_RB_MODE_REGULAR + * @arg @ref LL_DMA2D_RB_MODE_SWAP + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetRBSwapMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_RBS)); +} + +/** + * @brief Set DMA2D foreground alpha inversion mode. + * @rmtoll FGPFCCR AI LL_DMA2D_FGND_SetAlphaInvMode + * @param DMA2Dx DMA2D Instance + * @param AlphaInversionMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_REGULAR + * @arg @ref LL_DMA2D_ALPHA_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetAlphaInvMode(DMA2D_TypeDef *DMA2Dx, uint32_t AlphaInversionMode) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_AI, AlphaInversionMode); +} + +/** + * @brief Return DMA2D foreground alpha inversion mode. + * @rmtoll FGPFCCR AI LL_DMA2D_FGND_GetAlphaInvMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_REGULAR + * @arg @ref LL_DMA2D_ALPHA_INVERTED + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetAlphaInvMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_AI)); +} + +/** + * @brief Set DMA2D foreground line offset, expressed on 14 bits ([13:0] bits). + * @rmtoll FGOR LO LL_DMA2D_FGND_SetLineOffset + * @param DMA2Dx DMA2D Instance + * @param LineOffset Value between Min_Data=0 and Max_Data=0x3FF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetLineOffset(DMA2D_TypeDef *DMA2Dx, uint32_t LineOffset) +{ + MODIFY_REG(DMA2Dx->FGOR, DMA2D_FGOR_LO, LineOffset); +} + +/** + * @brief Return DMA2D foreground line offset, expressed on 14 bits ([13:0] bits). + * @rmtoll FGOR LO LL_DMA2D_FGND_GetLineOffset + * @param DMA2Dx DMA2D Instance + * @retval Foreground line offset value between Min_Data=0 and Max_Data=0x3FF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetLineOffset(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGOR, DMA2D_FGOR_LO)); +} + +/** + * @brief Set DMA2D foreground color values, expressed on 24 bits ([23:0] bits). + * @rmtoll FGCOLR RED LL_DMA2D_FGND_SetColor + * @rmtoll FGCOLR GREEN LL_DMA2D_FGND_SetColor + * @rmtoll FGCOLR BLUE LL_DMA2D_FGND_SetColor + * @param DMA2Dx DMA2D Instance + * @param Red Value between Min_Data=0 and Max_Data=0xFF + * @param Green Value between Min_Data=0 and Max_Data=0xFF + * @param Blue Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetColor(DMA2D_TypeDef *DMA2Dx, uint32_t Red, uint32_t Green, uint32_t Blue) +{ + MODIFY_REG(DMA2Dx->FGCOLR, (DMA2D_FGCOLR_RED | DMA2D_FGCOLR_GREEN | DMA2D_FGCOLR_BLUE), \ + ((Red << DMA2D_FGCOLR_RED_Pos) | (Green << DMA2D_FGCOLR_GREEN_Pos) | Blue)); +} + +/** + * @brief Set DMA2D foreground red color value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGCOLR RED LL_DMA2D_FGND_SetRedColor + * @param DMA2Dx DMA2D Instance + * @param Red Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetRedColor(DMA2D_TypeDef *DMA2Dx, uint32_t Red) +{ + MODIFY_REG(DMA2Dx->FGCOLR, DMA2D_FGCOLR_RED, (Red << DMA2D_FGCOLR_RED_Pos)); +} + +/** + * @brief Return DMA2D foreground red color value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGCOLR RED LL_DMA2D_FGND_GetRedColor + * @param DMA2Dx DMA2D Instance + * @retval Red color value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetRedColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGCOLR, DMA2D_FGCOLR_RED) >> DMA2D_FGCOLR_RED_Pos); +} + +/** + * @brief Set DMA2D foreground green color value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGCOLR GREEN LL_DMA2D_FGND_SetGreenColor + * @param DMA2Dx DMA2D Instance + * @param Green Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetGreenColor(DMA2D_TypeDef *DMA2Dx, uint32_t Green) +{ + MODIFY_REG(DMA2Dx->FGCOLR, DMA2D_FGCOLR_GREEN, (Green << DMA2D_FGCOLR_GREEN_Pos)); +} + +/** + * @brief Return DMA2D foreground green color value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGCOLR GREEN LL_DMA2D_FGND_GetGreenColor + * @param DMA2Dx DMA2D Instance + * @retval Green color value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetGreenColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGCOLR, DMA2D_FGCOLR_GREEN) >> DMA2D_FGCOLR_GREEN_Pos); +} + +/** + * @brief Set DMA2D foreground blue color value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGCOLR BLUE LL_DMA2D_FGND_SetBlueColor + * @param DMA2Dx DMA2D Instance + * @param Blue Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetBlueColor(DMA2D_TypeDef *DMA2Dx, uint32_t Blue) +{ + MODIFY_REG(DMA2Dx->FGCOLR, DMA2D_FGCOLR_BLUE, Blue); +} + +/** + * @brief Return DMA2D foreground blue color value, expressed on 8 bits ([7:0] bits). + * @rmtoll FGCOLR BLUE LL_DMA2D_FGND_GetBlueColor + * @param DMA2Dx DMA2D Instance + * @retval Blue color value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetBlueColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGCOLR, DMA2D_FGCOLR_BLUE)); +} + +/** + * @brief Set DMA2D foreground CLUT memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll FGCMAR MA LL_DMA2D_FGND_SetCLUTMemAddr + * @param DMA2Dx DMA2D Instance + * @param CLUTMemoryAddress Value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetCLUTMemAddr(DMA2D_TypeDef *DMA2Dx, uint32_t CLUTMemoryAddress) +{ + LL_DMA2D_WriteReg(DMA2Dx, FGCMAR, CLUTMemoryAddress); +} + +/** + * @brief Get DMA2D foreground CLUT memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll FGCMAR MA LL_DMA2D_FGND_GetCLUTMemAddr + * @param DMA2Dx DMA2D Instance + * @retval Foreground CLUT memory address value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetCLUTMemAddr(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(LL_DMA2D_ReadReg(DMA2Dx, FGCMAR)); +} + +/** + * @brief Set DMA2D foreground CLUT size, expressed on 8 bits ([7:0] bits). + * @rmtoll FGPFCCR CS LL_DMA2D_FGND_SetCLUTSize + * @param DMA2Dx DMA2D Instance + * @param CLUTSize Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetCLUTSize(DMA2D_TypeDef *DMA2Dx, uint32_t CLUTSize) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CS, (CLUTSize << DMA2D_FGPFCCR_CS_Pos)); +} + +/** + * @brief Get DMA2D foreground CLUT size, expressed on 8 bits ([7:0] bits). + * @rmtoll FGPFCCR CS LL_DMA2D_FGND_GetCLUTSize + * @param DMA2Dx DMA2D Instance + * @retval Foreground CLUT size value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetCLUTSize(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CS) >> DMA2D_FGPFCCR_CS_Pos); +} + +/** + * @brief Set DMA2D foreground CLUT color mode. + * @rmtoll FGPFCCR CCM LL_DMA2D_FGND_SetCLUTColorMode + * @param DMA2Dx DMA2D Instance + * @param CLUTColorMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_ARGB8888 + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_RGB888 + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetCLUTColorMode(DMA2D_TypeDef *DMA2Dx, uint32_t CLUTColorMode) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CCM, CLUTColorMode); +} + +/** + * @brief Return DMA2D foreground CLUT color mode. + * @rmtoll FGPFCCR CCM LL_DMA2D_FGND_GetCLUTColorMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_ARGB8888 + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_RGB888 + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetCLUTColorMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CCM)); +} + +/** + * @brief Set DMA2D foreground Chroma Sub Sampling (for YCbCr input color mode). + * @rmtoll FGPFCCR CSS LL_DMA2D_FGND_SetChrSubSampling + * @param DMA2Dx DMA2D Instance + * @param ChromaSubSampling This parameter can be one of the following values: + * @arg @ref LL_DMA2D_CSS_444 + * @arg @ref LL_DMA2D_CSS_422 + * @arg @ref LL_DMA2D_CSS_420 + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_FGND_SetChrSubSampling(DMA2D_TypeDef *DMA2Dx, uint32_t ChromaSubSampling) +{ + MODIFY_REG(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CSS, ChromaSubSampling); +} + +/** + * @brief Return DMA2D foreground Chroma Sub Sampling (for YCbCr input color mode). + * @rmtoll FGPFCCR CSS LL_DMA2D_FGND_GetChrSubSampling + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_CSS_444 + * @arg @ref LL_DMA2D_CSS_422 + * @arg @ref LL_DMA2D_CSS_420 + */ +__STATIC_INLINE uint32_t LL_DMA2D_FGND_GetChrSubSampling(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->FGPFCCR, DMA2D_FGPFCCR_CSS)); +} +/** + * @} + */ + +/** @defgroup DMA2D_LL_EF_BGND_Configuration Background Configuration Functions + * @{ + */ + +/** + * @brief Set DMA2D background memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll BGMAR MA LL_DMA2D_BGND_SetMemAddr + * @param DMA2Dx DMA2D Instance + * @param MemoryAddress Value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetMemAddr(DMA2D_TypeDef *DMA2Dx, uint32_t MemoryAddress) +{ + LL_DMA2D_WriteReg(DMA2Dx, BGMAR, MemoryAddress); +} + +/** + * @brief Get DMA2D background memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll BGMAR MA LL_DMA2D_BGND_GetMemAddr + * @param DMA2Dx DMA2D Instance + * @retval Background memory address value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetMemAddr(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(LL_DMA2D_ReadReg(DMA2Dx, BGMAR)); +} + +/** + * @brief Enable DMA2D background CLUT loading. + * @rmtoll BGPFCCR START LL_DMA2D_BGND_EnableCLUTLoad + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_EnableCLUTLoad(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_START); +} + +/** + * @brief Indicate if DMA2D background CLUT loading is enabled. + * @rmtoll BGPFCCR START LL_DMA2D_BGND_IsEnabledCLUTLoad + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_IsEnabledCLUTLoad(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_START) == (DMA2D_BGPFCCR_START)) ? 1UL : 0UL); +} + +/** + * @brief Set DMA2D background color mode. + * @rmtoll BGPFCCR CM LL_DMA2D_BGND_SetColorMode + * @param DMA2Dx DMA2D Instance + * @param ColorMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB8888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB565 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB1555 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB4444 + * @arg @ref LL_DMA2D_INPUT_MODE_L8 + * @arg @ref LL_DMA2D_INPUT_MODE_AL44 + * @arg @ref LL_DMA2D_INPUT_MODE_AL88 + * @arg @ref LL_DMA2D_INPUT_MODE_L4 + * @arg @ref LL_DMA2D_INPUT_MODE_A8 + * @arg @ref LL_DMA2D_INPUT_MODE_A4 + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetColorMode(DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_CM, ColorMode); +} + +/** + * @brief Return DMA2D background color mode. + * @rmtoll BGPFCCR CM LL_DMA2D_BGND_GetColorMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB8888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB888 + * @arg @ref LL_DMA2D_INPUT_MODE_RGB565 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB1555 + * @arg @ref LL_DMA2D_INPUT_MODE_ARGB4444 + * @arg @ref LL_DMA2D_INPUT_MODE_L8 + * @arg @ref LL_DMA2D_INPUT_MODE_AL44 + * @arg @ref LL_DMA2D_INPUT_MODE_AL88 + * @arg @ref LL_DMA2D_INPUT_MODE_L4 + * @arg @ref LL_DMA2D_INPUT_MODE_A8 + * @arg @ref LL_DMA2D_INPUT_MODE_A4 + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetColorMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_CM)); +} + +/** + * @brief Set DMA2D background alpha mode. + * @rmtoll BGPFCCR AM LL_DMA2D_BGND_SetAlphaMode + * @param DMA2Dx DMA2D Instance + * @param AphaMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_MODE_NO_MODIF + * @arg @ref LL_DMA2D_ALPHA_MODE_REPLACE + * @arg @ref LL_DMA2D_ALPHA_MODE_COMBINE + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetAlphaMode(DMA2D_TypeDef *DMA2Dx, uint32_t AphaMode) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_AM, AphaMode); +} + +/** + * @brief Return DMA2D background alpha mode. + * @rmtoll BGPFCCR AM LL_DMA2D_BGND_GetAlphaMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_MODE_NO_MODIF + * @arg @ref LL_DMA2D_ALPHA_MODE_REPLACE + * @arg @ref LL_DMA2D_ALPHA_MODE_COMBINE + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetAlphaMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_AM)); +} + +/** + * @brief Set DMA2D background alpha value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGPFCCR ALPHA LL_DMA2D_BGND_SetAlpha + * @param DMA2Dx DMA2D Instance + * @param Alpha Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetAlpha(DMA2D_TypeDef *DMA2Dx, uint32_t Alpha) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_ALPHA, (Alpha << DMA2D_BGPFCCR_ALPHA_Pos)); +} + +/** + * @brief Return DMA2D background alpha value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGPFCCR ALPHA LL_DMA2D_BGND_GetAlpha + * @param DMA2Dx DMA2D Instance + * @retval Alpha value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetAlpha(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_ALPHA) >> DMA2D_BGPFCCR_ALPHA_Pos); +} + +/** + * @brief Set DMA2D background Red Blue swap mode. + * @rmtoll BGPFCCR RBS LL_DMA2D_BGND_SetRBSwapMode + * @param DMA2Dx DMA2D Instance + * @param RBSwapMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_RB_MODE_REGULAR + * @arg @ref LL_DMA2D_RB_MODE_SWAP + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetRBSwapMode(DMA2D_TypeDef *DMA2Dx, uint32_t RBSwapMode) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_RBS, RBSwapMode); +} + +/** + * @brief Return DMA2D background Red Blue swap mode. + * @rmtoll BGPFCCR RBS LL_DMA2D_BGND_GetRBSwapMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_RB_MODE_REGULAR + * @arg @ref LL_DMA2D_RB_MODE_SWAP + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetRBSwapMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_RBS)); +} + +/** + * @brief Set DMA2D background alpha inversion mode. + * @rmtoll BGPFCCR AI LL_DMA2D_BGND_SetAlphaInvMode + * @param DMA2Dx DMA2D Instance + * @param AlphaInversionMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_REGULAR + * @arg @ref LL_DMA2D_ALPHA_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetAlphaInvMode(DMA2D_TypeDef *DMA2Dx, uint32_t AlphaInversionMode) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_AI, AlphaInversionMode); +} + +/** + * @brief Return DMA2D background alpha inversion mode. + * @rmtoll BGPFCCR AI LL_DMA2D_BGND_GetAlphaInvMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_ALPHA_REGULAR + * @arg @ref LL_DMA2D_ALPHA_INVERTED + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetAlphaInvMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_AI)); +} + +/** + * @brief Set DMA2D background line offset, expressed on 14 bits ([13:0] bits). + * @rmtoll BGOR LO LL_DMA2D_BGND_SetLineOffset + * @param DMA2Dx DMA2D Instance + * @param LineOffset Value between Min_Data=0 and Max_Data=0x3FF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetLineOffset(DMA2D_TypeDef *DMA2Dx, uint32_t LineOffset) +{ + MODIFY_REG(DMA2Dx->BGOR, DMA2D_BGOR_LO, LineOffset); +} + +/** + * @brief Return DMA2D background line offset, expressed on 14 bits ([13:0] bits). + * @rmtoll BGOR LO LL_DMA2D_BGND_GetLineOffset + * @param DMA2Dx DMA2D Instance + * @retval Background line offset value between Min_Data=0 and Max_Data=0x3FF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetLineOffset(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGOR, DMA2D_BGOR_LO)); +} + +/** + * @brief Set DMA2D background color values, expressed on 24 bits ([23:0] bits). + * @rmtoll BGCOLR RED LL_DMA2D_BGND_SetColor + * @rmtoll BGCOLR GREEN LL_DMA2D_BGND_SetColor + * @rmtoll BGCOLR BLUE LL_DMA2D_BGND_SetColor + * @param DMA2Dx DMA2D Instance + * @param Red Value between Min_Data=0 and Max_Data=0xFF + * @param Green Value between Min_Data=0 and Max_Data=0xFF + * @param Blue Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetColor(DMA2D_TypeDef *DMA2Dx, uint32_t Red, uint32_t Green, uint32_t Blue) +{ + MODIFY_REG(DMA2Dx->BGCOLR, (DMA2D_BGCOLR_RED | DMA2D_BGCOLR_GREEN | DMA2D_BGCOLR_BLUE), \ + ((Red << DMA2D_BGCOLR_RED_Pos) | (Green << DMA2D_BGCOLR_GREEN_Pos) | Blue)); +} + +/** + * @brief Set DMA2D background red color value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGCOLR RED LL_DMA2D_BGND_SetRedColor + * @param DMA2Dx DMA2D Instance + * @param Red Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetRedColor(DMA2D_TypeDef *DMA2Dx, uint32_t Red) +{ + MODIFY_REG(DMA2Dx->BGCOLR, DMA2D_BGCOLR_RED, (Red << DMA2D_BGCOLR_RED_Pos)); +} + +/** + * @brief Return DMA2D background red color value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGCOLR RED LL_DMA2D_BGND_GetRedColor + * @param DMA2Dx DMA2D Instance + * @retval Red color value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetRedColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGCOLR, DMA2D_BGCOLR_RED) >> DMA2D_BGCOLR_RED_Pos); +} + +/** + * @brief Set DMA2D background green color value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGCOLR GREEN LL_DMA2D_BGND_SetGreenColor + * @param DMA2Dx DMA2D Instance + * @param Green Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetGreenColor(DMA2D_TypeDef *DMA2Dx, uint32_t Green) +{ + MODIFY_REG(DMA2Dx->BGCOLR, DMA2D_BGCOLR_GREEN, (Green << DMA2D_BGCOLR_GREEN_Pos)); +} + +/** + * @brief Return DMA2D background green color value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGCOLR GREEN LL_DMA2D_BGND_GetGreenColor + * @param DMA2Dx DMA2D Instance + * @retval Green color value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetGreenColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGCOLR, DMA2D_BGCOLR_GREEN) >> DMA2D_BGCOLR_GREEN_Pos); +} + +/** + * @brief Set DMA2D background blue color value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGCOLR BLUE LL_DMA2D_BGND_SetBlueColor + * @param DMA2Dx DMA2D Instance + * @param Blue Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetBlueColor(DMA2D_TypeDef *DMA2Dx, uint32_t Blue) +{ + MODIFY_REG(DMA2Dx->BGCOLR, DMA2D_BGCOLR_BLUE, Blue); +} + +/** + * @brief Return DMA2D background blue color value, expressed on 8 bits ([7:0] bits). + * @rmtoll BGCOLR BLUE LL_DMA2D_BGND_GetBlueColor + * @param DMA2Dx DMA2D Instance + * @retval Blue color value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetBlueColor(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGCOLR, DMA2D_BGCOLR_BLUE)); +} + +/** + * @brief Set DMA2D background CLUT memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll BGCMAR MA LL_DMA2D_BGND_SetCLUTMemAddr + * @param DMA2Dx DMA2D Instance + * @param CLUTMemoryAddress Value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetCLUTMemAddr(DMA2D_TypeDef *DMA2Dx, uint32_t CLUTMemoryAddress) +{ + LL_DMA2D_WriteReg(DMA2Dx, BGCMAR, CLUTMemoryAddress); +} + +/** + * @brief Get DMA2D background CLUT memory address, expressed on 32 bits ([31:0] bits). + * @rmtoll BGCMAR MA LL_DMA2D_BGND_GetCLUTMemAddr + * @param DMA2Dx DMA2D Instance + * @retval Background CLUT memory address value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetCLUTMemAddr(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(LL_DMA2D_ReadReg(DMA2Dx, BGCMAR)); +} + +/** + * @brief Set DMA2D background CLUT size, expressed on 8 bits ([7:0] bits). + * @rmtoll BGPFCCR CS LL_DMA2D_BGND_SetCLUTSize + * @param DMA2Dx DMA2D Instance + * @param CLUTSize Value between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetCLUTSize(DMA2D_TypeDef *DMA2Dx, uint32_t CLUTSize) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_CS, (CLUTSize << DMA2D_BGPFCCR_CS_Pos)); +} + +/** + * @brief Get DMA2D background CLUT size, expressed on 8 bits ([7:0] bits). + * @rmtoll BGPFCCR CS LL_DMA2D_BGND_GetCLUTSize + * @param DMA2Dx DMA2D Instance + * @retval Background CLUT size value between Min_Data=0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetCLUTSize(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_CS) >> DMA2D_BGPFCCR_CS_Pos); +} + +/** + * @brief Set DMA2D background CLUT color mode. + * @rmtoll BGPFCCR CCM LL_DMA2D_BGND_SetCLUTColorMode + * @param DMA2Dx DMA2D Instance + * @param CLUTColorMode This parameter can be one of the following values: + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_ARGB8888 + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_RGB888 + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_BGND_SetCLUTColorMode(DMA2D_TypeDef *DMA2Dx, uint32_t CLUTColorMode) +{ + MODIFY_REG(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_CCM, CLUTColorMode); +} + +/** + * @brief Return DMA2D background CLUT color mode. + * @rmtoll BGPFCCR CCM LL_DMA2D_BGND_GetCLUTColorMode + * @param DMA2Dx DMA2D Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_ARGB8888 + * @arg @ref LL_DMA2D_CLUT_COLOR_MODE_RGB888 + */ +__STATIC_INLINE uint32_t LL_DMA2D_BGND_GetCLUTColorMode(const DMA2D_TypeDef *DMA2Dx) +{ + return (uint32_t)(READ_BIT(DMA2Dx->BGPFCCR, DMA2D_BGPFCCR_CCM)); +} + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup DMA2D_LL_EF_FLAG_MANAGEMENT Flag Management + * @{ + */ + +/** + * @brief Check if the DMA2D Configuration Error Interrupt Flag is set or not + * @rmtoll ISR CEIF LL_DMA2D_IsActiveFlag_CE + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsActiveFlag_CE(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->ISR, DMA2D_ISR_CEIF) == (DMA2D_ISR_CEIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D CLUT Transfer Complete Interrupt Flag is set or not + * @rmtoll ISR CTCIF LL_DMA2D_IsActiveFlag_CTC + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsActiveFlag_CTC(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->ISR, DMA2D_ISR_CTCIF) == (DMA2D_ISR_CTCIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D CLUT Access Error Interrupt Flag is set or not + * @rmtoll ISR CAEIF LL_DMA2D_IsActiveFlag_CAE + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsActiveFlag_CAE(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->ISR, DMA2D_ISR_CAEIF) == (DMA2D_ISR_CAEIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D Transfer Watermark Interrupt Flag is set or not + * @rmtoll ISR TWIF LL_DMA2D_IsActiveFlag_TW + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsActiveFlag_TW(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->ISR, DMA2D_ISR_TWIF) == (DMA2D_ISR_TWIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D Transfer Complete Interrupt Flag is set or not + * @rmtoll ISR TCIF LL_DMA2D_IsActiveFlag_TC + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsActiveFlag_TC(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->ISR, DMA2D_ISR_TCIF) == (DMA2D_ISR_TCIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D Transfer Error Interrupt Flag is set or not + * @rmtoll ISR TEIF LL_DMA2D_IsActiveFlag_TE + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsActiveFlag_TE(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->ISR, DMA2D_ISR_TEIF) == (DMA2D_ISR_TEIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear DMA2D Configuration Error Interrupt Flag + * @rmtoll IFCR CCEIF LL_DMA2D_ClearFlag_CE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_ClearFlag_CE(DMA2D_TypeDef *DMA2Dx) +{ + WRITE_REG(DMA2Dx->IFCR, DMA2D_IFCR_CCEIF); +} + +/** + * @brief Clear DMA2D CLUT Transfer Complete Interrupt Flag + * @rmtoll IFCR CCTCIF LL_DMA2D_ClearFlag_CTC + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_ClearFlag_CTC(DMA2D_TypeDef *DMA2Dx) +{ + WRITE_REG(DMA2Dx->IFCR, DMA2D_IFCR_CCTCIF); +} + +/** + * @brief Clear DMA2D CLUT Access Error Interrupt Flag + * @rmtoll IFCR CAECIF LL_DMA2D_ClearFlag_CAE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_ClearFlag_CAE(DMA2D_TypeDef *DMA2Dx) +{ + WRITE_REG(DMA2Dx->IFCR, DMA2D_IFCR_CAECIF); +} + +/** + * @brief Clear DMA2D Transfer Watermark Interrupt Flag + * @rmtoll IFCR CTWIF LL_DMA2D_ClearFlag_TW + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_ClearFlag_TW(DMA2D_TypeDef *DMA2Dx) +{ + WRITE_REG(DMA2Dx->IFCR, DMA2D_IFCR_CTWIF); +} + +/** + * @brief Clear DMA2D Transfer Complete Interrupt Flag + * @rmtoll IFCR CTCIF LL_DMA2D_ClearFlag_TC + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_ClearFlag_TC(DMA2D_TypeDef *DMA2Dx) +{ + WRITE_REG(DMA2Dx->IFCR, DMA2D_IFCR_CTCIF); +} + +/** + * @brief Clear DMA2D Transfer Error Interrupt Flag + * @rmtoll IFCR CTEIF LL_DMA2D_ClearFlag_TE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_ClearFlag_TE(DMA2D_TypeDef *DMA2Dx) +{ + WRITE_REG(DMA2Dx->IFCR, DMA2D_IFCR_CTEIF); +} + +/** + * @} + */ + +/** @defgroup DMA2D_LL_EF_IT_MANAGEMENT Interruption Management + * @{ + */ + +/** + * @brief Enable Configuration Error Interrupt + * @rmtoll CR CEIE LL_DMA2D_EnableIT_CE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableIT_CE(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_CEIE); +} + +/** + * @brief Enable CLUT Transfer Complete Interrupt + * @rmtoll CR CTCIE LL_DMA2D_EnableIT_CTC + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableIT_CTC(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_CTCIE); +} + +/** + * @brief Enable CLUT Access Error Interrupt + * @rmtoll CR CAEIE LL_DMA2D_EnableIT_CAE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableIT_CAE(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_CAEIE); +} + +/** + * @brief Enable Transfer Watermark Interrupt + * @rmtoll CR TWIE LL_DMA2D_EnableIT_TW + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableIT_TW(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_TWIE); +} + +/** + * @brief Enable Transfer Complete Interrupt + * @rmtoll CR TCIE LL_DMA2D_EnableIT_TC + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableIT_TC(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_TCIE); +} + +/** + * @brief Enable Transfer Error Interrupt + * @rmtoll CR TEIE LL_DMA2D_EnableIT_TE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_EnableIT_TE(DMA2D_TypeDef *DMA2Dx) +{ + SET_BIT(DMA2Dx->CR, DMA2D_CR_TEIE); +} + +/** + * @brief Disable Configuration Error Interrupt + * @rmtoll CR CEIE LL_DMA2D_DisableIT_CE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableIT_CE(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_CEIE); +} + +/** + * @brief Disable CLUT Transfer Complete Interrupt + * @rmtoll CR CTCIE LL_DMA2D_DisableIT_CTC + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableIT_CTC(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_CTCIE); +} + +/** + * @brief Disable CLUT Access Error Interrupt + * @rmtoll CR CAEIE LL_DMA2D_DisableIT_CAE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableIT_CAE(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_CAEIE); +} + +/** + * @brief Disable Transfer Watermark Interrupt + * @rmtoll CR TWIE LL_DMA2D_DisableIT_TW + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableIT_TW(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_TWIE); +} + +/** + * @brief Disable Transfer Complete Interrupt + * @rmtoll CR TCIE LL_DMA2D_DisableIT_TC + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableIT_TC(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_TCIE); +} + +/** + * @brief Disable Transfer Error Interrupt + * @rmtoll CR TEIE LL_DMA2D_DisableIT_TE + * @param DMA2Dx DMA2D Instance + * @retval None + */ +__STATIC_INLINE void LL_DMA2D_DisableIT_TE(DMA2D_TypeDef *DMA2Dx) +{ + CLEAR_BIT(DMA2Dx->CR, DMA2D_CR_TEIE); +} + +/** + * @brief Check if the DMA2D Configuration Error interrupt source is enabled or disabled. + * @rmtoll CR CEIE LL_DMA2D_IsEnabledIT_CE + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledIT_CE(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_CEIE) == (DMA2D_CR_CEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D CLUT Transfer Complete interrupt source is enabled or disabled. + * @rmtoll CR CTCIE LL_DMA2D_IsEnabledIT_CTC + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledIT_CTC(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_CTCIE) == (DMA2D_CR_CTCIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D CLUT Access Error interrupt source is enabled or disabled. + * @rmtoll CR CAEIE LL_DMA2D_IsEnabledIT_CAE + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledIT_CAE(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_CAEIE) == (DMA2D_CR_CAEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D Transfer Watermark interrupt source is enabled or disabled. + * @rmtoll CR TWIE LL_DMA2D_IsEnabledIT_TW + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledIT_TW(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_TWIE) == (DMA2D_CR_TWIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D Transfer Complete interrupt source is enabled or disabled. + * @rmtoll CR TCIE LL_DMA2D_IsEnabledIT_TC + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledIT_TC(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_TCIE) == (DMA2D_CR_TCIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the DMA2D Transfer Error interrupt source is enabled or disabled. + * @rmtoll CR TEIE LL_DMA2D_IsEnabledIT_TE + * @param DMA2Dx DMA2D Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA2D_IsEnabledIT_TE(const DMA2D_TypeDef *DMA2Dx) +{ + return ((READ_BIT(DMA2Dx->CR, DMA2D_CR_TEIE) == (DMA2D_CR_TEIE)) ? 1UL : 0UL); +} + + + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup DMA2D_LL_EF_Init_Functions Initialization and De-initialization Functions + * @{ + */ + +ErrorStatus LL_DMA2D_DeInit(const DMA2D_TypeDef *DMA2Dx); +ErrorStatus LL_DMA2D_Init(DMA2D_TypeDef *DMA2Dx, LL_DMA2D_InitTypeDef *DMA2D_InitStruct); +void LL_DMA2D_StructInit(LL_DMA2D_InitTypeDef *DMA2D_InitStruct); +void LL_DMA2D_ConfigLayer(DMA2D_TypeDef *DMA2Dx, LL_DMA2D_LayerCfgTypeDef *DMA2D_LayerCfg, uint32_t LayerIdx); +void LL_DMA2D_LayerCfgStructInit(LL_DMA2D_LayerCfgTypeDef *DMA2D_LayerCfg); +void LL_DMA2D_ConfigOutputColor(DMA2D_TypeDef *DMA2Dx, LL_DMA2D_ColorTypeDef *DMA2D_ColorStruct); +uint32_t LL_DMA2D_GetOutputBlueColor(const DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode); +uint32_t LL_DMA2D_GetOutputGreenColor(const DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode); +uint32_t LL_DMA2D_GetOutputRedColor(const DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode); +uint32_t LL_DMA2D_GetOutputAlphaColor(const DMA2D_TypeDef *DMA2Dx, uint32_t ColorMode); +void LL_DMA2D_ConfigSize(DMA2D_TypeDef *DMA2Dx, uint32_t NbrOfLines, uint32_t NbrOfPixelsPerLines); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (DMA2D) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_DMA2D_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_exti.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_exti.h new file mode 100644 index 0000000..ca6590c --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_exti.h @@ -0,0 +1,1505 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_exti.h + * @author MCD Application Team + * @brief Header file of EXTI LL 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 STM32H7RSxx_LL_EXTI_H +#define STM32H7RSxx_LL_EXTI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_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 */ + + uint32_t Line_64_95; /*!< Specifies the EXTI lines to be enabled or disabled for Lines in range 64 to 95 + 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 (LL_EXTI_LINE_0 |LL_EXTI_LINE_1 | LL_EXTI_LINE_2 | LL_EXTI_LINE_3 | \ + LL_EXTI_LINE_4 | LL_EXTI_LINE_5 | LL_EXTI_LINE_6 | LL_EXTI_LINE_7 | \ + LL_EXTI_LINE_8 | LL_EXTI_LINE_9 | LL_EXTI_LINE_10 | LL_EXTI_LINE_11 | \ + LL_EXTI_LINE_12 | LL_EXTI_LINE_13 | LL_EXTI_LINE_14 | LL_EXTI_LINE_15 | \ + LL_EXTI_LINE_16 | LL_EXTI_LINE_17 | LL_EXTI_LINE_18 | LL_EXTI_LINE_19 | \ + LL_EXTI_LINE_20 | LL_EXTI_LINE_21 | LL_EXTI_LINE_22 | LL_EXTI_LINE_23 | \ + LL_EXTI_LINE_24 | LL_EXTI_LINE_25 | LL_EXTI_LINE_26 | LL_EXTI_LINE_27 | \ + LL_EXTI_LINE_28 | LL_EXTI_LINE_29 | LL_EXTI_LINE_30 | LL_EXTI_LINE_31) +/*!< 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 */ +#define LL_EXTI_LINE_46 EXTI_IMR2_IM46 /*!< Extended line 46 */ +#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_58 EXTI_IMR2_IM58 /*!< Extended line 58 */ +#define LL_EXTI_LINE_59 EXTI_IMR2_IM59 /*!< Extended line 59 */ +#define LL_EXTI_LINE_ALL_32_63 (LL_EXTI_LINE_32 | LL_EXTI_LINE_33 | LL_EXTI_LINE_34 | LL_EXTI_LINE_35 | \ + LL_EXTI_LINE_36 | LL_EXTI_LINE_37 | LL_EXTI_LINE_38 | LL_EXTI_LINE_39 | \ + LL_EXTI_LINE_40 | LL_EXTI_LINE_41 | LL_EXTI_LINE_42 | LL_EXTI_LINE_43 | \ + LL_EXTI_LINE_44 | LL_EXTI_LINE_45 | LL_EXTI_LINE_46 | LL_EXTI_LINE_47 | \ + LL_EXTI_LINE_48 | LL_EXTI_LINE_49 | LL_EXTI_LINE_50 | LL_EXTI_LINE_51 | \ + LL_EXTI_LINE_52 | LL_EXTI_LINE_53 | LL_EXTI_LINE_54 | LL_EXTI_LINE_55 | \ + LL_EXTI_LINE_56 | LL_EXTI_LINE_57 | LL_EXTI_LINE_58 | LL_EXTI_LINE_59) +/*!< All Extended line not reserved*/ + +#define LL_EXTI_LINE_77 EXTI_IMR3_IM77 /*!< Extended line 77 */ +#define LL_EXTI_LINE_ALL_64_95 LL_EXTI_LINE_77 /*!< All Extended line not reserved*/ + +#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*/ +/** + * @} + */ +#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_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @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 + * @note The reset value for the 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 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_58 + * @arg @ref LL_EXTI_LINE_59 + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableIT_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR2, ExtiLine); +} + +/** + * @brief Enable ExtiLine Interrupt request for Lines in range 64 to 95 + * @note The reset value for the direct lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR3 IMx LL_EXTI_EnableIT_64_95 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_77 + * @arg @ref LL_EXTI_LINE_ALL_64_95 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableIT_64_95(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR3, 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_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @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 + * @note The reset value for the direct lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @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_58 + * @arg @ref LL_EXTI_LINE_59 + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableIT_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Interrupt request for Lines in range 64 to 95 + * @note The reset value for the 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 IMR3 IMx LL_EXTI_DisableIT_64_95 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_77 + * @arg @ref LL_EXTI_LINE_ALL_64_95 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableIT_64_95(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR3, 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_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @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 + * @note The reset value for the 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 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_58 + * @arg @ref LL_EXTI_LINE_59 + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @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)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if ExtiLine Interrupt request is enabled for Lines in range 64 to 95 + * @note The reset value for the direct lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR3 IMx LL_EXTI_IsEnabledIT_64_95 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_77 + * @arg @ref LL_EXTI_LINE_ALL_64_95 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledIT_64_95(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->IMR3, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @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_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @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_58 + * @arg @ref LL_EXTI_LINE_59 + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableEvent_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->EMR2, ExtiLine); +} + +/** + * @brief Enable ExtiLine Event request for Lines in range 64 to 95 + * @rmtoll EMR3 EMx LL_EXTI_EnableEvent_64_95 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_77 + * @arg @ref LL_EXTI_LINE_ALL_64_95 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableEvent_64_95(uint32_t ExtiLine) +{ + SET_BIT(EXTI->EMR3, 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_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @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_58 + * @arg @ref LL_EXTI_LINE_59 + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableEvent_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->EMR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Event request for Lines in range 64 to 95 + * @rmtoll EMR3 EMx LL_EXTI_DisableEvent_64_95 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_77 + * @arg @ref LL_EXTI_LINE_ALL_64_95 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableEvent_64_95(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->EMR3, 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_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @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_58 + * @arg @ref LL_EXTI_LINE_59 + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @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)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if ExtiLine Event request is enabled for Lines in range 64 to 95 + * @rmtoll EMR3 EMx LL_EXTI_IsEnabledEvent_64_95 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_77 + * @arg @ref LL_EXTI_LINE_ALL_64_95 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledEvent_64_95(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->EMR3, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @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_IMR1, 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 + * @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 + * @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_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @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 Flag is set or not for Lines in range 0 to 31 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR1 PIFx LL_EXTI_IsActiveFlag_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 + * @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 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsActiveFlag_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->PR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Check if the ExtLine Flag is set or not for Lines in range 32 to 63 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR2 PIFx LL_EXTI_IsActiveFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsActiveFlag_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->PR2, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Read ExtLine Combination Flag for Lines in range 0 to 31 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR1 PIFx LL_EXTI_ReadFlag_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 + * @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 + * @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_ReadFlag_0_31(uint32_t ExtiLine) +{ + return (uint32_t)(READ_BIT(EXTI->PR1, ExtiLine)); +} + +/** + * @brief Read ExtLine Combination Flag for Lines in range 32 to 63 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR2 PIFx LL_EXTI_ReadFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @retval @note This bit is set when the selected edge event arrives on the interrupt + */ +__STATIC_INLINE uint32_t LL_EXTI_ReadFlag_32_63(uint32_t ExtiLine) +{ + return (uint32_t)(READ_BIT(EXTI->PR2, ExtiLine)); +} + +/** + * @brief Clear ExtLine Flags for Lines in range 0 to 31 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR1 PIFx LL_EXTI_ClearFlag_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 + * @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 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_ClearFlag_0_31(uint32_t ExtiLine) +{ + WRITE_REG(EXTI->PR1, ExtiLine); +} + +/** + * @brief Clear ExtLine Flags for Lines in range 32 to 63 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR2 PIFx LL_EXTI_ClearFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_54 + * @retval Please check each device line mapping for EXTI Line availability + */ +__STATIC_INLINE void LL_EXTI_ClearFlag_32_63(uint32_t ExtiLine) +{ + WRITE_REG(EXTI->PR2, ExtiLine); +} + +/** + * @} + */ + +#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 /* STM32H7RSxx_LL_EXTI_H */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_gpio.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_gpio.h new file mode 100644 index 0000000..46f180b --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_gpio.h @@ -0,0 +1,994 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO LL 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 __STM32H7RSxx_LL_GPIO_H +#define __STM32H7RSxx_LL_GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ +#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || \ + defined (GPIOE) || defined (GPIOF) || defined (GPIOG) || defined (GPIOH) || \ + defined (GPIOM) || defined (GPION) || defined (GPIOO) || defined (GPIOP) + +/** @defgroup GPIO_LL GPIO + * @{ + */ +/** MISRA C:2012 deviation rule has been granted for following rules: + * Rule-18.1_d - Medium: Array pointer `GPIOx' is accessed with index [..,..] + * which may be out of array bounds [..,UNKNOWN] in following APIs: + * LL_GPIO_GetAFPin_0_7 + * LL_GPIO_SetAFPin_0_7 + * LL_GPIO_SetAFPin_8_15 + * LL_GPIO_GetAFPin_8_15 + */ + +/* 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 */ +/** + * @} + */ + +/** @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) * GPIO_MODER_MODE1_Pos)), + (Mode << (POSITION_VAL(Pin) * GPIO_MODER_MODE1_Pos))); +} + +/** + * @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) * GPIO_MODER_MODE1_Pos))) + >> (POSITION_VAL(Pin) * GPIO_MODER_MODE1_Pos)); +} + +/** + * @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) * GPIO_OSPEEDR_OSPEED1_Pos)), + (Speed << (POSITION_VAL(Pin) * GPIO_OSPEEDR_OSPEED1_Pos))); +} + +/** + * @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) * GPIO_OSPEEDR_OSPEED1_Pos))) + >> (POSITION_VAL(Pin) * GPIO_OSPEEDR_OSPEED1_Pos)); +} + +/** + * @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) * GPIO_PUPDR_PUPD1_Pos)), + (Pull << (POSITION_VAL(Pin) * GPIO_PUPDR_PUPD1_Pos))); +} + +/** + * @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) * GPIO_PUPDR_PUPD1_Pos))) + >> (POSITION_VAL(Pin) * GPIO_PUPDR_PUPD1_Pos)); +} + +/** + * @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) * GPIO_AFRL_AFSEL1_Pos)), + (Alternate << (POSITION_VAL(Pin) * GPIO_AFRL_AFSEL1_Pos))); +} + +/** + * @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) * GPIO_AFRL_AFSEL1_Pos))) + >> (POSITION_VAL(Pin) * GPIO_AFRL_AFSEL1_Pos)); +} + +/** + * @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) * GPIO_AFRH_AFSEL9_Pos)), + (Alternate << (POSITION_VAL(Pin >> 8U) * GPIO_AFRH_AFSEL9_Pos))); +} + +/** + * @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) * GPIO_AFRH_AFSEL9_Pos))) + >> (POSITION_VAL(Pin >> 8U) * GPIO_AFRH_AFSEL9_Pos)); +} + +/** + * @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)); +} + +/** + * @} + */ + +#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, const 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 (GPIOM) || defined (GPION) || defined (GPIOO) || defined (GPIOP) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_GPIO_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_i2c.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_i2c.h new file mode 100644 index 0000000..7b234c5 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_i2c.h @@ -0,0 +1,2372 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_i2c.h + * @author MCD Application Team + * @brief Header file of I2C LL 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 STM32H7RSxx_LL_I2C_H +#define STM32H7RSxx_LL_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +#if defined (I2C1) || defined (I2C2) || defined (I2C3) + +/** @defgroup I2C_LL I2C + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_LL_Private_Constants I2C Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/* 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) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + uint32_t tmp = ((uint32_t)(((uint32_t)SlaveAddr & I2C_CR2_SADD) | \ + ((uint32_t)SlaveAddrSize & I2C_CR2_ADD10) | \ + (((uint32_t)TransferSize << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \ + (uint32_t)EndMode | (uint32_t)Request) & (~0x80000000U)); + + /* update CR2 register */ + 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, + tmp); +} + +/** + * @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 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_I2C_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_icache.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_icache.h new file mode 100644 index 0000000..a3921a4 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_icache.h @@ -0,0 +1,453 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_icache.h + * @author MCD Application Team + * @brief Header file of ICACHE LL 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 STM32H7RSxx_LL_ICACHE_H +#define STM32H7RSxx_LL_ICACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -----------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +#if defined(ICACHE) + +/** @defgroup ICACHE_LL ICACHE + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +/* 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_4WAYS ICACHE_CR_WAYSEL /*!< 4-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 */ +/** + * @} + */ + + +/** + * @} + */ + +/* 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_4WAYS + * @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_4WAYS + */ +__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); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ICACHE */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_ICACHE_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_pwr.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_pwr.h new file mode 100644 index 0000000..d0968de --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_pwr.h @@ -0,0 +1,1887 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_pwr.h + * @author MCD Application Team + * @brief Header file of PWR LL 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 STM32H7RSxx_LL_PWR_H +#define STM32H7RSxx_LL_PWR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_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 (0x1FU) +/** + * @} + */ +/** + * @} + */ +/* 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_SR_CSSF PWR_CSR3_CSSF /*!< Clear Stop and Standby flags */ +#define LL_PWR_WKUPCR_WKUPC1 PWR_WKUPCR_WKUPC1 /*!< Clear Wakeup flag 1 */ +#define LL_PWR_WKUPCR_WKUPC2 PWR_WKUPCR_WKUPC2 /*!< Clear Wakeup flag 2 */ +#define LL_PWR_WKUPCR_WKUPC3 PWR_WKUPCR_WKUPC3 /*!< Clear Wakeup flag 3 */ +#define LL_PWR_WKUPCR_WKUPC4 PWR_WKUPCR_WKUPC4 /*!< Clear Wakeup flag 4 */ +#define LL_PWR_WKUPCR_WKUPC PWR_WKUPCR_WKUPC /*!< 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_CSR4_VOSRDY /*!< Voltage scaling ready flag */ +#define LL_PWR_FLAG_STOPF PWR_CSR3_STOPF /*!< Stop flag */ +#define LL_PWR_FLAG_SBF PWR_CSR3_SBF /*!< Standby flag */ +#define LL_PWR_WAKEUP_FLAG1 PWR_WKUPFR_WKUPF1 /*!< Wakeup flag 1 */ +#define LL_PWR_WAKEUP_FLAG2 PWR_WKUPFR_WKUPF2 /*!< Wakeup flag 2 */ +#define LL_PWR_WAKEUP_FLAG3 PWR_WKUPFR_WKUPF3 /*!< Wakeup flag 3 */ +#define LL_PWR_WAKEUP_FLAG4 PWR_WKUPFR_WKUPF4 /*!< Wakeup flag 4 */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_MODE_PWR Power Down Mode In Deep Sleep Mode + * @{ + */ +#define LL_PWR_POWERDOWN_MODE_DS_STOP (0U) /*!< Enter to Stop mode when the CPU enters deepsleep */ +#define LL_PWR_POWERDOWN_MODE_DS_STANDBY PWR_CSR3_PDDS /*!< Enter to Standby mode when the CPU enters deepsleep */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_REGU_VOLTAGE Run mode Regulator Voltage Scaling + * @{ + */ +#define LL_PWR_REGU_VOLTAGE_SCALE0 PWR_CSR4_VOS /*!< Voltage scaling range 0 (highest frequency) */ +#define LL_PWR_REGU_VOLTAGE_SCALE1 (0U) /*!< Voltage scaling range 1 (lowest power) */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_STOP_MODE_REGU_VOLTAGE Stop mode Regulator Voltage Scaling + * @{ + */ +#define LL_PWR_REGU_STOP_VOLTAGE_SCALE3 PWR_CR1_SVOS /*!< Voltage scaling range 3 (highest frequency) when system enters STOP mode */ +#define LL_PWR_REGU_STOP_VOLTAGE_SCALE5 (0U) /*!< Voltage scaling range 5 (lowest power) when system enters STOP mode */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_PVDLEVEL Power Digital Voltage Level Detector + * @{ + */ +#define LL_PWR_PVDLEVEL_1 (0U) /*!< PVD level 1 */ +#define LL_PWR_PVDLEVEL_2 PWR_CR1_PLS_0 /*!< PVD level 2 */ +#define LL_PWR_PVDLEVEL_3 PWR_CR1_PLS_1 /*!< PVD level 3 */ +#define LL_PWR_PVDLEVEL_4 (PWR_CR1_PLS_0 | PWR_CR1_PLS_1) /*!< PVD level 4 */ +#define LL_PWR_PVDLEVEL_5 PWR_CR1_PLS_2 /*!< PVD level 5 */ +#define LL_PWR_PVDLEVEL_6 (PWR_CR1_PLS_0 | PWR_CR1_PLS_2) /*!< PVD level 6 */ +#define LL_PWR_PVDLEVEL_7 (PWR_CR1_PLS_1 | PWR_CR1_PLS_2) /*!< PVD level 7 */ +#define LL_PWR_PVDLEVEL_EXT (PWR_CR1_PLS_0 | PWR_CR1_PLS_1 | PWR_CR1_PLS_2) +/*!< External voltage level on PVD_IN pin, compared to internal VREFINT level */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_AVDLEVEL Power Analog Voltage Level Detector + * @{ + */ +#define LL_PWR_AVDLEVEL_1 (0U) /*!< Analog Voltage detector level 1 */ +#define LL_PWR_AVDLEVEL_2 PWR_CR1_ALS_0 /*!< Analog Voltage detector level 2 */ +#define LL_PWR_AVDLEVEL_3 PWR_CR1_ALS_1 /*!< Analog Voltage detector level 3 */ +#define LL_PWR_AVDLEVEL_4 (PWR_CR1_ALS_0 | PWR_CR1_ALS_1) /*!< Analog Voltage detector level 4 */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_XSPI_CAP1 XSPI 1 capacitor + * @{ + */ +#define LL_PWR_XSPI1_CAPACITOR_OFF (0U) /*!< XSPI Port 1 Capacitor OFF */ +#define LL_PWR_XSPI1_CAPACITOR_1_DIV_3 PWR_CSR2_XSPICAP1_0 /*!< XSPI Port 1 Capacitor set to 1/3 */ +#define LL_PWR_XSPI1_CAPACITOR_2_DIV_3 PWR_CSR2_XSPICAP1_1 /*!< XSPI Port 1 Capacitor set to 2/3 */ +#define LL_PWR_XSPI1_CAPACITOR_FULL (PWR_CSR2_XSPICAP1_0 | PWR_CSR2_XSPICAP1_1) +/*!< XSPI Port 1 Capacitor set to full capacitance */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_XSPI_CAP2 XSPI 2 Capacitor + * @{ + */ +#define LL_PWR_XSPI2_CAPACITOR_OFF (0U) /*!< XSPI Port 2 Capacitor OFF */ +#define LL_PWR_XSPI2_CAPACITOR_1_DIV_3 PWR_CSR2_XSPICAP2_0 /*!< XSPI Port 2 Capacitor set to 1/3 */ +#define LL_PWR_XSPI2_CAPACITOR_2_DIV_3 PWR_CSR2_XSPICAP2_1 /*!< XSPI Port 2 Capacitor set to 2/3 */ +#define LL_PWR_XSPI2_CAPACITOR_FULL (PWR_CSR2_XSPICAP2_0 | PWR_CSR2_XSPICAP2_1) +/*!< XSPI Port 2 Capacitor set to full capacitance */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_BATT_CHARG_RESISTOR Battery Charge Resistor + * @{ + */ +#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_CSR2_VBRS /*!< Charge the Battery through a 1.5 kO resistor */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_WAKEUP_PIN Wakeup Pins + * @{ + */ +#define LL_PWR_WAKEUP_PIN1 PWR_WKUPEPR_WKUPEN1 /*!< Wake-Up pin 1 : PA0 */ +#define LL_PWR_WAKEUP_PIN2 PWR_WKUPEPR_WKUPEN2 /*!< Wake-Up pin 2 : PA2 */ +#define LL_PWR_WAKEUP_PIN3 PWR_WKUPEPR_WKUPEN3 /*!< Wake-Up pin 3 : PC13 */ +#define LL_PWR_WAKEUP_PIN4 PWR_WKUPEPR_WKUPEN4 /*!< Wake-Up pin 4 : PC1 */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_WAKEUP_PIN_PULL Wakeup Pins pull configuration + * @{ + */ +#define LL_PWR_WAKEUP_PIN_NOPULL (0UL) /*!< Configure Wake-Up pin in no pull */ +#define LL_PWR_WAKEUP_PIN_PULLUP (1UL) /*!< Configure Wake-Up pin in pull Up */ +#define LL_PWR_WAKEUP_PIN_PULLDOWN (2UL) /*!< Configure Wake-Up pin in pull Down */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_SUPPLY_PWR Power supply source configuration + * @{ + */ +#define LL_PWR_LDO_SUPPLY PWR_CSR2_LDOEN /*!< Core domains are supplied from the LDO */ +#define LL_PWR_DIRECT_SMPS_SUPPLY PWR_CSR2_SDEN /*!< Core domains are supplied from the SMPS */ +#define LL_PWR_SMPS_1V8_SUPPLIES_LDO (PWR_CSR2_SDHILEVEL | PWR_CSR2_SDEN | PWR_CSR2_LDOEN) /*!< The SMPS 1.8V output supplies the LDO which supplies the Core domains */ +#define LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | PWR_CSR2_SDEN | PWR_CSR2_LDOEN) /*!< The SMPS 1.8V output supplies an external circuits and the LDO. The Core domains are supplied from the LDO */ +#define LL_PWR_SMPS_1V8_SUPPLIES_EXT (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | PWR_CSR2_SDEN | PWR_CSR2_BYPASS) /*!< The SMPS 1.8V output supplies an external source which supplies the Core domains */ +#define LL_PWR_EXTERNAL_SOURCE_SUPPLY PWR_CSR2_BYPASS /*!< The SMPS and the LDO are Bypassed. The Core domains are supplied from an external source */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_GPIO_PIN_MASK PWR GPIO Pin Mask + * @{ + */ +#define LL_PWR_GPIO_PIN_0 (0x0001U) /*!< GPIO port I/O pin 0 */ +#define LL_PWR_GPIO_PIN_1 (0x0002U) /*!< GPIO port I/O pin 1 */ +#define LL_PWR_GPIO_PIN_2 (0x0004U) /*!< GPIO port I/O pin 2 */ +#define LL_PWR_GPIO_PIN_3 (0x0008U) /*!< GPIO port I/O pin 3 */ +#define LL_PWR_GPIO_PIN_4 (0x0010U) /*!< GPIO port I/O pin 4 */ +#define LL_PWR_GPIO_PIN_5 (0x0020U) /*!< GPIO port I/O pin 5 */ +#define LL_PWR_GPIO_PIN_6 (0x0040U) /*!< GPIO port I/O pin 6 */ +#define LL_PWR_GPIO_PIN_7 (0x0080U) /*!< GPIO port I/O pin 7 */ +#define LL_PWR_GPIO_PIN_8 (0x0100U) /*!< GPIO port I/O pin 8 */ +#define LL_PWR_GPIO_PIN_9 (0x0200U) /*!< GPIO port I/O pin 9 */ +#define LL_PWR_GPIO_PIN_10 (0x0400U) /*!< GPIO port I/O pin 10 */ +#define LL_PWR_GPIO_PIN_11 (0x0800U) /*!< GPIO port I/O pin 11 */ +#define LL_PWR_GPIO_PIN_12 (0x1000U) /*!< GPIO port I/O pin 12 */ +#define LL_PWR_GPIO_PIN_13 (0x2000U) /*!< GPIO port I/O pin 13 */ +#define LL_PWR_GPIO_PIN_14 (0x4000U) /*!< GPIO port I/O pin 14 */ +#define LL_PWR_GPIO_PIN_15 (0x8000U) /*!< GPIO port I/O pin 15 */ +/** + * @} + */ + +/** + * @} + */ +/* 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 Enable Power Voltage Detector + * @rmtoll CR1 PVDE LL_PWR_EnablePVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnablePVD(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_PVDE); +} + +/** + * @brief Disable Power Voltage Detector + * @rmtoll CR1 PVDE LL_PWR_DisablePVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisablePVD(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_PVDE); +} + +/** + * @brief Check if Power Voltage Detector is enabled + * @rmtoll CR1 PVDE LL_PWR_IsEnabledPVD + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledPVD(void) +{ + return ((READ_BIT(PWR->CR1, PWR_CR1_PVDE) == (PWR_CR1_PVDE)) ? 1UL : 0UL); +} + +/** + * @brief Configure the voltage threshold detected by the Power Voltage Detector + * @rmtoll CR1 PLS LL_PWR_SetPVDLevel + * @param PVDLevel This parameter can be one of the following values: + * @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 + * @arg @ref LL_PWR_PVDLEVEL_EXT + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetPVDLevel(uint32_t PVDLevel) +{ + MODIFY_REG(PWR->CR1, PWR_CR1_PLS, PVDLevel); +} + +/** + * @brief Get the voltage threshold detection + * @rmtoll CR1 PLS LL_PWR_GetPVDLevel + * @retval Returned value can be one of the following values: + * @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 + * @arg @ref LL_PWR_PVDLEVEL_EXT + */ +__STATIC_INLINE uint32_t LL_PWR_GetPVDLevel(void) +{ + return READ_BIT(PWR->CR1, PWR_CR1_PLS); +} + +/** + * @brief Enable access to the backup domain + * @rmtoll CR1 DBP LL_PWR_EnableBkUpAccess + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableBkUpAccess(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_DBP); +} + +/** + * @brief Disable access to the backup domain + * @rmtoll CR1 DBP LL_PWR_DisableBkUpAccess + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableBkUpAccess(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_DBP); +} + +/** + * @brief Check if the backup domain is enabled + * @rmtoll CR1 DBP LL_PWR_IsEnabledBkUpAccess + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpAccess(void) +{ + return ((READ_BIT(PWR->CR1, PWR_CR1_DBP) == (PWR_CR1_DBP)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Flash low-power mode in Stop Mode + * @rmtoll CR1 FLPS LL_PWR_EnableFlashLowPower + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableFlashLowPower(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_FLPS); +} + +/** + * @brief Disable the Flash low-power mode in Stop Mode + * @rmtoll CR1 FLPS LL_PWR_DisableFlashLowPower + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableFlashLowPower(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_FLPS); +} + +/** + * @brief Check if the Flash low-power mode in Stop Mode is enabled + * @rmtoll CR1 FLPS LL_PWR_IsEnabledFlashLowPower + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledFlashLowPower(void) +{ + return ((READ_BIT(PWR->CR1, PWR_CR1_FLPS) == (PWR_CR1_FLPS)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Analog Voltage Booster + * @rmtoll CR1 BOOSTE LL_PWR_EnableAnalogBooster + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAnalogBooster(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_BOOSTE); +} + +/** + * @brief Disable the Analog Voltage Booster + * @rmtoll CR1 BOOSTE LL_PWR_DisableAnalogBooster + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAnalogBooster(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_BOOSTE); +} + +/** + * @brief Check if the Analog Voltage Booster is enabled + * @rmtoll CR1 BOOSTE LL_PWR_IsEnabledAnalogBooster + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAnalogBooster(void) +{ + return ((READ_BIT(PWR->CR1, PWR_CR1_BOOSTE) == (PWR_CR1_BOOSTE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Analog Voltage Ready + * @rmtoll CR1 AVDREADY LL_PWR_EnableAnalogVoltageReady + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAnalogVoltageReady(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_AVDREADY); +} + +/** + * @brief Disable the Analog Voltage Ready + * @rmtoll CR1 AVDREADY LL_PWR_DisableAnalogVoltageReady + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAnalogVoltageReady(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_AVDREADY); +} + +/** + * @brief Check if the Analog Voltage Ready is enabled + * @rmtoll CR1 AVDREADY LL_PWR_IsEnabledAnalogVoltageReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAnalogVoltageReady(void) +{ + return ((READ_BIT(PWR->CR1, PWR_CR1_AVDREADY) == (PWR_CR1_AVDREADY)) ? 1UL : 0UL); +} + +/** + * @brief Enable Analog Power Voltage Monitor + * @rmtoll CR1 AVDEN LL_PWR_EnableAVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAVD(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_AVDEN); +} + +/** + * @brief Disable Analog Power Voltage Monitor + * @rmtoll CR1 AVDEN LL_PWR_DisableAVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAVD(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_AVDEN); +} + +/** + * @brief Check if Analog Power Voltage Monitor is enabled + * @rmtoll CR1 AVDEN LL_PWR_IsEnabledAVD + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAVD(void) +{ + return ((READ_BIT(PWR->CR1, PWR_CR1_AVDEN) == (PWR_CR1_AVDEN)) ? 1UL : 0UL); +} + +/** + * @brief Set the Analog Voltage detector level + * @rmtoll CR1 ALS LL_PWR_SetAVDLevel + * @param AVDLevel This parameter can be one of the following values: + * @arg @ref LL_PWR_AVDLEVEL_1 + * @arg @ref LL_PWR_AVDLEVEL_2 + * @arg @ref LL_PWR_AVDLEVEL_3 + * @arg @ref LL_PWR_AVDLEVEL_4 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetAVDLevel(uint32_t AVDLevel) +{ + MODIFY_REG(PWR->CR1, PWR_CR1_ALS, AVDLevel); +} + +/** + * @brief Get the Analog Voltage detector level selected + * @rmtoll CR1 ALS LL_PWR_GetAVDLevel + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_AVDLEVEL_1 + * @arg @ref LL_PWR_AVDLEVEL_2 + * @arg @ref LL_PWR_AVDLEVEL_3 + * @arg @ref LL_PWR_AVDLEVEL_4 + */ +__STATIC_INLINE uint32_t LL_PWR_GetAVDLevel(void) +{ + return READ_BIT(PWR->CR1, PWR_CR1_ALS); +} + +/** + * @brief Enable Backup Regulator + * @rmtoll CSR1 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->CSR1, PWR_CSR1_BREN); +} + +/** + * @brief Disable Backup Regulator + * @rmtoll CSR1 BREN LL_PWR_DisableBkUpRegulator + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableBkUpRegulator(void) +{ + CLEAR_BIT(PWR->CSR1, PWR_CSR1_BREN); +} + +/** + * @brief Check if the backup Regulator is enabled + * @rmtoll CSR1 BREN LL_PWR_IsEnabledBkUpRegulator + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpRegulator(void) +{ + return ((READ_BIT(PWR->CSR1, PWR_CSR1_BREN) == (PWR_CSR1_BREN)) ? 1UL : 0UL); +} + +/** + * @brief Enable VBAT and Temperature monitoring + * @rmtoll CSR1 MONEN LL_PWR_EnableMonitoring + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableMonitoring(void) +{ + SET_BIT(PWR->CSR1, PWR_CSR1_MONEN); +} + +/** + * @brief Disable VBAT and Temperature monitoring + * @rmtoll CSR1 MONEN LL_PWR_DisableMonitoring + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableMonitoring(void) +{ + CLEAR_BIT(PWR->CSR1, PWR_CSR1_MONEN); +} + +/** + * @brief Check if the VBAT and Temperature monitoring is enabled + * @rmtoll CSR1 MONEN LL_PWR_IsEnabledMonitoring + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledMonitoring(void) +{ + return ((READ_BIT(PWR->CSR1, PWR_CSR1_MONEN) == (PWR_CSR1_MONEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure the PWR supply + * @rmtoll CSR2 SDHILEVEL LL_PWR_ConfigSupply + * @rmtoll CSR2 SMPSEXTHP LL_PWR_ConfigSupply + * @rmtoll CSR2 SDEN LL_PWR_ConfigSupply + * @rmtoll CSR2 LDOEN LL_PWR_ConfigSupply + * @rmtoll CSR2 BYPASS LL_PWR_ConfigSupply + * @param SupplySource This parameter can be one of the following values: + * @arg @ref LL_PWR_LDO_SUPPLY + * @arg @ref LL_PWR_DIRECT_SMPS_SUPPLY + * @arg @ref LL_PWR_SMPS_1V8_SUPPLIES_LDO + * @arg @ref LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO + * @arg @ref LL_PWR_SMPS_1V8_SUPPLIES_EXT + * @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->CSR2, (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | PWR_CSR2_SDEN | PWR_CSR2_LDOEN | PWR_CSR2_BYPASS), + SupplySource); +} + +/** + * @brief Get the PWR supply + * @rmtoll CSR2 SDHILEVEL LL_PWR_GetSupply + * @rmtoll CSR2 SMPSEXTHP LL_PWR_GetSupply + * @rmtoll CSR2 SDEN LL_PWR_GetSupply + * @rmtoll CSR2 LDOEN LL_PWR_GetSupply + * @rmtoll CSR2 BYPASS LL_PWR_GetSupply + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_LDO_SUPPLY + * @arg @ref LL_PWR_DIRECT_SMPS_SUPPLY + * @arg @ref LL_PWR_SMPS_1V8_SUPPLIES_LDO + * @arg @ref LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO + * @arg @ref LL_PWR_SMPS_1V8_SUPPLIES_EXT + * @arg @ref LL_PWR_EXTERNAL_SOURCE_SUPPLY + */ +__STATIC_INLINE uint32_t LL_PWR_GetSupply(void) +{ + /* Get the power supply configuration */ + return READ_BIT(PWR->CSR2, + (PWR_CSR2_SDHILEVEL | PWR_CSR2_SMPSEXTHP | PWR_CSR2_SDEN | PWR_CSR2_LDOEN | PWR_CSR2_BYPASS)); +} + +/** + * @brief Enable VBAT battery charging + * @rmtoll CSR2 VBE LL_PWR_EnableBatteryCharging + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableBatteryCharging(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_VBE); +} + +/** + * @brief Disable VBAT battery charging + * @rmtoll CSR2 VBE LL_PWR_DisableBatteryCharging + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableBatteryCharging(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_VBE); +} + +/** + * @brief Check if VBAT battery charging is enabled + * @rmtoll CSR2 VBE LL_PWR_IsEnabledBatteryCharging + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledBatteryCharging(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_VBE) == (PWR_CSR2_VBE)) ? 1UL : 0UL); +} + +/** + * @brief Set the Battery charge resistor impedance + * @rmtoll CSR2 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->CSR2, PWR_CSR2_VBRS, Resistor); +} + +/** + * @brief Get the Battery charge resistor impedance + * @rmtoll CSR2 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 (READ_BIT(PWR->CSR2, PWR_CSR2_VBRS)); +} + +/** + * @brief Set the XSPI port 1 capacitor value + * @rmtoll CSR2 XSPICAP1 LL_PWR_SetXSPI1Capacitor + * @param Capacitor This parameter can be one of the following values: + * @arg @ref LL_PWR_XSPI1_CAPACITOR_OFF + * @arg @ref LL_PWR_XSPI1_CAPACITOR_1_DIV_3 + * @arg @ref LL_PWR_XSPI1_CAPACITOR_2_DIV_3 + * @arg @ref LL_PWR_XSPI1_CAPACITOR_FULL + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetXSPI1Capacitor(uint32_t Capacitor) +{ + MODIFY_REG(PWR->CSR2, PWR_CSR2_XSPICAP1, Capacitor); +} + +/** + * @brief Get the XSPI port 1 capacitor value + * @rmtoll CSR2 XSPICAP1 LL_PWR_GetXSPI1Capacitor + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_XSPI1_CAPACITOR_OFF + * @arg @ref LL_PWR_XSPI1_CAPACITOR_1_DIV_3 + * @arg @ref LL_PWR_XSPI1_CAPACITOR_2_DIV_3 + * @arg @ref LL_PWR_XSPI1_CAPACITOR_FULL + */ +__STATIC_INLINE uint32_t LL_PWR_GetXSPI1Capacitor(void) +{ + return (READ_BIT(PWR->CSR2, PWR_CSR2_XSPICAP1)); +} + +/** + * @brief Set the XSPI port 2 capacitor value + * @rmtoll CSR2 XSPICAP2 LL_PWR_SetXSPI2Capacitor + * @param Capacitor This parameter can be one of the following values: + * @arg @ref LL_PWR_XSPI2_CAPACITOR_OFF + * @arg @ref LL_PWR_XSPI2_CAPACITOR_1_DIV_3 + * @arg @ref LL_PWR_XSPI2_CAPACITOR_2_DIV_3 + * @arg @ref LL_PWR_XSPI2_CAPACITOR_FULL + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetXSPI2Capacitor(uint32_t Capacitor) +{ + MODIFY_REG(PWR->CSR2, PWR_CSR2_XSPICAP2, Capacitor); +} + +/** + * @brief Get the XSPI port 2 capacitor value + * @rmtoll CSR2 XSPICAP2 LL_PWR_GetXSPI2Capacitor + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_XSPI2_CAPACITOR_OFF + * @arg @ref LL_PWR_XSPI2_CAPACITOR_1_DIV_3 + * @arg @ref LL_PWR_XSPI2_CAPACITOR_2_DIV_3 + * @arg @ref LL_PWR_XSPI2_CAPACITOR_FULL + */ +__STATIC_INLINE uint32_t LL_PWR_GetXSPI2Capacitor(void) +{ + return (uint32_t)(READ_BIT(PWR->CSR2, PWR_CSR2_XSPICAP2)); +} + +/** + * @brief Enable the USB voltage detector + * @rmtoll CSR2 USB33DEN LL_PWR_EnableUSBVoltageDetector + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableUSBVoltageDetector(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_USB33DEN); +} + +/** + * @brief Disable the USB voltage detector + * @rmtoll CSR2 USB33DEN LL_PWR_DisableUSBVoltageDetector + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableUSBVoltageDetector(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_USB33DEN); +} + +/** + * @brief Check if the USB voltage detector is enabled + * @rmtoll CSR2 USB33DEN LL_PWR_IsEnabledUSBVoltageDetector + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUSBVoltageDetector(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_USB33DEN) == (PWR_CSR2_USB33DEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable the USB regulator + * @rmtoll CSR2 USBREGEN LL_PWR_EnableUSBReg + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableUSBReg(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_USBREGEN); +} + +/** + * @brief Disable the USB regulator + * @rmtoll CSR2 USBREGEN LL_PWR_DisableUSBReg + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableUSBReg(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_USBREGEN); +} + +/** + * @brief Check if the USB regulator is enabled + * @rmtoll CSR2 USBREGEN LL_PWR_IsEnabledUSBReg + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUSBReg(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_USBREGEN) == (PWR_CSR2_USBREGEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable the USB HS PHY regulator + * @rmtoll CSR2 USBHSREGEN LL_PWR_EnableUSBHSPHYReg + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableUSBHSPHYReg(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_USBHSREGEN); +} + +/** + * @brief Disable USB HS PHY regulator + * @rmtoll CSR2 USBHSREGEN LL_PWR_DisableUSBHSPHYReg + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableUSBHSPHYReg(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_USBHSREGEN); +} + +/** + * @brief Check if the USB HS PHY regulator is enabled + * @rmtoll CSR2 USBHSREGEN LL_PWR_IsEnabledUSBHSPHYReg + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUSBHSPHYReg(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_USBHSREGEN) == (PWR_CSR2_USBHSREGEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable UCPD configuration memorization in Standby. + * @rmtoll UCPDR UCPD_STBY LL_PWR_EnableUCPDStandbyMode + * @retval None + * @note This function must be called just before entering Standby mode when using UCPD. + */ +__STATIC_INLINE void LL_PWR_EnableUCPDStandbyMode(void) +{ + /* Memorize UCPD configuration when entering standby mode */ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} + +/** + * @brief Disable UCPD configuration memorization in Standby. + * @rmtoll UCPDR UCPD_STBY LL_PWR_DisableUCPDStandbyMode + * @retval None + * @note This function must be called on exiting the Standby mode and before any UCPD + * configuration update. + */ +__STATIC_INLINE void LL_PWR_DisableUCPDStandbyMode(void) +{ + CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} + +/** + * @brief Check if the UCPD configuration memorization in Standby is enabled + * @rmtoll UCPDR UCPD_STBY 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); +} + +/** + * @brief Enable the UCPD dead battery behavior + * @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 UCPD dead battery behavior + * @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 if the UCPD dead battery behavior is enabled + * @rmtoll UCPDR UCPD_DBDIS LL_PWR_IsEnabledUCPDDeadBattery + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUCPDDeadBattery(void) +{ + return ((READ_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS) == (PWR_UCPDR_UCPD_DBDIS)) ? 1UL : 0UL); +} + +/** + * @brief Enable the XSPI_P1 interface + * @rmtoll CSR2 EN_XSPIM1 LL_PWR_EnableXSPIM1 + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableXSPIM1(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM1); +} + +/** + * @brief Disable the XSPI_P1 interface + * @rmtoll CSR2 EN_XSPIM1 LL_PWR_DisableXSPIM1 + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableXSPIM1(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM1); +} + +/** + * @brief Check if the XSPI_P1 interface is enabled + * @rmtoll CSR2 EN_XSPIM1 LL_PWR_IsEnabledXSPIM1 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledXSPIM1(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM1) == (PWR_CSR2_EN_XSPIM1)) ? 1UL : 0UL); +} + +/** + * @brief Enable the XSPI_P2 interface + * @rmtoll CSR2 EN_XSPIM2 LL_PWR_EnableXSPIM2 + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableXSPIM2(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM2); +} + +/** + * @brief Disable the XSPI_P2 interface + * @rmtoll CSR2 EN_XSPIM2 LL_PWR_DisableXSPIM2 + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableXSPIM2(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM2); +} + +/** + * @brief Check if the XSPI_P2 interface is enabled + * @rmtoll CSR2 EN_XSPIM2 LL_PWR_IsEnabledXSPIM2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledXSPIM2(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM2) == (PWR_CSR2_EN_XSPIM2)) ? 1UL : 0UL); +} + +/** + * @brief Set the Power Down mode when device enters deepsleep mode + * @rmtoll CSR3 PDDS LL_PWR_SetPowerDownModeDS + * @param PDMode This parameter can be one of the following values: + * @arg @ref LL_PWR_POWERDOWN_MODE_DS_STOP + * @arg @ref LL_PWR_POWERDOWN_MODE_DS_STANDBY + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetPowerDownModeDS(uint32_t PDMode) +{ + MODIFY_REG(PWR->CSR3, PWR_CSR3_PDDS, PDMode); +} + +/** + * @brief Get the Power Down mode when device enters deepsleep mode + * @rmtoll CSR3 PDDS LL_PWR_GetPowerDownModeDS + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_POWERDOWN_MODE_DS_STOP + * @arg @ref LL_PWR_POWERDOWN_MODE_DS_STANDBY + */ +__STATIC_INLINE uint32_t LL_PWR_GetPowerDownModeDS(void) +{ + return (uint32_t)(READ_BIT(PWR->CSR3, PWR_CSR3_PDDS)); +} + +/** + * @brief Set the main internal Regulator output voltage + * @rmtoll CSR4 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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetRegulVoltageScaling(uint32_t VoltageScaling) +{ + MODIFY_REG(PWR->CSR4, PWR_CSR4_VOS, VoltageScaling); +} + +/** + * @brief Get the main internal Regulator output voltage + * @rmtoll CSR4 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 + */ +__STATIC_INLINE uint32_t LL_PWR_GetRegulVoltageScaling(void) +{ + return (uint32_t)(READ_BIT(PWR->CSR4, PWR_CSR4_VOS)); +} + +/** + * @brief Set the internal Regulator output voltage in STOP mode + * @rmtoll CR1 SVOS LL_PWR_SetStopModeRegulVoltageScaling + * @param VoltageScaling This parameter can be one of the following values: + * @arg @ref LL_PWR_REGU_STOP_VOLTAGE_SCALE3 + * @arg @ref LL_PWR_REGU_STOP_VOLTAGE_SCALE5 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetStopModeRegulVoltageScaling(uint32_t VoltageScaling) +{ + MODIFY_REG(PWR->CR1, PWR_CR1_SVOS, VoltageScaling); +} + +/** + * @brief Get the internal Regulator output voltage in STOP mode + * @rmtoll CR1 SVOS LL_PWR_GetStopModeRegulVoltageScaling + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_REGU_STOP_VOLTAGE_SCALE3 + * @arg @ref LL_PWR_REGU_STOP_VOLTAGE_SCALE5 + */ +__STATIC_INLINE uint32_t LL_PWR_GetStopModeRegulVoltageScaling(void) +{ + return READ_BIT(PWR->CR1, PWR_CR1_SVOS); +} + +/** + * @brief Enable the WakeUp PINx functionality + * @rmtoll WKUPEPR WKUPEN1 LL_PWR_EnableWakeUpPin\n + * WKUPEPR WKUPEN2 LL_PWR_EnableWakeUpPin\n + * WKUPEPR WKUPEN3 LL_PWR_EnableWakeUpPin\n + * WKUPEPR WKUPEN4 LL_PWR_EnableWakeUpPin + * @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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableWakeUpPin(uint32_t WakeUpPin) +{ + SET_BIT(PWR->WKUPEPR, WakeUpPin); +} + +/** + * @brief Disable the WakeUp PINx functionality + * @rmtoll WKUPEPR WKUPEN1 LL_PWR_DisableWakeUpPin\n + * WKUPEPR WKUPEN2 LL_PWR_DisableWakeUpPin\n + * WKUPEPR WKUPEN3 LL_PWR_DisableWakeUpPin\n + * WKUPEPR WKUPEN4 LL_PWR_DisableWakeUpPin + * @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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableWakeUpPin(uint32_t WakeUpPin) +{ + CLEAR_BIT(PWR->WKUPEPR, WakeUpPin); +} + +/** + * @brief Check if the WakeUp PINx functionality is enabled + * @rmtoll WKUPEPR WKUPEN1 LL_PWR_IsEnabledWakeUpPin\n + * WKUPEPR WKUPEN2 LL_PWR_IsEnabledWakeUpPin\n + * WKUPEPR WKUPEN3 LL_PWR_IsEnabledWakeUpPin\n + * WKUPEPR WKUPEN4 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 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledWakeUpPin(uint32_t WakeUpPin) +{ + return ((READ_BIT(PWR->WKUPEPR, WakeUpPin) == (WakeUpPin)) ? 1UL : 0UL); +} + +/** + * @brief Set the Wake-Up pin polarity low for the event detection + * @rmtoll WKUPEPR WKUPP1 LL_PWR_SetWakeUpPinPolarityLow\n + * WKUPEPR WKUPP2 LL_PWR_SetWakeUpPinPolarityLow\n + * WKUPEPR WKUPP3 LL_PWR_SetWakeUpPinPolarityLow\n + * WKUPEPR WKUPP4 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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPolarityLow(uint32_t WakeUpPin) +{ + SET_BIT(PWR->WKUPEPR, (WakeUpPin << PWR_WKUPEPR_WKUPP1_Pos)); +} + +/** + * @brief Set the Wake-Up pin polarity high for the event detection + * @rmtoll WKUPEPR WKUPP1 LL_PWR_SetWakeUpPinPolarityHigh\n + * WKUPEPR WKUPP2 LL_PWR_SetWakeUpPinPolarityHigh\n + * WKUPEPR WKUPP3 LL_PWR_SetWakeUpPinPolarityHigh\n + * WKUPEPR WKUPP4 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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPolarityHigh(uint32_t WakeUpPin) +{ + CLEAR_BIT(PWR->WKUPEPR, (WakeUpPin << PWR_WKUPEPR_WKUPP1_Pos)); +} + +/** + * @brief Check if the Wake-Up pin polarity is low for event detection + * @rmtoll WKUPEPR WKUPP1 LL_PWR_IsWakeUpPinPolarityLow\n + * WKUPEPR WKUPP2 LL_PWR_IsWakeUpPinPolarityLow\n + * WKUPEPR WKUPP3 LL_PWR_IsWakeUpPinPolarityLow\n + * WKUPEPR WKUPP4 LL_PWR_IsWakeUpPinPolarityLow + * @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 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsWakeUpPinPolarityLow(uint32_t WakeUpPin) +{ + return ((READ_BIT(PWR->WKUPEPR, (WakeUpPin << PWR_WKUPEPR_WKUPP1_Pos)) == (WakeUpPin << PWR_WKUPEPR_WKUPP1_Pos)) ? 1UL : 0UL); +} + +/** + * @brief Set the Wake-Up pin Pull None + * @rmtoll WKUPEPR WKUPPUPD1 LL_PWR_SetWakeUpPinPullNone\n + * WKUPEPR WKUPPUPD2 LL_PWR_SetWakeUpPinPullNone\n + * WKUPEPR WKUPPUPD3 LL_PWR_SetWakeUpPinPullNone\n + * WKUPEPR WKUPPUPD4 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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPullNone(uint32_t WakeUpPin) +{ + MODIFY_REG(PWR->WKUPEPR, \ + (PWR_WKUPEPR_WKUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin)) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)), \ + (LL_PWR_WAKEUP_PIN_NOPULL << ((PWR_WKUPEPR_WKUPPUPD1_Pos + (LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin))) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); +} + +/** + * @brief Set the Wake-Up pin Pull Up + * @rmtoll WKUPEPR WKUPPUPD1 LL_PWR_SetWakeUpPinPullUp\n + * WKUPEPR WKUPPUPD2 LL_PWR_SetWakeUpPinPullUp\n + * WKUPEPR WKUPPUPD3 LL_PWR_SetWakeUpPinPullUp\n + * WKUPEPR WKUPPUPD4 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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPullUp(uint32_t WakeUpPin) +{ + MODIFY_REG(PWR->WKUPEPR, \ + (PWR_WKUPEPR_WKUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin)) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)), \ + (LL_PWR_WAKEUP_PIN_PULLUP << ((PWR_WKUPEPR_WKUPPUPD1_Pos + (LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin))) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); +} + +/** + * @brief Set the Wake-Up pin Pull Down + * @rmtoll WKUPEPR WKUPPUPD1 LL_PWR_SetWakeUpPinPullDown\n + * WKUPEPR WKUPPUPD2 LL_PWR_SetWakeUpPinPullDown\n + * WKUPEPR WKUPPUPD3 LL_PWR_SetWakeUpPinPullDown\n + * WKUPEPR WKUPPUPD4 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 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPullDown(uint32_t WakeUpPin) +{ + MODIFY_REG(PWR->WKUPEPR, \ + (PWR_WKUPEPR_WKUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin)) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)), \ + (LL_PWR_WAKEUP_PIN_PULLDOWN << ((PWR_WKUPEPR_WKUPPUPD1_Pos + (LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin))) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); +} + +/** + * @brief Get the Wake-Up pin pull + * @rmtoll WKUPEPR WKUPPUPD1 LL_PWR_GetWakeUpPinPull\n + * WKUPEPR WKUPPUPD2 LL_PWR_GetWakeUpPinPull\n + * WKUPEPR WKUPPUPD3 LL_PWR_GetWakeUpPinPull\n + * WKUPEPR WKUPPUPD4 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 + * @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->WKUPEPR, (PWR_WKUPEPR_WKUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin)) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); + + return (uint32_t)(regValue >> ((PWR_WKUPEPR_WKUPPUPD1_Pos + (LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * POSITION_VAL(WakeUpPin))) & LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)); +} + +/** + * @brief Enable the pull-up on I3C1_SCL (PB6)) in standby mode + * @rmtoll APCR I3CPB6_PU LL_PWR_EnableI3CPB6PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableI3CPB6PU(void) +{ + SET_BIT(PWR->APCR, PWR_APCR_I3CPB6_PU); +} + +/** + * @brief Disable the pull-up on I3C1_SCL (PB6) in standby mode + * @rmtoll APCR I3CPB6_PU LL_PWR_DisableI3CPB6PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableI3CPB6PU(void) +{ + CLEAR_BIT(PWR->APCR, PWR_APCR_I3CPB6_PU); +} + +/** + * @brief Check if the pull-up on I3C1_SCL (PB6) in standby mode is enabled + * @rmtoll APCR I3CPB6_PU LL_PWR_IsEnabledI3CPB6PU + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledI3CPB6PU(void) +{ + return ((READ_BIT(PWR->APCR, PWR_APCR_I3CPB6_PU) == (PWR_APCR_I3CPB6_PU)) ? 1UL : 0UL); +} + +/** + * @brief Enable the pull-up on I3C1_SDA (PB7) in standby mode + * @rmtoll APCR I3CPB7_PU LL_PWR_EnableI3CPB7PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableI3CPB7PU(void) +{ + SET_BIT(PWR->APCR, PWR_APCR_I3CPB7_PU); +} + +/** + * @brief Disable the pull-up on I3C1_SDA (PB7) in standby mode + * @rmtoll APCR I3CPB7_PU LL_PWR_DisableI3CPB7PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableI3CPB7PU(void) +{ + CLEAR_BIT(PWR->APCR, PWR_APCR_I3CPB7_PU); +} + +/** + * @brief Check if the pull-up on I3C1_SDA (PB7) in standby mode is enabled + * @rmtoll APCR I3CPB7_PU LL_PWR_IsEnabledI3CPB7PU + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledI3CPB7PU(void) +{ + return ((READ_BIT(PWR->APCR, PWR_APCR_I3CPB7_PU) == (PWR_APCR_I3CPB7_PU)) ? 1UL : 0UL); +} + +/** + * @brief Enable the pull-up on I3C1_SCL (PB8) in standby mode + * @rmtoll APCR I3CPB8_PU LL_PWR_EnableI3CPB8PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableI3CPB8PU(void) +{ + SET_BIT(PWR->APCR, PWR_APCR_I3CPB8_PU); +} + +/** + * @brief Disable the pull-up on I3C1_SCL (PB8) in standby mode + * @rmtoll APCR I3CPB8_PU LL_PWR_DisableI3CPB8PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableI3CPB8PU(void) +{ + CLEAR_BIT(PWR->APCR, PWR_APCR_I3CPB8_PU); +} + +/** + * @brief Check if the pull-up on I3C1_SCL (PB8) in standby mode is enabled + * @rmtoll APCR I3CPB8_PU LL_PWR_IsEnabledI3CPB8PU + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledI3CPB8PU(void) +{ + return ((READ_BIT(PWR->APCR, PWR_APCR_I3CPB8_PU) == (PWR_APCR_I3CPB8_PU)) ? 1UL : 0UL); +} + +/** + * @brief Enable the pull-up on I3C1_SDA (PB9) in standby mode + * @rmtoll APCR I3CPB9_PU LL_PWR_EnableI3CPB9PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableI3CPB9PU(void) +{ + SET_BIT(PWR->APCR, PWR_APCR_I3CPB9_PU); +} + +/** + * @brief Disable the pull-up on I3C1_SDA (PB9) in standby mode + * @rmtoll APCR I3CPB9_PU LL_PWR_DisableI3CPB9PU + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableI3CPB9PU(void) +{ + CLEAR_BIT(PWR->APCR, PWR_APCR_I3CPB9_PU); +} + +/** + * @brief Check if the pull-up on I3C1_SDA (PB9) in standby mode is enabled + * @rmtoll APCR I3CPB9_PU LL_PWR_IsEnabledI3CPB9PU + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledI3CPB9PU(void) +{ + return ((READ_BIT(PWR->APCR, PWR_APCR_I3CPB9_PU) == (PWR_APCR_I3CPB9_PU)) ? 1UL : 0UL); +} + +/** + * @brief Enable the pull-up and pull-down configuration + * @rmtoll APCR APC LL_PWR_EnablePUPDConfig + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnablePUPDConfig(void) +{ + SET_BIT(PWR->APCR, PWR_APCR_APC); +} + +/** + * @brief Disable the pull-up and pull-down configuration + * @rmtoll APCR APC LL_PWR_DisablePUPDConfig + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisablePUPDConfig(void) +{ + CLEAR_BIT(PWR->APCR, PWR_APCR_APC); +} + +/** + * @brief Check if the pull-up and pull-down configuration is enabled. + * @rmtoll APCR APC LL_PWR_IsEnabledPUPDConfig + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledPUPDConfig(void) +{ + return ((READ_BIT(PWR->APCR, PWR_APCR_APC) == (PWR_APCR_APC)) ? 1UL : 0UL); +} + +/** + * @brief Enable GPIO N pull-up in Standby mode + * @rmtoll PUCRN PUx LL_PWR_EnableGPIONPullUp + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_6 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_EnableGPIONPullUp(uint32_t GPIOPin) +{ + SET_BIT(PWR->PUCRN, GPIOPin); +} + +/** + * @brief Disable GPIO N pull-up in Standby mode + * @rmtoll PUCRN PUx LL_PWR_DisableGPIONPullUp + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_6 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_DisableGPIONPullUp(uint32_t GPIOPin) +{ + CLEAR_BIT(PWR->PUCRN, GPIOPin); +} + +/** + * @brief Check if GPIO pull-up in Standby mode is enabled + * @rmtoll PUCRN PUx LL_PWR_IsEnabledGPIONPullUp + * @param GPIOPin This parameter can be one of the following values: + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_6 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledGPIONPullUp(uint32_t GPIOPin) +{ + return ((READ_BIT(PWR->PUCRN, GPIOPin) == (GPIOPin)) ? 1UL : 0UL); +} + +/** + * @brief Enable GPIO O pull-up in Standby mode + * @rmtoll PUCRO PUx LL_PWR_EnableGPIOOPullUp + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_4 + + * @retval None. + */ +__STATIC_INLINE void LL_PWR_EnableGPIOOPullUp(uint32_t GPIOPin) +{ + SET_BIT(PWR->PUCRO, GPIOPin); +} + +/** + * @brief Disable GPIO O pull-up in Standby mode + * @rmtoll PUCRO PUx LL_PWR_DisableGPIOOPullUp + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_DisableGPIOOPullUp(uint32_t GPIOPin) +{ + CLEAR_BIT(PWR->PUCRO, GPIOPin); +} + +/** + * @brief Check if GPIO O pull-up in Standby mode is enabled + * @rmtoll PUCRO PUx LL_PWR_IsEnabledGPIOOPullUp + * @param GPIOPin This parameter can be one of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledGPIOOPullUp(uint32_t GPIOPin) +{ + return ((READ_BIT(PWR->PUCRO, GPIOPin) == (GPIOPin)) ? 1UL : 0UL); +} + +/** + * @brief Enable GPIO N pull-down in Standby mode + * @rmtoll PDCRN PDx LL_PWR_EnableGPIONPullDown + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_2 + * @arg @ref LL_PWR_GPIO_PIN_6 + * @arg @ref LL_PWR_GPIO_PIN_8 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_EnableGPIONPullDown(uint32_t GPIOPin) +{ + SET_BIT(PWR->PDCRN, GPIOPin); +} + +/** + * @brief Disable GPIO N pull-down in Standby mode + * @rmtoll PDCRN PDx LL_PWR_DisableGPIONPullDown + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_2 + * @arg @ref LL_PWR_GPIO_PIN_6 + * @arg @ref LL_PWR_GPIO_PIN_8 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_DisableGPIONPullDown(uint32_t GPIOPin) +{ + CLEAR_BIT(PWR->PDCRN, GPIOPin); +} + +/** + * @brief Check if GPIO N pull-down in Standby mode is enabled + * @rmtoll PDCRN PDx LL_PWR_IsEnabledGPIONPullDown + * @param GPIOPin This parameter can be one of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_2 + * @arg @ref LL_PWR_GPIO_PIN_6 + * @arg @ref LL_PWR_GPIO_PIN_8 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledGPIONPullDown(uint32_t GPIOPin) +{ + return ((READ_BIT(PWR->PDCRN, GPIOPin) == (GPIOPin)) ? 1UL : 0UL); +} +/** + * @brief Enable GPIO O pull-down in Standby mode + * @rmtoll PDCRO PDx LL_PWR_EnableGPIOOPullDown + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_2 + * @arg @ref LL_PWR_GPIO_PIN_3 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_EnableGPIOOPullDown(uint32_t GPIOPin) +{ + SET_BIT(PWR->PDCRO, GPIOPin); +} + +/** + * @brief Disable GPIO O pull-down in Standby mode + * @rmtoll PDCRO PDx LL_PWR_DisableGPIOOPullDown + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_2 + * @arg @ref LL_PWR_GPIO_PIN_3 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_DisableGPIOOPullDown(uint32_t GPIOPin) +{ + CLEAR_BIT(PWR->PDCRO, GPIOPin); +} + +/** + * @brief Check if GPIO O pull-down in Standby mode is enabled + * @rmtoll PDCRO PDx LL_PWR_IsEnabledGPIOOPullDown + * @param GPIOPin This parameter can be one of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_1 + * @arg @ref LL_PWR_GPIO_PIN_2 + * @arg @ref LL_PWR_GPIO_PIN_3 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledGPIOOPullDown(uint32_t GPIOPin) +{ + return ((READ_BIT(PWR->PDCRO, GPIOPin) == (GPIOPin)) ? 1UL : 0UL); +} + +/** + * @brief Enable GPIO P pull-down in Standby mode + * @rmtoll PDCRP PDx LL_PWR_EnableGPIOPPullDown + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @arg @ref LL_PWR_GPIO_PIN_8 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_EnableGPIOPPullDown(uint32_t GPIOPin) +{ + SET_BIT(PWR->PDCRP, GPIOPin); +} + +/** + * @brief Disable GPIO P pull-down in Standby mode + * @rmtoll PDCRP PDx LL_PWR_DisableGPIOPPullDown + * @param GPIOPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @arg @ref LL_PWR_GPIO_PIN_8 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval None. + */ +__STATIC_INLINE void LL_PWR_DisableGPIOPPullDown(uint32_t GPIOPin) +{ + CLEAR_BIT(PWR->PDCRP, GPIOPin); +} + +/** + * @brief Check if GPIO P pull-down in Standby mode is enabled + * @rmtoll PDCRP PDx LL_PWR_IsEnabledGPIOPPullDown + * @param GPIOPin This parameter can be one of the following values: + * @arg @ref LL_PWR_GPIO_PIN_0 + * @arg @ref LL_PWR_GPIO_PIN_4 + * @arg @ref LL_PWR_GPIO_PIN_8 + * @arg @ref LL_PWR_GPIO_PIN_12 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledGPIOPPullDown(uint32_t GPIOPin) +{ + return ((READ_BIT(PWR->PDCRP, GPIOPin) == (GPIOPin)) ? 1UL : 0UL); +} +/** + * @} + */ + + +/** @defgroup PWR_LL_EF_FLAG_MANAGEMENT PWR FLAG Management + * @{ + */ + +/** + * @brief Indicate whether the voltage level is ready for current actual used VOS + * @rmtoll SR1 ACTVOSRDY LL_PWR_IsActiveFlag_ACTVOSRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_ACTVOSRDY(void) +{ + return ((READ_BIT(PWR->SR1, PWR_SR1_ACTVOSRDY) == (PWR_SR1_ACTVOSRDY)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether VDD voltage is below the selected PVD threshold + * @rmtoll SR1 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->SR1, PWR_SR1_PVDO) == (PWR_SR1_PVDO)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether VDDA voltage is below the selected AVD threshold + * @rmtoll SR1 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->SR1, PWR_SR1_AVDO) == (PWR_SR1_AVDO)) ? 1UL : 0UL); +} + +/** + * @brief Get Backup Regulator ready Flag + * @rmtoll CSR1 BRRDY LL_PWR_IsActiveFlag_BRRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_BRRDY(void) +{ + return ((READ_BIT(PWR->CSR1, PWR_CSR1_BRRDY) == (PWR_CSR1_BRRDY)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the VBAT level is above or below low threshold + * @rmtoll CSR1 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->CSR1, PWR_CSR1_VBATL) == (PWR_CSR1_VBATL)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the VBAT level is above or below high threshold + * @rmtoll CSR1 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->CSR1, PWR_CSR1_VBATH) == (PWR_CSR1_VBATH)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the CPU temperature level is above or below low threshold + * @rmtoll CSR1 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->CSR1, PWR_CSR1_TEMPL) == (PWR_CSR1_TEMPL)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the CPU temperature level is above or below high threshold + * @rmtoll CSR1 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->CSR1, PWR_CSR1_TEMPH) == (PWR_CSR1_TEMPH)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the SMPS external supply is ready or not + * @rmtoll CSR2 SDEXTRDY LL_PWR_IsActiveFlag_SDEXTRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_SDEXTRDY(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_SDEXTRDY) == (PWR_CSR2_SDEXTRDY)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the USB supply is ready or not + * @rmtoll CSR2 USB33RDY LL_PWR_IsActiveFlag_USB33RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_USB33RDY(void) +{ + return ((READ_BIT(PWR->CSR2, PWR_CSR2_USB33RDY) == (PWR_CSR2_USB33RDY)) ? 1UL : 0UL); +} + +/** + * @brief Get System Stop Flag + * @rmtoll CSR3 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->CSR3, PWR_CSR3_STOPF) == (PWR_CSR3_STOPF)) ? 1UL : 0UL); +} + +/** + * @brief Get System Standby Flag + * @rmtoll CSR3 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->CSR3, PWR_CSR3_SBF) == (PWR_CSR3_SBF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the Regulator is ready in the selected voltage range + * or if its output voltage is still changing to the required voltage level + * @rmtoll CSR4 VOSRDY LL_PWR_IsActiveFlag_VOSRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VOSRDY(void) +{ + return ((READ_BIT(PWR->CSR4, PWR_CSR4_VOSRDY) == (PWR_CSR4_VOSRDY)) ? 1UL : 0UL); +} + +/** + * @brief Get Wake-up Flag 1 + * @rmtoll WKUPFR WKUPF1 LL_PWR_IsActiveFlag_WU1 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU1(void) +{ + return ((READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF1) == (PWR_WKUPFR_WKUPF1)) ? 1UL : 0UL); +} + +/** + * @brief Get Wake-up Flag 2 + * @rmtoll WKUPFR WKUPF2 LL_PWR_IsActiveFlag_WU2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU2(void) +{ + return ((READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF2) == (PWR_WKUPFR_WKUPF2)) ? 1UL : 0UL); +} + +/** + * @brief Get Wake-up Flag 3 + * @rmtoll WKUPFR WKUPF3 LL_PWR_IsActiveFlag_WU3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU3(void) +{ + return ((READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF3) == (PWR_WKUPFR_WKUPF3)) ? 1UL : 0UL); +} + +/** + * @brief Get Wake-up Flag 4 + * @rmtoll WKUPFR WKUPF4 LL_PWR_IsActiveFlag_WU4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU4(void) +{ + return ((READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF4) == (PWR_WKUPFR_WKUPF4)) ? 1UL : 0UL); +} + +/** + * @brief Clear STOP and STANDBY and flags + * @rmtoll CSR3 CSSF LL_PWR_ClearFlag_STOP_SB + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_STOP_SB(void) +{ + SET_BIT(PWR->CSR3, PWR_CSR3_CSSF); +} + +/** + * @brief Clear Wake-up Flag 1 + * @rmtoll WKUPCR WKUPC1 LL_PWR_ClearFlag_WU1 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU1(void) +{ + WRITE_REG(PWR->WKUPCR, PWR_WKUPCR_WKUPC1); +} + +/** + * @brief Clear Wake-up Flag 2 + * @rmtoll WKUPCR WKUPC2 LL_PWR_ClearFlag_WU2 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU2(void) +{ + WRITE_REG(PWR->WKUPCR, PWR_WKUPCR_WKUPC2); +} + +/** + * @brief Clear Wake-up Flag 3 + * @rmtoll WKUPCR WKUPC3 LL_PWR_ClearFlag_WU3 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU3(void) +{ + WRITE_REG(PWR->WKUPCR, PWR_WKUPCR_WKUPC3); +} + +/** + * @brief Clear Wake-up Flag 4 + * @rmtoll WKUPCR WKUPC4 LL_PWR_ClearFlag_WU4 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU4(void) +{ + WRITE_REG(PWR->WKUPCR, PWR_WKUPCR_WKUPC4); +} + +/** + * @brief Clear all wake up flags. + * @rmtoll WUSCR WKUPC LL_PWR_ClearFlag_WU + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU(void) +{ + WRITE_REG(PWR->WKUPCR, PWR_WKUPCR_WKUPC); +} + +/** + * @} + */ + +#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 + +#endif /* STM32H7RSxx_LL_PWR_H */ + + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_rcc.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_rcc.h new file mode 100644 index 0000000..96df2c7 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_rcc.h @@ -0,0 +1,5934 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_rcc.h + * @author MCD Application Team + * @brief Header file of RCC LL 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 STM32H7RSxx_LL_RCC_H +#define STM32H7RSxx_LL_RCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" +#include + +/** @addtogroup STM32H7RSxx_LL_Driver + * @{ + */ + +#if defined(RCC) + +/** @defgroup RCC_LL RCC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCC_LL_Private_Constants RCC Private Constants + * @{ + */ +/* + LL_CLKSOURCE() macro output description + + 31 24 16 8 0 + -------------------------------------------------------- + | Mask | ClkSource | Bit | Register | + | | Config | Position | Offset | + -------------------------------------------------------- +*/ +#define LL_RCC_REG_SHIFT 0U +#define LL_RCC_POS_SHIFT 8U +#define LL_RCC_CONFIG_SHIFT 16U +#define LL_RCC_MASK_SHIFT 24U + +/* Clock source register offset vs CCIPR1 register */ +#define CCIPR1_OFFSET 0x0UL +#define CCIPR2_OFFSET 0x4UL +#define CCIPR3_OFFSET 0x8UL +#define CCIPR4_OFFSET 0xCUL + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RCC_LL_Private_Macros RCC Private Macros + * @{ + */ +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif /* UNUSED */ + +#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)((((uint32_t)(__MSK__) >> (__POS__)) << LL_RCC_MASK_SHIFT) | \ + (((uint32_t)(__POS__) ) << LL_RCC_POS_SHIFT) | \ + (((uint32_t)(__REG__) ) << LL_RCC_REG_SHIFT) | \ + (((uint32_t)(__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; + uint32_t CPUCLK_Frequency; + uint32_t HCLK_Frequency; + uint32_t PCLK1_Frequency; + uint32_t PCLK2_Frequency; + uint32_t PCLK4_Frequency; + uint32_t PCLK5_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; + uint32_t PLL_S_Frequency; + uint32_t PLL_T_Frequency; +} LL_PLL_ClocksTypeDef; + +/** + * @brief PLL Spread Spectrum Mode Structure + */ +typedef struct +{ + uint16_t ModulationPeriod; /* Modulation Period (value between 0 to 2^13-1) */ + uint16_t IncrementStep; /* Modulation Depth (value between 0 to 2^15-1) */ + uint16_t SpreadMode; /* LL_RCC_PLL_SPREAD_CENTER or LL_RCC_PLL_SPREAD_DOWN */ + uint16_t DitheringRPDFN; /* Rectangular probability density function noise enable/disable */ + uint16_t DitheringTPDFN; /* Triangular probability density function noise enable/disable */ +} LL_PLL_SpreadSpectrumTypeDef; + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported variables --------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Variables RCC Exported Variables + * @{ + */ +extern const uint8_t LL_RCC_PrescTable[16]; + +/** + * @} + */ + +/* 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 24000000U /*!< 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 (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the I2S_CKIN external oscillator in Hz */ +#endif /* EXTERNAL_CLOCK_VALUE */ + +#if !defined (HSI48_VALUE) +#define HSI48_VALUE 48000000U /*!< Value of the HSI48 oscillator in Hz */ +#endif /* HSI48_VALUE */ + +/** + * @} + */ + +/** @defgroup RCC_LL_EC_HSIDIV HSI oscillator divider + * @{ + */ +#define LL_RCC_HSI_DIV_1 0U +#define LL_RCC_HSI_DIV_2 RCC_CR_HSIDIV_0 +#define LL_RCC_HSI_DIV_4 RCC_CR_HSIDIV_1 +#define LL_RCC_HSI_DIV_8 RCC_CR_HSIDIV +/** + * @} + */ + +/** @defgroup LL_RCC_EC_XSPI1SWP XSXPI1 kernel clock switch position + * @{ + */ +#define LL_RCC_SWP_XSPI1_NEUTRAL 0U +#define LL_RCC_SWP_XSPI1_HCLK5 RCC_CKPROTR_XSPI1SWP_0 +#define LL_RCC_SWP_XSPI1_PLL2S RCC_CKPROTR_XSPI1SWP_1 +#define LL_RCC_SWP_XSPI1_PLL2T (RCC_CKPROTR_XSPI1SWP_1 | RCC_CKPROTR_XSPI1SWP_0) +#define LL_RCC_SWP_XSPI1_HCLK_DIV4 RCC_CKPROTR_XSPI1SWP_2 +/** + * @} + */ + +/** @defgroup LL_RCC_EC_XSPI2SWP SXPI2 kernel clock switch position + * @{ + */ +#define LL_RCC_SWP_XSPI2_NEUTRAL 0U +#define LL_RCC_SWP_XSPI2_HCLK5 RCC_CKPROTR_XSPI2SWP_0 +#define LL_RCC_SWP_XSPI2_PLL2S RCC_CKPROTR_XSPI2SWP_1 +#define LL_RCC_SWP_XSPI2_PLL2T (RCC_CKPROTR_XSPI2SWP_1 | RCC_CKPROTR_XSPI2SWP_0) +#define LL_RCC_SWP_XSPI2_HCLK_DIV4 RCC_CKPROTR_XSPI2SWP_2 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_FMCSWP FMC kernel clock switch position + * @{ + */ +#define LL_RCC_SWP_FMC_NEUTRAL 0U +#define LL_RCC_SWP_FMC_HCLK5 RCC_CKPROTR_FMCSWP_0 +#define LL_RCC_SWP_FMC_PLL1Q RCC_CKPROTR_FMCSWP_1 +#define LL_RCC_SWP_FMC_PLL2R (RCC_CKPROTR_FMCSWP_1 | RCC_CKPROTR_FMCSWP_0) +#define LL_RCC_SWP_FMC_HSI RCC_CKPROTR_FMCSWP_2 +#define LL_RCC_SWP_FMC_HCLK_DIV4 (RCC_CKPROTR_FMCSWP_2 | RCC_CKPROTR_FMCSWP_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LSEDRIVE LSE oscillator drive capability + * @{ + */ +#define LL_RCC_LSEDRIVE_LOW 0U +#define LL_RCC_LSEDRIVE_MEDIUMLOW RCC_BDCR_LSEDRV_0 +#define LL_RCC_LSEDRIVE_MEDIUMHIGH RCC_BDCR_LSEDRV_1 +#define LL_RCC_LSEDRIVE_HIGH RCC_BDCR_LSEDRV +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYS_CLKSOURCE System clock switch + * @{ + */ +#define LL_RCC_SYS_CLKSOURCE_HSI 0U +#define LL_RCC_SYS_CLKSOURCE_CSI RCC_CFGR_SW_0 +#define LL_RCC_SYS_CLKSOURCE_HSE RCC_CFGR_SW_1 +#define LL_RCC_SYS_CLKSOURCE_PLL1 (RCC_CFGR_SW_1 | RCC_CFGR_SW_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYS_CLKSOURCE_STATUS System clock switch status + * @{ + */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSI 0U /*!< HSI used as system clock */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_CSI RCC_CFGR_SWS_0 /*!< CSI used as system clock */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSE RCC_CFGR_SWS_1 /*!< HSE used as system clock */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_PLL1 (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0) /*!< PLL1 used as system clock */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYSWAKEUP_CLKSOURCE System wakeup clock source + * @{ + */ +#define LL_RCC_SYSWAKEUP_CLKSOURCE_HSI 0U +#define LL_RCC_SYSWAKEUP_CLKSOURCE_CSI RCC_CFGR_STOPWUCK +/** + * @} + */ + +/** @defgroup RCC_LL_EC_KERWAKEUP_CLKSOURCE Kernel wakeup clock source + * @{ + */ +#define LL_RCC_KERWAKEUP_CLKSOURCE_HSI 0U +#define LL_RCC_KERWAKEUP_CLKSOURCE_CSI RCC_CFGR_STOPKERWUCK +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYSCLK_DIV System prescaler + * @{ + */ +#define LL_RCC_SYSCLK_DIV_1 0U +#define LL_RCC_SYSCLK_DIV_2 RCC_CDCFGR_CPRE_3 +#define LL_RCC_SYSCLK_DIV_4 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_0) +#define LL_RCC_SYSCLK_DIV_8 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_1) +#define LL_RCC_SYSCLK_DIV_16 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_1 | RCC_CDCFGR_CPRE_0) +#define LL_RCC_SYSCLK_DIV_64 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2) +#define LL_RCC_SYSCLK_DIV_128 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2 | RCC_CDCFGR_CPRE_0) +#define LL_RCC_SYSCLK_DIV_256 (RCC_CDCFGR_CPRE_3 | RCC_CDCFGR_CPRE_2 | RCC_CDCFGR_CPRE_1) +#define LL_RCC_SYSCLK_DIV_512 RCC_CDCFGR_CPRE +/** + * @} + */ + +/** @defgroup RCC_LL_EC_AHB_DIV AHB prescaler + * @{ + */ +#define LL_RCC_AHB_DIV_1 0U +#define LL_RCC_AHB_DIV_2 RCC_BMCFGR_BMPRE_3 +#define LL_RCC_AHB_DIV_4 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_0) +#define LL_RCC_AHB_DIV_8 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_1) +#define LL_RCC_AHB_DIV_16 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_1 | RCC_BMCFGR_BMPRE_0) +#define LL_RCC_AHB_DIV_64 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2) +#define LL_RCC_AHB_DIV_128 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2 | RCC_BMCFGR_BMPRE_0) +#define LL_RCC_AHB_DIV_256 (RCC_BMCFGR_BMPRE_3 | RCC_BMCFGR_BMPRE_2 | RCC_BMCFGR_BMPRE_1) +#define LL_RCC_AHB_DIV_512 RCC_BMCFGR_BMPRE +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB1_DIV APB1 prescaler + * @{ + */ +#define LL_RCC_APB1_DIV_1 0U +#define LL_RCC_APB1_DIV_2 RCC_APBCFGR_PPRE1_2 +#define LL_RCC_APB1_DIV_4 (RCC_APBCFGR_PPRE1_2 | RCC_APBCFGR_PPRE1_0) +#define LL_RCC_APB1_DIV_8 (RCC_APBCFGR_PPRE1_2 | RCC_APBCFGR_PPRE1_1) +#define LL_RCC_APB1_DIV_16 RCC_APBCFGR_PPRE1 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB2_DIV APB2 prescaler + * @{ + */ +#define LL_RCC_APB2_DIV_1 0U +#define LL_RCC_APB2_DIV_2 RCC_APBCFGR_PPRE2_2 +#define LL_RCC_APB2_DIV_4 (RCC_APBCFGR_PPRE2_2 | RCC_APBCFGR_PPRE2_0) +#define LL_RCC_APB2_DIV_8 (RCC_APBCFGR_PPRE2_2 | RCC_APBCFGR_PPRE2_1) +#define LL_RCC_APB2_DIV_16 RCC_APBCFGR_PPRE2 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB4_DIV APB4 prescaler + * @{ + */ +#define LL_RCC_APB4_DIV_1 0U +#define LL_RCC_APB4_DIV_2 RCC_APBCFGR_PPRE4_2 +#define LL_RCC_APB4_DIV_4 (RCC_APBCFGR_PPRE4_2 | RCC_APBCFGR_PPRE4_0) +#define LL_RCC_APB4_DIV_8 (RCC_APBCFGR_PPRE4_2 | RCC_APBCFGR_PPRE4_1) +#define LL_RCC_APB4_DIV_16 RCC_APBCFGR_PPRE4 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB5_DIV APB5 prescaler + * @{ + */ +#define LL_RCC_APB5_DIV_1 0U +#define LL_RCC_APB5_DIV_2 RCC_APBCFGR_PPRE5_2 +#define LL_RCC_APB5_DIV_4 (RCC_APBCFGR_PPRE5_2 | RCC_APBCFGR_PPRE5_0) +#define LL_RCC_APB5_DIV_8 (RCC_APBCFGR_PPRE5_2 | RCC_APBCFGR_PPRE5_1) +#define LL_RCC_APB5_DIV_16 RCC_APBCFGR_PPRE5 +/** + * @} + */ + + +/** @defgroup RCC_LL_EC_MCOxSOURCE MCO source selection + * @{ + */ +#define LL_RCC_MCO1SOURCE_HSI ((RCC_CFGR_MCO1SEL>>16U) | 0U) +#define LL_RCC_MCO1SOURCE_LSE ((RCC_CFGR_MCO1SEL>>16U) | RCC_CFGR_MCO1SEL_0) +#define LL_RCC_MCO1SOURCE_HSE ((RCC_CFGR_MCO1SEL>>16U) | RCC_CFGR_MCO1SEL_1) +#define LL_RCC_MCO1SOURCE_PLL1Q ((RCC_CFGR_MCO1SEL>>16U) | RCC_CFGR_MCO1SEL_1 | RCC_CFGR_MCO1SEL_0) +#define LL_RCC_MCO1SOURCE_HSI48 ((RCC_CFGR_MCO1SEL>>16U) | RCC_CFGR_MCO1SEL_2) +#define LL_RCC_MCO2SOURCE_SYSCLK ((RCC_CFGR_MCO2SEL>>16U) | 0U) +#define LL_RCC_MCO2SOURCE_PLL2P ((RCC_CFGR_MCO2SEL>>16U) | RCC_CFGR_MCO2SEL_0) +#define LL_RCC_MCO2SOURCE_HSE ((RCC_CFGR_MCO2SEL>>16U) | RCC_CFGR_MCO2SEL_1) +#define LL_RCC_MCO2SOURCE_PLL1P ((RCC_CFGR_MCO2SEL>>16U) | RCC_CFGR_MCO2SEL_1 | RCC_CFGR_MCO2SEL_0) +#define LL_RCC_MCO2SOURCE_CSI ((RCC_CFGR_MCO2SEL>>16U) | RCC_CFGR_MCO2SEL_2) +#define LL_RCC_MCO2SOURCE_LSI ((RCC_CFGR_MCO2SEL>>16U) | RCC_CFGR_MCO2SEL_2 | RCC_CFGR_MCO2SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_MCOx_DIV MCO prescaler + * @{ + */ +#define LL_RCC_MCO1_DIV_1 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_0) +#define LL_RCC_MCO1_DIV_2 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_1) +#define LL_RCC_MCO1_DIV_3 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_1) +#define LL_RCC_MCO1_DIV_4 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_5 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_6 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_7 ((RCC_CFGR_MCO1PRE>>16U) |\ + RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_8 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_9 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_10 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_11 ((RCC_CFGR_MCO1PRE>>16U) |\ + RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_12 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_13 ((RCC_CFGR_MCO1PRE>>16U) |\ + RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_14 ((RCC_CFGR_MCO1PRE>>16U) |\ + RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_2 | RCC_CFGR_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_15 ((RCC_CFGR_MCO1PRE>>16U) | RCC_CFGR_MCO1PRE) +#define LL_RCC_MCO2_DIV_1 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_0) +#define LL_RCC_MCO2_DIV_2 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_1) +#define LL_RCC_MCO2_DIV_3 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_0 | RCC_CFGR_MCO2PRE_1) +#define LL_RCC_MCO2_DIV_4 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_5 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_0 | RCC_CFGR_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_6 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_1 | RCC_CFGR_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_7 ((RCC_CFGR_MCO2PRE>>16U) |\ + RCC_CFGR_MCO2PRE_0 | RCC_CFGR_MCO2PRE_1 | RCC_CFGR_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_8 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_9 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_0 | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_10 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_1 | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_11 ((RCC_CFGR_MCO2PRE>>16U) |\ + RCC_CFGR_MCO2PRE_0 | RCC_CFGR_MCO2PRE_1 | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_12 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE_2 | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_13 ((RCC_CFGR_MCO2PRE>>16U) |\ + RCC_CFGR_MCO2PRE_0 | RCC_CFGR_MCO2PRE_2 | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_14 ((RCC_CFGR_MCO2PRE>>16U) |\ + RCC_CFGR_MCO2PRE_1 | RCC_CFGR_MCO2PRE_2 | RCC_CFGR_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_15 ((RCC_CFGR_MCO2PRE>>16U) | RCC_CFGR_MCO2PRE) + +/** + * @} + */ + +/** @defgroup RCC_LL_EC_RTC_HSEDIV HSE prescaler for RTC clock + * @{ + */ +#define LL_RCC_RTC_NOCLOCK 0U +#define LL_RCC_RTC_HSE_DIV_2 (RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_3 (RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_4 (RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_5 (RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_6 (RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_7 (RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_8 (RCC_CFGR_RTCPRE_3) +#define LL_RCC_RTC_HSE_DIV_9 (RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_10 (RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_11 (RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_12 (RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_13 (RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_14 (RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_15 (RCC_CFGR_RTCPRE_3 |\ + RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_16 (RCC_CFGR_RTCPRE_4) +#define LL_RCC_RTC_HSE_DIV_17 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_18 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_19 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_20 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_21 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_22 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_23 (RCC_CFGR_RTCPRE_4 |\ + RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_24 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3) +#define LL_RCC_RTC_HSE_DIV_25 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_26 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_27 (RCC_CFGR_RTCPRE_4 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_28 (RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_29 (RCC_CFGR_RTCPRE_4 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_30 (RCC_CFGR_RTCPRE_4 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_31 (RCC_CFGR_RTCPRE_4 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_32 (RCC_CFGR_RTCPRE_5) +#define LL_RCC_RTC_HSE_DIV_33 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_34 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_35 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_36 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_37 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_38 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_39 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_40 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_3) +#define LL_RCC_RTC_HSE_DIV_41 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_42 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_43 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_44 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_45 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_46 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_47 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_48 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_4) +#define LL_RCC_RTC_HSE_DIV_49 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_50 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_51 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_52 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_53 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_54 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_55 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_56 (RCC_CFGR_RTCPRE_5 | RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3) +#define LL_RCC_RTC_HSE_DIV_57 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_58 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_59 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_60 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2) +#define LL_RCC_RTC_HSE_DIV_61 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_0) +#define LL_RCC_RTC_HSE_DIV_62 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1) +#define LL_RCC_RTC_HSE_DIV_63 (RCC_CFGR_RTCPRE_5 |\ + RCC_CFGR_RTCPRE_4 | RCC_CFGR_RTCPRE_3 | RCC_CFGR_RTCPRE_2 | RCC_CFGR_RTCPRE_1 | RCC_CFGR_RTCPRE_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_ADC_CLKSOURCE Peripheral ADC clock source selection + * @{ + */ +#define LL_RCC_ADC_CLKSOURCE_PLL2P 0U +#define LL_RCC_ADC_CLKSOURCE_PLL3R RCC_CCIPR1_ADCSEL_0 +#define LL_RCC_ADC_CLKSOURCE_CLKP RCC_CCIPR1_ADCSEL_1 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_ADFx_CLKSOURCE Peripheral ADF clock source selection + * @{ + */ +#define LL_RCC_ADF1_CLKSOURCE_HCLK 0U +#define LL_RCC_ADF1_CLKSOURCE_PLL2P RCC_CCIPR1_ADF1SEL_0 +#define LL_RCC_ADF1_CLKSOURCE_PLL3P RCC_CCIPR1_ADF1SEL_1 +#define LL_RCC_ADF1_CLKSOURCE_I2S_CKIN (RCC_CCIPR1_ADF1SEL_1 | RCC_CCIPR1_ADF1SEL_0) +#define LL_RCC_ADF1_CLKSOURCE_CSI RCC_CCIPR1_ADF1SEL_2 +#define LL_RCC_ADF1_CLKSOURCE_HSI (RCC_CCIPR1_ADF1SEL_2 | RCC_CCIPR1_ADF1SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_CEC_CLKSOURCE Peripheral CEC clock source selection + * @{ + */ +#define LL_RCC_CEC_CLKSOURCE_LSE 0U +#define LL_RCC_CEC_CLKSOURCE_LSI RCC_CCIPR2_CECSEL_0 +#define LL_RCC_CEC_CLKSOURCE_CSI_DIV_122 RCC_CCIPR2_CECSEL_1 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_CLKP_CLKSOURCE Peripheral CLKP clock source selection + * @{ + */ +#define LL_RCC_CLKP_CLKSOURCE_HSI 0U +#define LL_RCC_CLKP_CLKSOURCE_CSI RCC_CCIPR1_CKPERSEL_0 +#define LL_RCC_CLKP_CLKSOURCE_HSE RCC_CCIPR1_CKPERSEL_1 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_ETHxPHY_CLKSOURCE Peripheral ETHPHY clock source selection + * @{ + */ +#define LL_RCC_ETH1PHY_CLKSOURCE_HSE 0U +#define LL_RCC_ETH1PHY_CLKSOURCE_PLL3S RCC_CCIPR1_ETH1PHYCKSEL +/** + * @} + */ + +/** @defgroup RCC_LL_EC_ETHxREF_CLKSOURCE Peripheral ETHREF clock source selection + * @{ + */ +#define LL_RCC_ETH1REF_CLKSOURCE_RMII 0U +#define LL_RCC_ETH1REF_CLKSOURCE_HSE RCC_CCIPR1_ETH1REFCKSEL_0 +#define LL_RCC_ETH1REF_CLKSOURCE_FB RCC_CCIPR1_ETH1REFCKSEL_1 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_FDCAN_CLKSOURCE Peripheral FDCAN clock source selection + * @{ + */ +#define LL_RCC_FDCAN_CLKSOURCE_HSE 0U +#define LL_RCC_FDCAN_CLKSOURCE_PLL1Q RCC_CCIPR2_FDCANSEL_0 +#define LL_RCC_FDCAN_CLKSOURCE_PLL2Q RCC_CCIPR2_FDCANSEL_1 +/** + * @} + */ + +/** @defgroup RCC_LL_EC_FMC_CLKSOURCE Peripheral FMC clock source selection + * @{ + */ +#define LL_RCC_FMC_CLKSOURCE_HCLK 0U +#define LL_RCC_FMC_CLKSOURCE_PLL1Q RCC_CCIPR1_FMCSEL_0 +#define LL_RCC_FMC_CLKSOURCE_PLL2R RCC_CCIPR1_FMCSEL_1 +#define LL_RCC_FMC_CLKSOURCE_HSI (RCC_CCIPR1_FMCSEL_1 | RCC_CCIPR1_FMCSEL_0) +#define LL_RCC_FMC_CLKSOURCE_HCLK_DIV4 LL_RCC_SWP_FMC_HCLK_DIV4 /* Recovery: Read-only */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I2Cx_CLKSOURCE Peripheral I2C clock source selection + * @{ + */ +#define LL_RCC_I2C1_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C1_I3C1SEL, RCC_CCIPR2_I2C1_I3C1SEL_Pos, 0U) +#define LL_RCC_I2C1_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C1_I3C1SEL, RCC_CCIPR2_I2C1_I3C1SEL_Pos, RCC_CCIPR2_I2C1_I3C1SEL_0) +#define LL_RCC_I2C1_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C1_I3C1SEL, RCC_CCIPR2_I2C1_I3C1SEL_Pos, RCC_CCIPR2_I2C1_I3C1SEL_1) +#define LL_RCC_I2C1_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C1_I3C1SEL, RCC_CCIPR2_I2C1_I3C1SEL_Pos, RCC_CCIPR2_I2C1_I3C1SEL_1 |\ + RCC_CCIPR2_I2C1_I3C1SEL_0) + +#define LL_RCC_I2C23_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C23SEL, RCC_CCIPR2_I2C23SEL_Pos, 0U) +#define LL_RCC_I2C23_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C23SEL, RCC_CCIPR2_I2C23SEL_Pos, RCC_CCIPR2_I2C23SEL_0) +#define LL_RCC_I2C23_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C23SEL, RCC_CCIPR2_I2C23SEL_Pos, RCC_CCIPR2_I2C23SEL_1) +#define LL_RCC_I2C23_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C23SEL, RCC_CCIPR2_I2C23SEL_Pos, RCC_CCIPR2_I2C23SEL_1 |\ + RCC_CCIPR2_I2C23SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I3Cx_CLKSOURCE Peripheral I3C clock source selection + * @{ + */ +#define LL_RCC_I3C1_CLKSOURCE_PCLK1 0U +#define LL_RCC_I3C1_CLKSOURCE_PLL3R RCC_CCIPR2_I2C1_I3C1SEL_0 +#define LL_RCC_I3C1_CLKSOURCE_HSI RCC_CCIPR2_I2C1_I3C1SEL_1 +#define LL_RCC_I3C1_CLKSOURCE_CSI (RCC_CCIPR2_I2C1_I3C1SEL_1 | RCC_CCIPR2_I2C1_I3C1SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LPTIMx_CLKSOURCE Peripheral LPTIM clock source selection + * @{ + */ +#define LL_RCC_LPTIM1_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, 0U) +#define LL_RCC_LPTIM1_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_0) +#define LL_RCC_LPTIM1_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_1) +#define LL_RCC_LPTIM1_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_1 |\ + RCC_CCIPR2_LPTIM1SEL_0) +#define LL_RCC_LPTIM1_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_2) +#define LL_RCC_LPTIM1_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_2 |\ + RCC_CCIPR2_LPTIM1SEL_0) + +#define LL_RCC_LPTIM23_CLKSOURCE_PCLK4 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, 0U) +#define LL_RCC_LPTIM23_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, RCC_CCIPR4_LPTIM23SEL_0) +#define LL_RCC_LPTIM23_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, RCC_CCIPR4_LPTIM23SEL_1) +#define LL_RCC_LPTIM23_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, RCC_CCIPR4_LPTIM23SEL_1 |\ + RCC_CCIPR4_LPTIM23SEL_0) +#define LL_RCC_LPTIM23_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, RCC_CCIPR4_LPTIM23SEL_2) +#define LL_RCC_LPTIM23_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, RCC_CCIPR4_LPTIM23SEL_2 |\ + RCC_CCIPR4_LPTIM23SEL_0) + +#define LL_RCC_LPTIM45_CLKSOURCE_PCLK4 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, 0U) +#define LL_RCC_LPTIM45_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, RCC_CCIPR4_LPTIM45SEL_0) +#define LL_RCC_LPTIM45_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, RCC_CCIPR4_LPTIM45SEL_1) +#define LL_RCC_LPTIM45_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, RCC_CCIPR4_LPTIM45SEL_1 |\ + RCC_CCIPR4_LPTIM45SEL_0) +#define LL_RCC_LPTIM45_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, RCC_CCIPR4_LPTIM45SEL_2) +#define LL_RCC_LPTIM45_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, RCC_CCIPR4_LPTIM45SEL_2 |\ + RCC_CCIPR4_LPTIM45SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LPUARTx_CLKSOURCE Peripheral LPUART clock source selection + * @{ + */ +#define LL_RCC_LPUART1_CLKSOURCE_PCLK4 0U +#define LL_RCC_LPUART1_CLKSOURCE_PLL2Q RCC_CCIPR4_LPUART1SEL_0 +#define LL_RCC_LPUART1_CLKSOURCE_PLL3Q RCC_CCIPR4_LPUART1SEL_1 +#define LL_RCC_LPUART1_CLKSOURCE_HSI (RCC_CCIPR4_LPUART1SEL_1 | RCC_CCIPR4_LPUART1SEL_0) +#define LL_RCC_LPUART1_CLKSOURCE_CSI RCC_CCIPR4_LPUART1SEL_2 +#define LL_RCC_LPUART1_CLKSOURCE_LSE (RCC_CCIPR4_LPUART1SEL_2 | RCC_CCIPR4_LPUART1SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LTDC_CLKSOURCE Peripheral LTDC clock source selection + * @{ + */ +#define LL_RCC_LTDC_CLKSOURCE_PLL3R 0U +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PSSI_CLKSOURCE Peripheral PSSI clock source selection + * @{ + */ +#define LL_RCC_PSSI_CLKSOURCE_PLL3R 0U +#define LL_RCC_PSSI_CLKSOURCE_CLKP RCC_CCIPR1_PSSISEL +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SAIx_CLKSOURCE Peripheral SAI clock source selection + * @{ + */ +#define LL_RCC_SAI1_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI1SEL, RCC_CCIPR3_SAI1SEL_Pos, 0U) +#define LL_RCC_SAI1_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI1SEL, RCC_CCIPR3_SAI1SEL_Pos, RCC_CCIPR3_SAI1SEL_0) +#define LL_RCC_SAI1_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI1SEL, RCC_CCIPR3_SAI1SEL_Pos, RCC_CCIPR3_SAI1SEL_1) +#define LL_RCC_SAI1_CLKSOURCE_I2S_CKIN LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI1SEL, RCC_CCIPR3_SAI1SEL_Pos, RCC_CCIPR3_SAI1SEL_0 |\ + RCC_CCIPR3_SAI1SEL_1) +#define LL_RCC_SAI1_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI1SEL, RCC_CCIPR3_SAI1SEL_Pos, RCC_CCIPR3_SAI1SEL_2) + +#define LL_RCC_SAI2_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, 0U) +#define LL_RCC_SAI2_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, RCC_CCIPR3_SAI2SEL_0) +#define LL_RCC_SAI2_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, RCC_CCIPR3_SAI2SEL_1) +#define LL_RCC_SAI2_CLKSOURCE_I2S_CKIN LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, RCC_CCIPR3_SAI2SEL_1 |\ + RCC_CCIPR3_SAI2SEL_0) +#define LL_RCC_SAI2_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, RCC_CCIPR3_SAI2SEL_2) +#define LL_RCC_SAI2_CLKSOURCE_SPDIFRX LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, RCC_CCIPR3_SAI1SEL_2 |\ + RCC_CCIPR3_SAI2SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SDMMC_CLKSOURCE Peripheral SDMMC clock source selection + * @{ + */ +#define LL_RCC_SDMMC_CLKSOURCE_PLL2S 0U +#define LL_RCC_SDMMC_CLKSOURCE_PLL2T RCC_CCIPR1_SDMMC12SEL +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SPDIF_CLKSOURCE Peripheral SPDIF clock source selection + * @{ + */ +#define LL_RCC_SPDIFRX_CLKSOURCE_PLL1Q 0U +#define LL_RCC_SPDIFRX_CLKSOURCE_PLL2R RCC_CCIPR2_SPDIFRXSEL_0 +#define LL_RCC_SPDIFRX_CLKSOURCE_PLL3R RCC_CCIPR2_SPDIFRXSEL_1 +#define LL_RCC_SPDIFRX_CLKSOURCE_HSI (RCC_CCIPR2_SPDIFRXSEL_0 | RCC_CCIPR2_SPDIFRXSEL_1) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SPIx_CLKSOURCE Peripheral SPI clock source selection + * @{ + */ +#define LL_RCC_SPI1_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, 0U) +#define LL_RCC_SPI1_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_0) +#define LL_RCC_SPI1_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_1) +#define LL_RCC_SPI1_CLKSOURCE_I2S_CKIN LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_1 |\ + RCC_CCIPR3_SPI1SEL_0) +#define LL_RCC_SPI1_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_2) + +#define LL_RCC_SPI23_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_SPI23SEL, RCC_CCIPR2_SPI23SEL_Pos, 0U) +#define LL_RCC_SPI23_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_SPI23SEL, RCC_CCIPR2_SPI23SEL_Pos, RCC_CCIPR2_SPI23SEL_0) +#define LL_RCC_SPI23_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_SPI23SEL, RCC_CCIPR2_SPI23SEL_Pos, RCC_CCIPR2_SPI23SEL_1) +#define LL_RCC_SPI23_CLKSOURCE_I2S_CKIN LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_SPI23SEL, RCC_CCIPR2_SPI23SEL_Pos, RCC_CCIPR2_SPI23SEL_1 |\ + RCC_CCIPR2_SPI23SEL_0) +#define LL_RCC_SPI23_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_SPI23SEL, RCC_CCIPR2_SPI23SEL_Pos, RCC_CCIPR2_SPI23SEL_2) + +#define LL_RCC_SPI45_CLKSOURCE_PCLK2 LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, 0U) +#define LL_RCC_SPI45_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, RCC_CCIPR3_SPI45SEL_0) +#define LL_RCC_SPI45_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, RCC_CCIPR3_SPI45SEL_1) +#define LL_RCC_SPI45_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, RCC_CCIPR3_SPI45SEL_1 |\ + RCC_CCIPR3_SPI45SEL_0) +#define LL_RCC_SPI45_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, RCC_CCIPR3_SPI45SEL_2) +#define LL_RCC_SPI45_CLKSOURCE_HSE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, RCC_CCIPR3_SPI45SEL_2 |\ + RCC_CCIPR3_SPI45SEL_0) + +#define LL_RCC_SPI6_CLKSOURCE_PCLK4 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, 0U) +#define LL_RCC_SPI6_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, RCC_CCIPR4_SPI6SEL_0) +#define LL_RCC_SPI6_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, RCC_CCIPR4_SPI6SEL_1) +#define LL_RCC_SPI6_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, RCC_CCIPR4_SPI6SEL_1 |\ + RCC_CCIPR4_SPI6SEL_0) +#define LL_RCC_SPI6_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, RCC_CCIPR4_SPI6SEL_2) +#define LL_RCC_SPI6_CLKSOURCE_HSE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, RCC_CCIPR4_SPI6SEL_2 |\ + RCC_CCIPR4_SPI6SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USARTx_CLKSOURCE Peripheral USART clock source selection + * @{ + */ +#define LL_RCC_USART1_CLKSOURCE_PCLK2 LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, 0U) +#define LL_RCC_USART1_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, RCC_CCIPR3_USART1SEL_0) +#define LL_RCC_USART1_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, RCC_CCIPR3_USART1SEL_1) +#define LL_RCC_USART1_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, RCC_CCIPR3_USART1SEL_1 |\ + RCC_CCIPR3_USART1SEL_0) +#define LL_RCC_USART1_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, RCC_CCIPR3_USART1SEL_2) +#define LL_RCC_USART1_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, RCC_CCIPR3_USART1SEL_2 |\ + RCC_CCIPR3_USART1SEL_0) + +#define LL_RCC_USART234578_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, 0U) +#define LL_RCC_USART234578_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, RCC_CCIPR2_UART234578SEL_0) +#define LL_RCC_USART234578_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, RCC_CCIPR2_UART234578SEL_1) +#define LL_RCC_USART234578_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, RCC_CCIPR2_UART234578SEL_1 |\ + RCC_CCIPR2_UART234578SEL_0) +#define LL_RCC_USART234578_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, RCC_CCIPR2_UART234578SEL_2) +#define LL_RCC_USART234578_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, RCC_CCIPR2_UART234578SEL_2 |\ + RCC_CCIPR2_UART234578SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_OTGFS_CLKSOURCE Peripheral OTGFS kernel clock source selection + * @{ + */ +#define LL_RCC_OTGFS_CLKSOURCE_HSI48 0U +#define LL_RCC_OTGFS_CLKSOURCE_PLL3Q RCC_CCIPR1_OTGFSSEL_0 +#define LL_RCC_OTGFS_CLKSOURCE_HSE RCC_CCIPR1_OTGFSSEL_1 +#define LL_RCC_OTGFS_CLKSOURCE_CLK48 (RCC_CCIPR1_OTGFSSEL_1 | RCC_CCIPR1_OTGFSSEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USBPHYC_CLKSOURCE Peripheral USBPHYC kernel clock source selection + * @{ + */ +#define LL_RCC_USBPHYC_CLKSOURCE_HSE 0U +#define LL_RCC_USBPHYC_CLKSOURCE_HSE_DIV_2 RCC_CCIPR1_USBPHYCSEL_0 +#define LL_RCC_USBPHYC_CLKSOURCE_PLL3Q RCC_CCIPR1_USBPHYCSEL_1 +#define LL_RCC_USBPHYC_CLKSOURCE_DISABLE (RCC_CCIPR1_USBPHYCSEL_1 | RCC_CCIPR1_USBPHYCSEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USBREF_CLKSOURCE Peripheral USBREF clock source selection + * @{ + */ +#define LL_RCC_USBREF_CLKSOURCE_16M (RCC_CCIPR1_USBREFCKSEL_1 | RCC_CCIPR1_USBREFCKSEL_0) +#define LL_RCC_USBREF_CLKSOURCE_19_2M RCC_CCIPR1_USBREFCKSEL_3 +#define LL_RCC_USBREF_CLKSOURCE_20M (RCC_CCIPR1_USBREFCKSEL_3 | RCC_CCIPR1_USBREFCKSEL_0) +#define LL_RCC_USBREF_CLKSOURCE_24M (RCC_CCIPR1_USBREFCKSEL_3 | RCC_CCIPR1_USBREFCKSEL_1) +#define LL_RCC_USBREF_CLKSOURCE_26M (RCC_CCIPR1_USBREFCKSEL_3 |\ + RCC_CCIPR1_USBREFCKSEL_2 | RCC_CCIPR1_USBREFCKSEL_1) +#define LL_RCC_USBREF_CLKSOURCE_32M (RCC_CCIPR1_USBREFCKSEL_3 |\ + RCC_CCIPR1_USBREFCKSEL_1 | RCC_CCIPR1_USBREFCKSEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_XSPI_CLKSOURCE Peripheral XSPI clock source selection + * @{ + */ +#define LL_RCC_XSPI1_CLKSOURCE_HCLK LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI1SEL, RCC_CCIPR1_XSPI1SEL_Pos, 0U) +#define LL_RCC_XSPI1_CLKSOURCE_PLL2S LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI1SEL, RCC_CCIPR1_XSPI1SEL_Pos, RCC_CCIPR1_XSPI1SEL_0) +#define LL_RCC_XSPI1_CLKSOURCE_PLL2T LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI1SEL, RCC_CCIPR1_XSPI1SEL_Pos, RCC_CCIPR1_XSPI1SEL_1) +#define LL_RCC_XSPI1_CLKSOURCE_HCLK_DIV4 LL_RCC_SWP_XSPI1_HCLK_DIV4 /* Recovery: Read-only */ + +#define LL_RCC_XSPI2_CLKSOURCE_HCLK LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI2SEL, RCC_CCIPR1_XSPI2SEL_Pos, 0U) +#define LL_RCC_XSPI2_CLKSOURCE_PLL2S LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI2SEL, RCC_CCIPR1_XSPI2SEL_Pos, RCC_CCIPR1_XSPI2SEL_0) +#define LL_RCC_XSPI2_CLKSOURCE_PLL2T LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI2SEL, RCC_CCIPR1_XSPI2SEL_Pos, RCC_CCIPR1_XSPI2SEL_1) +#define LL_RCC_XSPI2_CLKSOURCE_HCLK_DIV4 LL_RCC_SWP_XSPI2_HCLK_DIV4 /* Recovery: Read-only */ +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_ADC_CLKSOURCE + * @{ + */ +#define LL_RCC_ADC_CLKSOURCE RCC_CCIPR1_ADCSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_ADFx_CLKSOURCE + * @{ + */ +#define LL_RCC_ADF1_CLKSOURCE RCC_CCIPR1_ADF1SEL +/** + * @} + */ + + +/** @addtogroup RCC_LL_EC_CEC_CLKSOURCE + * @{ + */ +#define LL_RCC_CEC_CLKSOURCE RCC_CCIPR2_CECSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_CLKP_CLKSOURCE + * @{ + */ +#define LL_RCC_CLKP_CLKSOURCE RCC_CCIPR1_CKPERSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_ETHxPHY_CLKSOURCE + * @{ + */ +#define LL_RCC_ETH1PHY_CLKSOURCE RCC_CCIPR1_ETH1PHYCKSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_ETHxREF_CLKSOURCE + * @{ + */ +#define LL_RCC_ETH1REF_CLKSOURCE RCC_CCIPR1_ETH1REFCKSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_FDCAN_CLKSOURCE + * @{ + */ +#define LL_RCC_FDCAN_CLKSOURCE RCC_CCIPR2_FDCANSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_FMC_CLKSOURCE + * @{ + */ +#define LL_RCC_FMC_CLKSOURCE RCC_CCIPR1_FMCSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_I2Cx_CLKSOURCE + * @{ + */ +#define LL_RCC_I2C1_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C1_I3C1SEL, RCC_CCIPR2_I2C1_I3C1SEL_Pos, 0U) +#define LL_RCC_I2C23_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_I2C23SEL, RCC_CCIPR2_I2C23SEL_Pos, 0U) +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_I3Cx_CLKSOURCE + * @{ + */ +#define LL_RCC_I3C1_CLKSOURCE RCC_CCIPR2_I2C1_I3C1SEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_LPTIMx_CLKSOURCE + * @{ + */ +#define LL_RCC_LPTIM1_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, 0U) +#define LL_RCC_LPTIM23_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM23SEL, RCC_CCIPR4_LPTIM23SEL_Pos, 0U) +#define LL_RCC_LPTIM45_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_LPTIM45SEL, RCC_CCIPR4_LPTIM45SEL_Pos, 0U) +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_LPUARTx_CLKSOURCE + * @{ + */ +#define LL_RCC_LPUART1_CLKSOURCE RCC_CCIPR4_LPUART1SEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_OTGFS_CLKSOURCE + * @{ + */ +#define LL_RCC_OTGFS_CLKSOURCE RCC_CCIPR1_OTGFSSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_PSSI_CLKSOURCE + * @{ + */ +#define LL_RCC_PSSI_CLKSOURCE RCC_CCIPR1_PSSISEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_SAIx_CLKSOURCE + * @{ + */ +#define LL_RCC_SAI1_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI1SEL, RCC_CCIPR3_SAI1SEL_Pos, 0U) +#define LL_RCC_SAI2_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SAI2SEL, RCC_CCIPR3_SAI2SEL_Pos, 0U) +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_SDMMC_CLKSOURCE + * @{ + */ +#define LL_RCC_SDMMC_CLKSOURCE RCC_CCIPR1_SDMMC12SEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_SPDIFRX_CLKSOURCE + * @{ + */ +#define LL_RCC_SPDIFRX_CLKSOURCE RCC_CCIPR2_SPDIFRXSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_SPIx_CLKSOURCE + * @{ + */ +#define LL_RCC_SPI1_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, 0U) +#define LL_RCC_SPI23_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_SPI23SEL, RCC_CCIPR2_SPI23SEL_Pos, 0U) +#define LL_RCC_SPI45_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI45SEL, RCC_CCIPR3_SPI45SEL_Pos, 0U) +#define LL_RCC_SPI6_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SPI6SEL, RCC_CCIPR4_SPI6SEL_Pos, 0U) +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_USARTx_CLKSOURCE + * @{ + */ +#define LL_RCC_USART1_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_USART1SEL, RCC_CCIPR3_USART1SEL_Pos, 0U) +#define LL_RCC_USART234578_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART234578SEL, RCC_CCIPR2_UART234578SEL_Pos, 0U) +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_USBPHYC_CLKSOURCE + * @{ + */ +#define LL_RCC_USBPHYC_CLKSOURCE RCC_CCIPR1_USBPHYCSEL +/** + * @} + */ + +/** @addtogroup RCC_LL_EC_USBREF_CLKSOURCE + * @{ + */ +#define LL_RCC_USBREF_CLKSOURCE RCC_CCIPR1_USBREFCKSEL +/** + * @} + */ + + +/** @addtogroup RCC_LL_EC_XSPIx_CLKSOURCE + * @{ + */ +#define LL_RCC_XSPI1_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI1SEL, RCC_CCIPR1_XSPI1SEL_Pos, 0U) +#define LL_RCC_XSPI2_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_XSPI2SEL, RCC_CCIPR1_XSPI2SEL_Pos, 0U) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_RTC_CLKSOURCE RTC clock source selection + * @{ + */ +#define LL_RCC_RTC_CLKSOURCE_NONE 0U +#define LL_RCC_RTC_CLKSOURCE_LSE RCC_BDCR_RTCSEL_0 +#define LL_RCC_RTC_CLKSOURCE_LSI RCC_BDCR_RTCSEL_1 +#define LL_RCC_RTC_CLKSOURCE_HSE (RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_TIM_CLKPRESCALER Timers clocks prescalers selection + * @{ + */ +#define LL_RCC_TIM_PRESCALER_TWICE 0U +#define LL_RCC_TIM_PRESCALER_FOUR_TIMES RCC_CFGR_TIMPRE +/* Legacy Aliases */ +#define LL_RCC_TIM_PRESCALER_DISABLE LL_RCC_TIM_PRESCALER_TWICE +#define LL_RCC_TIM_PRESCALER_ENABLE LL_RCC_TIM_PRESCALER_FOUR_TIMES +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLLSOURCE All PLLs entry clock source + * @{ + */ +#define LL_RCC_PLLSOURCE_HSI 0U +#define LL_RCC_PLLSOURCE_CSI RCC_PLLCKSELR_PLLSRC_0 +#define LL_RCC_PLLSOURCE_HSE RCC_PLLCKSELR_PLLSRC_1 +#define LL_RCC_PLLSOURCE_NONE (RCC_PLLCKSELR_PLLSRC_1 | RCC_PLLCKSELR_PLLSRC_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLLINPUTRANGE All PLLs input range + * @{ + */ +#define LL_RCC_PLLINPUTRANGE_1_2 0U +#define LL_RCC_PLLINPUTRANGE_2_4 RCC_PLLCFGR_PLL1RGE_0 +#define LL_RCC_PLLINPUTRANGE_4_8 RCC_PLLCFGR_PLL1RGE_1 +#define LL_RCC_PLLINPUTRANGE_8_16 (RCC_PLLCFGR_PLL1RGE_1 | RCC_PLLCFGR_PLL1RGE_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLLVCORANGE All PLLs VCO range + * @{ + */ +#define LL_RCC_PLLVCORANGE_WIDE 0U /*!< VCO output range: 400 to 1600 MHz */ +#define LL_RCC_PLLVCORANGE_MEDIUM RCC_PLLCFGR_PLL1VCOSEL /*!< VCO output range: 150 to 420 MHz */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL_SPREAD_SEL PLL Spread Spectrum Selection + * @{ + */ +#define LL_RCC_PLL_SPREAD_CENTER 0U /*!< PLL center spread spectrum selection */ +#define LL_RCC_PLL_SPREAD_DOWN RCC_PLL1SSCGR_SPREADSEL /*!< PLL down spread spectrum selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL_DITHERING_TPDFN PLL Dithering TPDF Noise Control + * @{ + */ +#define LL_RCC_PLL_DITHERING_TPDFN_ENABLE 0U /*!< PLL Dithering TPDF Noise injection enabled */ +#define LL_RCC_PLL_DITHERING_TPDFN_DISABLE RCC_PLL1SSCGR_TPDFNDIS /*!< PLL Dithering TPDF Noise injection disabled */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL_DITHERING_RPDFN PLL Dithering RPDF Noise Control + * @{ + */ +#define LL_RCC_PLL_DITHERING_RPDFN_ENABLE 0U /*!< PLL Dithering RPDF Noise injection enabled */ +#define LL_RCC_PLL_DITHERING_RPDFN_DISABLE RCC_PLL1SSCGR_RPDFNDIS /*!< PLL Dithering RPDF Noise injection disabled */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @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 SYSCLK frequency + * @param __SYSINPUTCLKFREQ__ Frequency of the input of sys_ck (based on HSE/CSI/HSI/PLL1P) + * @param __SYSPRESCALER__ 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 SYSCLK clock frequency (in Hz) + */ +#define LL_RCC_CALC_SYSCLK_FREQ(__SYSINPUTCLKFREQ__, __SYSPRESCALER__) ((__SYSINPUTCLKFREQ__) >> ((LL_RCC_PrescTable[((__SYSPRESCALER__) &\ + RCC_CDCFGR_CPRE) >> RCC_CDCFGR_CPRE_Pos]) & 0x1FU)) + +/** + * @brief Helper macro to calculate the HCLK frequency + * @param __SYSCLKFREQ__ SYSCLK frequency. + * @param __HPRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_AHB_DIV_1 + * @arg @ref LL_RCC_AHB_DIV_2 + * @arg @ref LL_RCC_AHB_DIV_4 + * @arg @ref LL_RCC_AHB_DIV_8 + * @arg @ref LL_RCC_AHB_DIV_16 + * @arg @ref LL_RCC_AHB_DIV_64 + * @arg @ref LL_RCC_AHB_DIV_128 + * @arg @ref LL_RCC_AHB_DIV_256 + * @arg @ref LL_RCC_AHB_DIV_512 + * @retval HCLK clock frequency (in Hz) + */ +#define LL_RCC_CALC_HCLK_FREQ(__SYSCLKFREQ__, __HPRESCALER__) ((__SYSCLKFREQ__) >> ((LL_RCC_PrescTable[((__HPRESCALER__) &\ + RCC_BMCFGR_BMPRE) >> RCC_BMCFGR_BMPRE_Pos]) & 0x1FU)) + +/** + * @brief Helper macro to calculate the PCLK1 frequency (ABP1) + * @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__) >> ((LL_RCC_PrescTable[((__APB1PRESCALER__) &\ + RCC_APBCFGR_PPRE1) >> RCC_APBCFGR_PPRE1_Pos]) & 0x1FU)) + +/** + * @brief Helper macro to calculate the PCLK2 frequency (ABP2) + * @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__) >> ((LL_RCC_PrescTable[((__APB2PRESCALER__) &\ + RCC_APBCFGR_PPRE2) >> RCC_APBCFGR_PPRE2_Pos]) & 0x1FU)) + +/** + * @brief Helper macro to calculate the PCLK4 frequency (ABP4) + * @param __HCLKFREQ__ HCLK frequency + * @param __APB4PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_APB4_DIV_1 + * @arg @ref LL_RCC_APB4_DIV_2 + * @arg @ref LL_RCC_APB4_DIV_4 + * @arg @ref LL_RCC_APB4_DIV_8 + * @arg @ref LL_RCC_APB4_DIV_16 + * @retval PCLK1 clock frequency (in Hz) + */ +#define LL_RCC_CALC_PCLK4_FREQ(__HCLKFREQ__, __APB4PRESCALER__) ((__HCLKFREQ__) >> ((LL_RCC_PrescTable[((__APB4PRESCALER__) &\ + RCC_APBCFGR_PPRE4) >> RCC_APBCFGR_PPRE4_Pos]) & 0x1FU)) + +/** + * @brief Helper macro to calculate the PCLK5 frequency (APB5) + * @param __HCLKFREQ__ HCLK frequency + * @param __APB5PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_APB5_DIV_1 + * @arg @ref LL_RCC_APB5_DIV_2 + * @arg @ref LL_RCC_APB5_DIV_4 + * @arg @ref LL_RCC_APB5_DIV_8 + * @arg @ref LL_RCC_APB5_DIV_16 + * @retval PCLK1 clock frequency (in Hz) + */ +#define LL_RCC_CALC_PCLK5_FREQ(__HCLKFREQ__, __APB5PRESCALER__) ((__HCLKFREQ__) >> ((LL_RCC_PrescTable[((__APB5PRESCALER__) &\ + RCC_APBCFGR_PPRE5) >> RCC_APBCFGR_PPRE5_Pos]) & 0x1FU)) + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_EC_PERIPH_FREQUENCY Peripheral clock frequency + * @{ + */ +#define LL_RCC_PERIPH_FREQUENCY_NO 0U /*!< 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 */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Functions RCC Exported Functions + * @{ + */ + +/** @defgroup RCC_LL_EF_HSE HSE + * @{ + */ + +/** + * @brief Enable the Clock Security System. + * @note Once HSE Clock Security System is enabled it cannot be changed anymore unless + * a reset occurs or system enter in standby mode. + * @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 Select the Analog HSE external clock type in Bypass mode + * @rmtoll CR HSEEXT LL_RCC_HSE_SelectAnalogClock + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_SelectAnalogClock(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT); +} + +/** + * @brief Select the Digital HSE external clock type in Bypass mode + * @rmtoll CR HSEEXT LL_RCC_HSE_SelectDigitalClock + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_SelectDigitalClock(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSEEXT); +} + +/** + * @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); +} + +/** + * @} + */ + +/** @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 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 Enable HSI oscillator in Stop mode + * @rmtoll CR HSIKERON LL_RCC_HSI_EnableStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_EnableStopMode(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSIKERON); +} + +/** + * @brief Disable HSI oscillator in Stop mode + * @rmtoll CR HSIKERON LL_RCC_HSI_DisableStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_DisableStopMode(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSIKERON); +} + +/** + * @brief Check if HSI oscillator in Stop mode has been enabled or not + * @rmtoll CR HSIKERON LL_RCC_HSI_IsEnabledStopMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_IsEnabledStopMode(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_HSIKERON) == (RCC_CR_HSIKERON)) ? 1UL : 0UL); +} + +/** + * @brief Enable XSPI clock protection + * @rmtoll CKPROTR XSPICKP LL_RCC_EnableXSPIClockProtection + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableXSPIClockProtection(void) +{ + SET_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPICKP); +} + +/** + * @brief Disable XSPI clock protection + * @rmtoll CKPROTR XSPICKP LL_RCC_DisableXSPIClockProtection + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableXSPIClockProtection(void) +{ + CLEAR_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPICKP); +} + +/** + * @brief Check if XSPI clock protection has been enabled or not + * @rmtoll CKPROTR XSPICKP LL_RCC_IsEnabledXSPIClockProtection + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledXSPIClockProtection(void) +{ + return ((READ_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPICKP) == (RCC_CKPROTR_XSPICKP)) ? 1UL : 0UL); +} + +/** + * @brief Enable FMC clock protection + * @rmtoll CKPROTR FMCCKP LL_RCC_EnableFMCClockProtection + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableFMCClockProtection(void) +{ + SET_BIT(RCC->CKPROTR, RCC_CKPROTR_FMCCKP); +} + +/** + * @brief Disable FMC clock protection + * @rmtoll CKPROTR FMCCKP LL_RCC_DisableFMCClockProtection + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableFMCClockProtection(void) +{ + CLEAR_BIT(RCC->CKPROTR, RCC_CKPROTR_FMCCKP); +} + +/** + * @brief Check if FMC clock protection has been enabled or not + * @rmtoll CKPROTR FMCCKP LL_RCC_IsEnabledFMCClockProtection + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledFMCClockProtection(void) +{ + return ((READ_BIT(RCC->CKPROTR, RCC_CKPROTR_FMCCKP) == (RCC_CKPROTR_FMCCKP)) ? 1UL : 0UL); +} + +/** + * @brief Get XSPI2 kernel clock switch position + * @rmtoll CKPROTR XSPI2SWP LL_RCC_GetXSPI2SwitchPosition + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SWP_XSPI2_NEUTRAL + @arg @ref LL_RCC_SWP_XSPI2_HCLK5 + @arg @ref LL_RCC_SWP_XSPI2_PLL2S + @arg @ref LL_RCC_SWP_XSPI2_PLL2T + @arg @ref LL_RCC_SWP_XSPI2_HCLK_DIV4 + */ +__STATIC_INLINE uint32_t LL_RCC_GetXSPI2SwitchPosition(void) +{ + return (READ_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPI2SWP)); +} + +/** + * @brief Get XSPI1 kernel clock switch position + * @rmtoll CKPROTR XSPI1SWP LL_RCC_GetXSPI1SwitchPosition + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SWP_XSPI1_NEUTRAL + @arg @ref LL_RCC_SWP_XSPI1_HCLK5 + @arg @ref LL_RCC_SWP_XSPI1_PLL2S + @arg @ref LL_RCC_SWP_XSPI1_PLL2T + @arg @ref LL_RCC_SWP_XSPI1_HCLK_DIV4 + */ +__STATIC_INLINE uint32_t LL_RCC_GetXSPI1SwitchPosition(void) +{ + return (READ_BIT(RCC->CKPROTR, RCC_CKPROTR_XSPI1SWP)); +} + +/** + * @brief Get FMC kernel clock switch position + * @rmtoll CKPROTR FMCSWP LL_RCC_GetFMCSwitchPosition + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SWP_FMC_NEUTRAL + @arg @ref LL_RCC_SWP_FMC_HCLK5 + @arg @ref LL_RCC_SWP_FMC_PLL1Q + @arg @ref LL_RCC_SWP_FMC_PLL2R + @arg @ref LL_RCC_SWP_FMC_HSI + @arg @ref LL_RCC_SWP_FMC_HCLK_DIV4 + */ +__STATIC_INLINE uint32_t LL_RCC_GetFMCSwitchPosition(void) +{ + return (READ_BIT(RCC->CKPROTR, RCC_CKPROTR_FMCSWP)); +} + +/** + * @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 Parameter can be a value between 0 and 127 + * @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 HSICFGR HSITRIM LL_RCC_HSI_GetCalibTrimming + * @retval A value between 0 and 127 + */ +__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 + * @rmtoll CR CSIKERON LL_RCC_CSI_EnableStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_EnableStopMode(void) +{ + SET_BIT(RCC->CR, RCC_CR_CSIKERON); +} + +/** + * @brief Disable CSI oscillator in Stop mode + * @rmtoll CR CSIKERON LL_RCC_CSI_DisableStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_DisableStopMode(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_CSIKERON); +} + +/** + * @brief Check if CSI oscillator in Stop mode has been enabled or not + * @rmtoll CR CSIKERON LL_RCC_CSI_IsEnabledStopMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_CSI_IsEnabledStopMode(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 0 and 31 + * @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 31 + */ +__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 oscillator + * @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 oscillator + * @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 clock is 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 + * @note When HSI48TRIM is written, HSI48CAL is updated with the sum of + * HSI48TRIM and the factory trim 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 the Clock Security System on LSE. + * @note Once LSE Clock Security System is enabled it cannot be changed anymore unless + * a clock failure is detected. + * @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 the Clock Security System on LSE. + * @note Once LSE Clock Security System is enabled it cannot be changed anymore unless + * a clock failure is detected. + * @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 LSE failure is detected by Clock Security System + * @rmtoll BDCR LSECSSD LL_RCC_LSE_IsFailureDetected + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_LSE_IsFailureDetected(void) +{ + return ((READ_BIT(RCC->BDCR, RCC_BDCR_LSECSSD) == RCC_BDCR_LSECSSD) ? 1UL : 0UL); +} + +/** + * @brief Re-arm the Clock Security System on LSE. + * @note Once a clock failure is detected, the LSE Clock Security System can be re-armed providing that + * LSECSSON is disabled. + * @rmtoll BDCR LSECSSRA LL_RCC_LSE_ReArmCSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_ReArmCSS(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSRA); +} + +/** + * @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 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 Enable Low-speed external DIGITAL clock type in Bypass mode (not to be used if RTC is active). + * @note The external clock must be enabled with the LSEON bit, to be used by the device. + * The LSEEXT bit can be written only if the LSE oscillator is disabled. + * @rmtoll BDCR LSEEXT LL_RCC_LSE_SelectDigitalClock + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_SelectDigitalClock(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEEXT); +} + +/** + * @brief Enable Low-speed external ANALOG clock type in Bypass mode (default after Backup domain reset). + * @note The external clock must be enabled with the LSEON bit, to be used by the device. + * The LSEEXT bit can be written only if the LSE oscillator is disabled. + * @rmtoll BDCR LSEEXT LL_RCC_LSE_SelectAnalogClock + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_SelectAnalogClock(void) +{ + CLEAR_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 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); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_LSI LSI + * @{ + */ + +/** + * @brief Enable LSI Oscillator + * @rmtoll CSR LSION LL_RCC_LSI_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSI_Enable(void) +{ + SET_BIT(RCC->CSR, RCC_CSR_LSION); +} + +/** + * @brief Disable LSI Oscillator + * @rmtoll CSR LSION LL_RCC_LSI_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSI_Disable(void) +{ + CLEAR_BIT(RCC->CSR, RCC_CSR_LSION); +} + +/** + * @brief Check if LSI is Ready + * @rmtoll CSR 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->CSR, RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_System System + * @{ + */ + +/** + * @brief Configure the system clock source + * @rmtoll CFGR 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->CFGR, RCC_CFGR_SW, Source); +} + +/** + * @brief Get the system clock source + * @rmtoll CFGR 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->CFGR, RCC_CFGR_SWS)); +} + +/** + * @brief Configure the system wakeup clock source + * @rmtoll CFGR STOPWUCK LL_RCC_SetSysWakeUpClkSource + * @param Source 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_SetSysWakeUpClkSource(uint32_t Source) +{ + MODIFY_REG(RCC->CFGR, RCC_CFGR_STOPWUCK, Source); +} + +/** + * @brief Get the system wakeup clock source + * @rmtoll CFGR STOPWUCK LL_RCC_GetSysWakeUpClkSource + * @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_GetSysWakeUpClkSource(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_STOPWUCK)); +} + +/** + * @brief Configure the kernel wakeup clock source + * @rmtoll CFGR 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->CFGR, RCC_CFGR_STOPKERWUCK, Source); +} + +/** + * @brief Get the kernel wakeup clock source + * @rmtoll CFGR 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->CFGR, RCC_CFGR_STOPKERWUCK)); +} + +/** + * @brief Set System prescaler + * @rmtoll CDCFGR CPRE LL_RCC_SetSysPrescaler + * @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_SetSysPrescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CDCFGR, RCC_CDCFGR_CPRE, Prescaler); +} + +/** + * @brief Set AHB prescaler + * @rmtoll BMCFGR BMPRE LL_RCC_SetAHBPrescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_AHB_DIV_1 + * @arg @ref LL_RCC_AHB_DIV_2 + * @arg @ref LL_RCC_AHB_DIV_4 + * @arg @ref LL_RCC_AHB_DIV_8 + * @arg @ref LL_RCC_AHB_DIV_16 + * @arg @ref LL_RCC_AHB_DIV_64 + * @arg @ref LL_RCC_AHB_DIV_128 + * @arg @ref LL_RCC_AHB_DIV_256 + * @arg @ref LL_RCC_AHB_DIV_512 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAHBPrescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->BMCFGR, RCC_BMCFGR_BMPRE, Prescaler); +} + +/** + * @brief Set APB1 prescaler + * @rmtoll APBCFGR 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->APBCFGR, RCC_APBCFGR_PPRE1, Prescaler); +} + +/** + * @brief Set APB2 prescaler + * @rmtoll APBCFGR 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->APBCFGR, RCC_APBCFGR_PPRE2, Prescaler); +} + +/** + * @brief Set APB4 prescaler + * @rmtoll APBCFGR PPRE4 LL_RCC_SetAPB4Prescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_APB4_DIV_1 + * @arg @ref LL_RCC_APB4_DIV_2 + * @arg @ref LL_RCC_APB4_DIV_4 + * @arg @ref LL_RCC_APB4_DIV_8 + * @arg @ref LL_RCC_APB4_DIV_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAPB4Prescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE4, Prescaler); +} + +/** + * @brief Set APB5 prescaler + * @rmtoll APBCFGR PPRE5 LL_RCC_SetAPB5Prescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_APB5_DIV_1 + * @arg @ref LL_RCC_APB5_DIV_2 + * @arg @ref LL_RCC_APB5_DIV_4 + * @arg @ref LL_RCC_APB5_DIV_8 + * @arg @ref LL_RCC_APB5_DIV_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAPB5Prescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE5, Prescaler); +} + +/** + * @brief Get System prescaler + * @rmtoll CDCFGR CPRE LL_RCC_GetSysPrescaler + * @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_GetSysPrescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CDCFGR, RCC_CDCFGR_CPRE)); +} + +/** + * @brief Get AHB prescaler + * @rmtoll BMCFGR BMPRE LL_RCC_GetAHBPrescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_AHB_DIV_1 + * @arg @ref LL_RCC_AHB_DIV_2 + * @arg @ref LL_RCC_AHB_DIV_4 + * @arg @ref LL_RCC_AHB_DIV_8 + * @arg @ref LL_RCC_AHB_DIV_16 + * @arg @ref LL_RCC_AHB_DIV_64 + * @arg @ref LL_RCC_AHB_DIV_128 + * @arg @ref LL_RCC_AHB_DIV_256 + * @arg @ref LL_RCC_AHB_DIV_512 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAHBPrescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->BMCFGR, RCC_BMCFGR_BMPRE)); +} + +/** + * @brief Get APB1 prescaler + * @rmtoll APBCFGR 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->APBCFGR, RCC_APBCFGR_PPRE1)); +} + +/** + * @brief Get APB2 prescaler + * @rmtoll APBCFGR 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->APBCFGR, RCC_APBCFGR_PPRE2)); +} + +/** + * @brief Get APB4 prescaler + * @rmtoll APBCFGR PPRE4 LL_RCC_GetAPB4Prescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_APB4_DIV_1 + * @arg @ref LL_RCC_APB4_DIV_2 + * @arg @ref LL_RCC_APB4_DIV_4 + * @arg @ref LL_RCC_APB4_DIV_8 + * @arg @ref LL_RCC_APB4_DIV_16 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAPB4Prescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE4)); +} + +/** + * @brief Get APB5 prescaler + * @rmtoll APBCFGR PPRE5 LL_RCC_GetAPB5Prescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_APB5_DIV_1 + * @arg @ref LL_RCC_APB5_DIV_2 + * @arg @ref LL_RCC_APB5_DIV_4 + * @arg @ref LL_RCC_APB5_DIV_8 + * @arg @ref LL_RCC_APB5_DIV_16 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAPB5Prescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE5)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_MCO MCO + * @{ + */ + +/** + * @brief Configure MCOx + * @rmtoll CFGR MCO1SEL LL_RCC_ConfigMCO\n + * CFGR MCO1PRE LL_RCC_ConfigMCO\n + * CFGR MCO2SEL LL_RCC_ConfigMCO\n + * CFGR 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->CFGR, (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 + * @param ClkSource 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_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_I2C23_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_CSI + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK1 + * @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_LPTIM23_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM45_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_I2S_CKIN + * @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_I2S_CKIN + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SAI2_CLKSOURCE_SPDIFRX + * @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_I2S_CKIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_I2S_CKIN + * @arg @ref LL_RCC_SPI23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_CSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSE + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK4 + * @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_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_USART234578_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_LSE + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2T + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2T + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetClockSource(uint32_t ClkSource) +{ + volatile 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 ADCx Kernel clock source + * @rmtoll CCIPR1 ADCSEL LL_RCC_SetADCClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_ADC_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_ADC_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_ADC_CLKSOURCE_CLKP + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetADCClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ADCSEL, ClkSource); +} + +/** + * @brief Configure ADFx Kernel clock source + * @rmtoll CCIPR1 ADF1SEL LL_RCC_SetADFClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_ADF1_CLKSOURCE_HCLK + * @arg @ref LL_RCC_ADF1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_ADF1_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_ADF1_CLKSOURCE_I2S_CKIN + * @arg @ref LL_RCC_ADF1_CLKSOURCE_CSI + * @arg @ref LL_RCC_ADF1_CLKSOURCE_HSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetADFClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ADF1SEL, ClkSource); +} + +/** + * @brief Configure CECx clock source + * @rmtoll CCIPR2 CECSEL LL_RCC_SetCECClockSource + * @param ClkSource 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_DIV_122 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetCECClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_CECSEL, ClkSource); +} + +/** + * @brief Configure CLKP Kernel clock source + * @rmtoll CCIPR1 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 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetCLKPClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_CKPERSEL, ClkSource); +} + +/** + * @brief Configure ETHx PHY clock source + * @rmtoll CCIPR1 ETH1PHYCKSEL LL_RCC_SetETHPHYClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_ETH1PHY_CLKSOURCE_HSE + * @arg @ref LL_RCC_ETH1PHY_CLKSOURCE_PLL3S + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetETHPHYClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ETH1PHYCKSEL, ClkSource); +} + +/** + * @brief Configure ETHx REF clock source + * @rmtoll CCIPR1 ETH1REFCKSEL LL_RCC_SetETHREFClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE_RMII + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE_HSE + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE_FB + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetETHREFClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_ETH1REFCKSEL, ClkSource); +} + +/** + * @brief Configure FDCANx Kernel clock source + * @rmtoll CCIPR2 FDCANSEL LL_RCC_SetFDCANClockSource + * @param ClkSource 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 ClkSource) +{ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_FDCANSEL, ClkSource); +} + +/** + * @brief Configure FMCx Kernel clock source + * @rmtoll CCIPR1 FMCSEL LL_RCC_SetFMCClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_FMC_CLKSOURCE_HCLK + * @arg @ref LL_RCC_FMC_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_FMC_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_FMC_CLKSOURCE_HSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetFMCClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_FMCSEL, ClkSource); +} + +/** + * @brief Configure I2Cx clock source + * @rmtoll CCIPR2 I2C1_I3C1SEL LL_RCC_SetI2CClockSource + * @rmtoll CCIPR2 I2C23SEL LL_RCC_SetI2CClockSource + * @param ClkSource 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_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_I2C23_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_CSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetI2CClockSource(uint32_t ClkSource) +{ + LL_RCC_SetClockSource(ClkSource); +} + +/** + * @brief Configure I3Cx clock source + * @rmtoll CCIPR2 I2C1_I3C1SEL LL_RCC_SetI3CClockSource + * @param ClkSource 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_HSI + * @arg @ref LL_RCC_I3C1_CLKSOURCE_CSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetI3CClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_I2C1_I3C1SEL, ClkSource); +} + +/** + * @brief Configure LPTIMx clock source + * @rmtoll CCIPR2 LPTIM1SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR4 LPTIM23SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR4 LPTIM45SEL LL_RCC_SetLPTIMClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK1 + * @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_LPTIM23_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_CLKP + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetLPTIMClockSource(uint32_t ClkSource) +{ + LL_RCC_SetClockSource(ClkSource); +} + +/** + * @brief Configure LPUARTx clock source + * @rmtoll CCIPR4 LPUART1SEL LL_RCC_SetLPUARTClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PCLK4 + * @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 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetLPUARTClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_LPUART1SEL, ClkSource); +} + +/** + * @brief Configure OTGFSx clock source + * @rmtoll CCIPR1 OTGFSSEL LL_RCC_SetOTGFSClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_HSI48 + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_CLK48 + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_HSE + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_PLL3Q + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetOTGFSClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_OTGFSSEL, ClkSource); +} + +/** + * @brief Configure XSPIx Kernel clock source + * @rmtoll CCIPR1 XSPI1SEL LL_RCC_SetXSPIClockSource\n + * CCIPR1 XSPI2SEL LL_RCC_SetXSPIClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2T + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2T + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetXSPIClockSource(uint32_t ClkSource) +{ + LL_RCC_SetClockSource(ClkSource); +} + +/** + * @brief Configure PSSI clock source + * @rmtoll CCIPR1 PSSISEL LL_RCC_SetPSSIClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_PSSI_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_PSSI_CLKSOURCE_CLKP + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetPSSIClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_PSSISEL, ClkSource); +} + +/** + * @brief Configure SAIx clock source + * @rmtoll CCIPR3 SAI1SEL LL_RCC_SetSAIClockSource\n + * CCIPR3 SAI2SEL LL_RCC_SetSAIClockSource + * @param ClkSource 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_I2S_CKIN + * @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_I2S_CKIN + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SAI2_CLKSOURCE_SPDIFRX + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSAIClockSource(uint32_t ClkSource) +{ + LL_RCC_SetClockSource(ClkSource); +} + +/** + * @brief Configure SDMMCx clock source + * @rmtoll CCIPR1 SDMMCSEL LL_RCC_SetSDMMCClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SDMMC_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_SDMMC_CLKSOURCE_PLL2T + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSDMMCClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_SDMMC12SEL, ClkSource); +} + +/** + * @brief Configure SPDIFRX Kernel clock source + * @rmtoll CCIPR2 SPDIFRXSEL LL_RCC_SetSPDIFRXClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_HSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSPDIFRXClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_SPDIFRXSEL, ClkSource); +} + +/** + * @brief Configure SPIx Kernel clock source + * @rmtoll CCIPR3 SPI1SEL LL_RCC_SetSPIClockSource\n + * CCIPR2 SPI23SEL LL_RCC_SetSPIClockSource\n + * CCIPR3 SPI45SEL LL_RCC_SetSPIClockSource\n + * CCIPR4 SPI6SEL LL_RCC_SetSPIClockSource + * @param ClkSource 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_I2S_CKIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_I2S_CKIN + * @arg @ref LL_RCC_SPI23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_CSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSE + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK4 + * @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 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSPIClockSource(uint32_t ClkSource) +{ + LL_RCC_SetClockSource(ClkSource); +} + +/** + * @brief Configure USARTx clock source + * @rmtoll CCIPR3 USART1SEL LL_RCC_SetUSARTClockSource\n + * CCIPR2 UART234578SEL LL_RCC_SetUSARTClockSource + * @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_USART234578_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_LSE + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetUSARTClockSource(uint32_t ClkSource) +{ + LL_RCC_SetClockSource(ClkSource); +} + +/** + * @brief Configure USBPHYC clock source + * @rmtoll CCIPR1 USBPHYCSEL LL_RCC_SetUSBPHYCClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_DISABLE + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_HSE + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_HSE_DIV_2 + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_PLL3Q + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetUSBPHYCClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USBPHYCSEL, ClkSource); +} + +/** + * @brief Configure USBREF clock source + * @rmtoll CCIPR1 USBREFCKSEL LL_RCC_SetUSBREFClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USBREF_CLKSOURCE_16M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_19_2M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_20M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_24M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_26M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_32M + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetUSBREFClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USBREFCKSEL, 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 + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE + * @arg @ref LL_RCC_I2C23_CLKSOURCE + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE + * @arg @ref LL_RCC_SAI1_CLKSOURCE + * @arg @ref LL_RCC_SAI2_CLKSOURCE + * @arg @ref LL_RCC_SPI1_CLKSOURCE + * @arg @ref LL_RCC_SPI23_CLKSOURCE + * @arg @ref LL_RCC_SPI45_CLKSOURCE + * @arg @ref LL_RCC_SPI6_CLKSOURCE + * @arg @ref LL_RCC_USART1_CLKSOURCE + * @arg @ref LL_RCC_USART234578_CLKSOURCE + * @arg @ref LL_RCC_XSPI1_CLKSOURCE + * @arg @ref LL_RCC_XSPI2_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_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_I2C23_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_CSI + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK1 + * @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_LPTIM23_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM45_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_I2S_CKIN + * @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_I2S_CKIN + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SAI2_CLKSOURCE_SPDIFRX + * @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_I2S_CKIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_I2S_CKIN + * @arg @ref LL_RCC_SPI23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_CSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSE + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK4 + * @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_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_USART234578_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_LSE + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2T + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2T + * @retval None + */ +__STATIC_INLINE uint32_t LL_RCC_GetClockSource(uint32_t Periph) +{ + const volatile 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 ADC Kernel clock source + * @rmtoll CCIPR1 ADCSEL LL_RCC_GetADCClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_ADC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_ADC_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_ADC_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_ADC_CLKSOURCE_CLKP + */ +__STATIC_INLINE uint32_t LL_RCC_GetADCClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ADCSEL)); +} + +/** + * @brief Get ADF clock source + * @rmtoll CCIPR1 ADF1SEL LL_RCC_GetADFClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_ADF1_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_ADF1_CLKSOURCE_HCLK + * @arg @ref LL_RCC_ADF1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_ADF1_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_ADF1_CLKSOURCE_I2S_CKIN + * @arg @ref LL_RCC_ADF1_CLKSOURCE_CSI + * @arg @ref LL_RCC_ADF1_CLKSOURCE_HSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetADFClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ADF1SEL)); +} + +/** + * @brief Get CEC clock source + * @rmtoll CCIPR2 CECSEL LL_RCC_GetCECClockSource + * @param Periph 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_DIV_122 + */ +__STATIC_INLINE uint32_t LL_RCC_GetCECClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_CECSEL)); +} + +/** + * @brief Get CLKP Kernel clock source + * @rmtoll CCIPR1 CKPERSEL LL_RCC_GetCLKPClockSource + * @param Periph 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 + */ +__STATIC_INLINE uint32_t LL_RCC_GetCLKPClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_CKPERSEL)); +} + +/** + * @brief Get ETH PHY clock source + * @rmtoll CCIPR1 ETH1PHYCKSEL LL_RCC_GetETHPHYClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_ETH1PHY_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_ETH1PHY_CLKSOURCE_HSE + * @arg @ref LL_RCC_ETH1PHY_CLKSOURCE_PLL3S + */ +__STATIC_INLINE uint32_t LL_RCC_GetETHPHYClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ETH1PHYCKSEL)); +} + +/** + * @brief Get ETH REF clock source + * @rmtoll CCIPR1 ETH1REFCKSEL LL_RCC_GetETHREFClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE_RMII + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE_HSE + * @arg @ref LL_RCC_ETH1REF_CLKSOURCE_FB + */ +__STATIC_INLINE uint32_t LL_RCC_GetETHREFClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_ETH1REFCKSEL)); +} + +/** + * @brief Get FDCAN Kernel clock source + * @rmtoll CCIPR2 FDCANSEL LL_RCC_GetFDCANClockSource + * @param Periph 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 Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_FDCANSEL)); +} + +/** + * @brief Get FMC Kernel clock source + * @rmtoll CCIPR1 FMCSEL LL_RCC_GetFMCClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_FMC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_FMC_CLKSOURCE_HCLK + * @arg @ref LL_RCC_FMC_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_FMC_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_FMC_CLKSOURCE_HSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetFMCClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_FMCSEL)); +} + +/** + * @brief Get I2Cx clock source + * @rmtoll CCIPR2 I2C1_I3C1SEL LL_RCC_GetI2CClockSource + * @rmtoll CCIPR2 I2C23SEL LL_RCC_GetI2CClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE + * @arg @ref LL_RCC_I2C23_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_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_I2C23_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C23_CLKSOURCE_CSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetI2CClockSource(uint32_t Periph) +{ + return LL_RCC_GetClockSource(Periph); +} + +/** + * @brief Get I3Cx clock source + * @rmtoll CCIPR2 I2C1_I3C1SEL LL_RCC_GetI3CClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_I3C1_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_HSI + * @arg @ref LL_RCC_I3C1_CLKSOURCE_CSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetI3CClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_I2C1_I3C1SEL)); +} + +/** + * @brief Get LPTIM clock source + * @rmtoll CCIPR2 LPTIM1SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR4 LPTIM23SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR4 LPTIM45SEL LL_RCC_GetLPTIMClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK1 + * @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_LPTIM23_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PCLK4 + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM45_CLKSOURCE_CLKP + * @retval None + */ +__STATIC_INLINE uint32_t LL_RCC_GetLPTIMClockSource(uint32_t Periph) +{ + return LL_RCC_GetClockSource(Periph); +} + +/** + * @brief Get LPUART clock source + * @rmtoll CCIPR4 LPUART1SEL LL_RCC_GetLPUARTClockSource + * @param Periph 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_PCLK4 + * @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 + */ +__STATIC_INLINE uint32_t LL_RCC_GetLPUARTClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_LPUART1SEL)); +} + +/** + * @brief Get OTGFS clock source + * @rmtoll CCIPR1 OTGFSSEL LL_RCC_GetOTGFSClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_OTGFS_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_HSE + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_HSI48 + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_OTGFS_CLKSOURCE_CLK48 + */ +__STATIC_INLINE uint32_t LL_RCC_GetOTGFSClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_OTGFSSEL)); +} + +/** + * @brief Get XSPI Kernel clock source + * @rmtoll CCIPR1 XSPI1SEL LL_RCC_GetXSPIClockSource\n + * CCIPR1 XSPI2SEL LL_RCC_GetXSPIClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_XSPI1_CLKSOURCE + * @arg @ref LL_RCC_XSPI2_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI1_CLKSOURCE_PLL2T + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_HCLK + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_XSPI2_CLKSOURCE_PLL2T + */ +__STATIC_INLINE uint32_t LL_RCC_GetXSPIClockSource(uint32_t Periph) +{ + return LL_RCC_GetClockSource(Periph); +} + +/** + * @brief Get PSSI clock source + * @rmtoll CCIPR1 PSSISEL LL_RCC_GetPSSIClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_PSSI_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PSSI_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_PSSI_CLKSOURCE_CLKP + */ +__STATIC_INLINE uint32_t LL_RCC_GetPSSIClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_PSSISEL)); +} + +/** + * @brief Get SAIx clock source + * @rmtoll CCIPR3 SAI1SEL LL_RCC_GetSAIClockSource\n + * CCIPR3 SAI2SEL LL_RCC_GetSAIClockSource + * @param Periph 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_I2S_CKIN + * @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_I2S_CKIN + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SAI2_CLKSOURCE_SPDIFRX + */ +__STATIC_INLINE uint32_t LL_RCC_GetSAIClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return LL_RCC_GetClockSource(Periph); +} + +/** + * @brief Get SDMMC clock source + * @rmtoll CCIPR1 SDMMCSEL LL_RCC_GetSDMMCClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_SDMMC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SDMMC_CLKSOURCE_PLL2S + * @arg @ref LL_RCC_SDMMC_CLKSOURCE_PLL2T + */ +__STATIC_INLINE uint32_t LL_RCC_GetSDMMCClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_SDMMC12SEL)); +} + +/** + * @brief Get SPDIFRX Kernel clock source + * @rmtoll CCIPR2 SPDIFRXSEL LL_RCC_GetSPDIFRXClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE_HSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetSPDIFRXClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_SPDIFRXSEL)); +} + +/** + * @brief Get SPIx Kernel clock source + * @rmtoll CCIPR3 SPI1SEL LL_RCC_GetSPIClockSource\n + * CCIPR2 SPI23SEL LL_RCC_GetSPIClockSource\n + * CCIPR3 SPI45SEL LL_RCC_GetSPIClockSource\n + * CCIPR4 SPI6SEL LL_RCC_GetSPIClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_SPI1_CLKSOURCE + * @arg @ref LL_RCC_SPI23_CLKSOURCE + * @arg @ref LL_RCC_SPI45_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_I2S_CKIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SPI23_CLKSOURCE_I2S_CKIN + * @arg @ref LL_RCC_SPI23_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_CSI + * @arg @ref LL_RCC_SPI45_CLKSOURCE_HSE + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK4 + * @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 + */ +__STATIC_INLINE uint32_t LL_RCC_GetSPIClockSource(uint32_t Periph) +{ + return LL_RCC_GetClockSource(Periph); +} + +/** + * @brief Get USARTx clock source + * @rmtoll CCIPR3 USART1SEL LL_RCC_GetUSARTClockSource\n + * CCIPR2 UART234578SEL LL_RCC_GetUSARTClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE + * @arg @ref LL_RCC_USART234578_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_USART234578_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_USART234578_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART234578_CLKSOURCE_LSE + */ +__STATIC_INLINE uint32_t LL_RCC_GetUSARTClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return LL_RCC_GetClockSource(Periph); +} + +/** + * @brief Get USBPHYC clock source + * @rmtoll CCIPR1 USBPHYCSEL LL_RCC_GetUSBPHYCClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_DISABLE + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_HSE + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_HSE_DIV_2 + * @arg @ref LL_RCC_USBPHYC_CLKSOURCE_PLL3Q + */ +__STATIC_INLINE uint32_t LL_RCC_GetUSBPHYCClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USBPHYCSEL)); +} + +/** + * @brief Configure USBREF clock frequency + * @rmtoll CCIPR1 USBREFCKSEL LL_RCC_GetUSBREFClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_USBREF_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USBREF_CLKSOURCE_16M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_19_2M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_20M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_24M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_26M + * @arg @ref LL_RCC_USBREF_CLKSOURCE_32M + * @retval None + */ +__STATIC_INLINE uint32_t LL_RCC_GetUSBREFClockSource(uint32_t Periph) +{ + UNUSED(Periph); + return (READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USBREFCKSEL)); +} + +/** + * @} + */ + +/** @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 + * @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 + */ +__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 VSWRST 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 VSWRST 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 CFGR RTCPRE LL_RCC_SetRTC_HSEPrescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_RTC_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->CFGR, RCC_CFGR_RTCPRE, Prescaler); +} + +/** + * @brief Get HSE Prescalers for RTC Clock + * @rmtoll CFGR RTCPRE LL_RCC_GetRTC_HSEPrescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_RTC_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->CFGR, RCC_CFGR_RTCPRE)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_TIM_CLOCK_PRESCALER TIM + * @{ + */ + +/** + * @brief Set Timers Clock Prescalers + * @rmtoll CFGR 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->CFGR, RCC_CFGR_TIMPRE, Prescaler); +} + +/** + * @brief Get Timers Clock Prescalers + * @rmtoll CFGR 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->CFGR, RCC_CFGR_TIMPRE)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_USBPHYC USBPHYC + * @{ + */ + +/** + * @brief Enable USBPHYC power-down + * @rmtoll AHB1LPENR UCPDCTRL LL_RCC_USBPHYC_EnablePowerDown + * @retval None + */ +__STATIC_INLINE void LL_RCC_USBPHYC_EnablePowerDown(void) +{ + SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_UCPDCTRL); +} + +/** + * @brief Disable USBPHYC power-down + * @rmtoll AHB1LPENR UCPDCTRL LL_RCC_USBPHYC_DisablePowerDown + * @retval None + */ +__STATIC_INLINE void LL_RCC_USBPHYC_DisablePowerDown(void) +{ + CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_UCPDCTRL); +} + +/** + * @brief Check if USBPHYC is powered-down + * @rmtoll AHB1LPENR UCPDCTRL LL_RCC_USBPHYC_IsEnabledPowerDown + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_USBPHYC_IsEnabledPowerDown(void) +{ + return ((READ_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_UCPDCTRL) == (RCC_AHB1LPENR_UCPDCTRL)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_PLL PLL + * @{ + */ + +/** + * @brief Set the oscillator used as PLL clock source. + * @note PLL clock source is common to all PLLs. + * @note PLLSRC can be written only when all PLLs are disabled. + * @rmtoll PLLCKSELR PLLSRC LL_RCC_PLL_SetSource + * @param PLLSource parameter can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_HSI + * @arg @ref LL_RCC_PLLSOURCE_CSI + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_NONE + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL_SetSource(uint32_t PLLSource) +{ + MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_PLLSRC, PLLSource); +} + +/** + * @brief Get the oscillator used as PLL clock source. + * @rmtoll PLLCKSELR PLLSRC LL_RCC_PLL_GetSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_HSI + * @arg @ref LL_RCC_PLLSOURCE_CSI + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_NONE + */ +__STATIC_INLINE uint32_t LL_RCC_PLL_GetSource(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCKSELR, RCC_PLLCKSELR_PLLSRC)); +} + +/** + * @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 PLL1ON 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 Configure PLL1 used for SYSCLK Domain + * @note PLL Source, DIVM1, DIVN and DIVP can be written only when PLL is disabled. + * @note PLLN/PLLR can be written only when PLL is disabled. + * @rmtoll PLLCKSELR PLLSRC LL_RCC_PLL1_ConfigDomain_SYS\n + * PLLCKSELR DIVM1 LL_RCC_PLL1_ConfigDomain_SYS\n + * PLL1DIVR1 DIVN LL_RCC_PLL1_ConfigDomain_SYS\n + * PLL1DIVR1 DIVP LL_RCC_PLL1_ConfigDomain_SYS + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_HSI + * @arg @ref LL_RCC_PLLSOURCE_CSI + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_NONE + * @param M parameter can be a value between 1 and 64 + * @param N parameter can be a value between 8 to 420 + * @param P parameter can be a value between 2 and 128 (odd division factor not supported) + * + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_ConfigDomain_SYS(uint32_t Source, uint32_t M, uint32_t N, uint32_t P) +{ + MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM1 | RCC_PLLCKSELR_PLLSRC, + (M << RCC_PLLCKSELR_DIVM1_Pos) | Source); + MODIFY_REG(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVP | RCC_PLL1DIVR1_DIVN, + ((P - 1UL) << RCC_PLL1DIVR1_DIVP_Pos) | ((N - 1UL) << RCC_PLL1DIVR1_DIVN_Pos)); +} + +/** + * @brief Enable PLL1P + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1PEN LL_RCC_PLL1P_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1P_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1PEN); +} + +/** + * @brief Enable PLL1Q + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1QEN LL_RCC_PLL1Q_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1Q_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1QEN); +} + +/** + * @brief Enable PLL1R + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1REN LL_RCC_PLL1R_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1R_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1REN); +} + +/** + * @brief Enable PLL1S + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1SEN LL_RCC_PLL1S_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1S_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1SEN); +} + +/** + * @brief Enable PLL1 FRACN + * @rmtoll PLLCFGR PLL1FRACEN LL_RCC_PLL1FRACN_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1FRACN_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN); +} + +/** + * @brief Check if PLL1 P is enabled + * @rmtoll PLLCFGR PLL1PEN LL_RCC_PLL1P_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1P_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1PEN) == RCC_PLLCFGR_PLL1PEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL1 Q is enabled + * @rmtoll PLLCFGR PLL1QEN LL_RCC_PLL1Q_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1Q_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1QEN) == RCC_PLLCFGR_PLL1QEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL1 R is enabled + * @rmtoll PLLCFGR PLL1REN LL_RCC_PLL1R_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1R_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1REN) == RCC_PLLCFGR_PLL1REN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL1 S is enabled + * @rmtoll PLLCFGR PLL1SEN LL_RCC_PLL1S_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1S_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1SEN) == RCC_PLLCFGR_PLL1SEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL1 FRACN is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN) == RCC_PLLCFGR_PLL1FRACEN) ? 1UL : 0UL); +} + +/** + * @brief Disable PLL1P + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1PEN LL_RCC_PLL1P_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1P_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1PEN); +} + +/** + * @brief Disable PLL1Q + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1QEN LL_RCC_PLL1Q_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1Q_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1QEN); +} + +/** + * @brief Disable PLL1R + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1REN LL_RCC_PLL1R_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1R_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1REN); +} + +/** + * @brief Disable PLL1S + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1SEN LL_RCC_PLL1S_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1S_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1SEN); +} + +/** + * @brief Disable PLL1 FRACN + * @rmtoll PLLCFGR PLL1FRACEN LL_RCC_PLL1FRACN_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1FRACN_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN); +} + +/** + * @brief Get PLL1 VCO Input Range + * @rmtoll PLLCFGR PLL1RGE LL_RCC_PLL1_GetVCOInputRange + * @retval Returned value 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 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetVCOInputRange(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1RGE)); +} + +/** + * @brief Get PLL1 VCO OutputRange + * @rmtoll PLLCFGR PLL1VCOSEL LL_RCC_PLL1_GetVCOOutputRange + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLLVCORANGE_WIDE + * @arg @ref LL_RCC_PLLVCORANGE_MEDIUM + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetVCOOutputRange(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1VCOSEL)); +} + +/** + * @brief Set PLL1 VCO Input Range + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL1RGE, InputRange); +} + +/** + * @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->PLLCFGR, RCC_PLLCFGR_PLL1VCOSEL, VCORange); +} + +/** + * @brief Get PLL1 N Coefficient + * @rmtoll PLL1DIVR1 DIVN LL_RCC_PLL1_GetN + * @retval A value between 8 and 420 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetN(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVN) >> RCC_PLL1DIVR1_DIVN_Pos) + 1UL); +} + +/** + * @brief Get PLL1 M Coefficient + * @rmtoll PLLCKSELR DIVM1 LL_RCC_PLL1_GetM + * @retval A value between 0 and 63 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetM(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos); +} + +/** + * @brief Get PLL1 P Coefficient + * @rmtoll PLL1DIVR1 DIVP LL_RCC_PLL1_GetP + * @retval A value between 2 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetP(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1UL); +} + +/** + * @brief Get PLL1 Q Coefficient + * @rmtoll PLL1DIVR1 DIVQ LL_RCC_PLL1_GetQ + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetQ(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVQ) >> RCC_PLL1DIVR1_DIVQ_Pos) + 1UL); +} + +/** + * @brief Get PLL1 R Coefficient + * @rmtoll PLL1DIVR1 DIVR LL_RCC_PLL1_GetR + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetR(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVR) >> RCC_PLL1DIVR1_DIVR_Pos) + 1UL); +} + +/** + * @brief Get PLL1 S Coefficient + * @rmtoll PLL1DIVR2 DIVS LL_RCC_PLL1_GetS + * @retval A value between 1 and 8 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetS(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR2, RCC_PLL1DIVR2_DIVS) >> RCC_PLL1DIVR2_DIVS_Pos) + 1UL); +} + +/** + * @brief Get PLL1 FRACN Coefficient + * @rmtoll PLL1FRACR FRACN 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_FRACN) >> RCC_PLL1FRACR_FRACN_Pos); +} + +/** + * @brief Set PLL1 N Coefficient + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1DIVR1 DIVN LL_RCC_PLL1_SetN + * @param N parameter can be a value between 8 and 420 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetN(uint32_t N) +{ + MODIFY_REG(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVN, (N - 1UL) << RCC_PLL1DIVR1_DIVN_Pos); +} + +/** + * @brief Set PLL1 M Coefficient + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCKSELR DIVM1 LL_RCC_PLL1_SetM + * @param M parameter can be a value between 1 and 64 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetM(uint32_t M) +{ + MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM1, M << RCC_PLLCKSELR_DIVM1_Pos); +} + +/** + * @brief Set PLL1 P Coefficient + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1DIVR1 DIVP LL_RCC_PLL1_SetP + * @param P parameter can be a value between 2 and 128 (odd division factor not supported) + */ +__STATIC_INLINE void LL_RCC_PLL1_SetP(uint32_t P) +{ + MODIFY_REG(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVP, (P - 1UL) << RCC_PLL1DIVR1_DIVP_Pos); +} + +/** + * @brief Set PLL1 Q Coefficient + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1DIVR1 DIVQ LL_RCC_PLL1_SetQ + * @param Q parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetQ(uint32_t Q) +{ + MODIFY_REG(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVQ, (Q - 1UL) << RCC_PLL1DIVR1_DIVQ_Pos); +} + +/** + * @brief Set PLL1 R Coefficient + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1DIVR1 DIVR LL_RCC_PLL1_SetR + * @param R parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetR(uint32_t R) +{ + MODIFY_REG(RCC->PLL1DIVR1, RCC_PLL1DIVR1_DIVR, (R - 1UL) << RCC_PLL1DIVR1_DIVR_Pos); +} + +/** + * @brief Set PLL1 S Coefficient + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1DIVR2 DIVS LL_RCC_PLL1_SetS + * @param S parameter can be a value between 1 and 8 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetS(uint32_t S) +{ + MODIFY_REG(RCC->PLL1DIVR2, RCC_PLL1DIVR2_DIVS, (S - 1UL) << RCC_PLL1DIVR2_DIVS_Pos); +} + +/** + * @brief Set PLL1 FRACN Coefficient + * @rmtoll PLL1FRACR FRACN 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_FRACN, FRACN << RCC_PLL1FRACR_FRACN_Pos); +} + +/** + * @brief Enable Spread Spectrum for PLL1. + * @note Configuration to be done with LL_RCC_PLL1_ConfigSpreadSpectrum + * @rmtoll PLLCFGR PLL1SSCGEN LL_RCC_PLL1_EnableSpreadSpectrum + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_EnableSpreadSpectrum(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1SSCGEN); +} + +/** + * @brief Disable Spread Spectrum for PLL1. + * @rmtoll PLLCFGR PLL1SSCGEN LL_RCC_PLL1_DisableSpreadSpectrum + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_DisableSpreadSpectrum(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1SSCGEN); +} + +/** + * @brief Check if Spread Spectrum for PLL1 is enabled + * @rmtoll PLLCFGR PLL1SSCGEN LL_RCC_PLL1_IsEnabledSpreadSpectrum + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_IsEnabledSpreadSpectrum(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1SSCGEN) == RCC_PLLCFGR_PLL1SSCGEN) ? 1UL : 0UL); +} + +/** + * @brief Get Spread Spectrum Modulation Period for PLL1 + * @rmtoll PLL1SSCGR MODPER LL_RCC_PLL1_GetModulationPeriod + * @retval Between Min_Data=0 and Max_Data=8191 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetModulationPeriod(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL1SSCGR, RCC_PLL1SSCGR_MODPER)); +} + +/** + * @brief Get Spread Spectrum Increment Step for PLL1 + * @rmtoll PLL1SSCGR INCSTEP LL_RCC_PLL1_GetIncrementStep + * @retval Between Min_Data=0 and Max_Data=32767 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetIncrementStep(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL1SSCGR, RCC_PLL1SSCGR_INCSTEP) >> RCC_PLL1SSCGR_INCSTEP_Pos); +} + +/** + * @brief Get Spread Spectrum Selection for PLL1 + * @rmtoll PLL1SSCGR SPREADSEL LL_RCC_PLL1_GetSpreadSelection + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL_SPREAD_CENTER + * @arg @ref LL_RCC_PLL_SPREAD_DOWN + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetSpreadSelection(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL1SSCGR, RCC_PLL1SSCGR_SPREADSEL)); +} + +/** + * @brief Check if Dithering RPDF Noise for PLL1 is enabled + * @rmtoll PLL1SSCGR RPDFNDIS LL_RCC_PLL1_IsEnabledRPDFNDithering + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_IsEnabledRPDFNDithering(void) +{ + return ((READ_BIT(RCC->PLL1SSCGR, RCC_PLL1SSCGR_RPDFNDIS) == 0U) ? 1UL : 0UL); +} + +/** + * @brief Check if Dithering TPDF Noise for PLL1 is enabled + * @rmtoll PLL1SSCGR TPDFNDIS LL_RCC_PLL1_IsEnabledTPDFNDithering + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_IsEnabledTPDFNDithering(void) +{ + return ((READ_BIT(RCC->PLL1SSCGR, RCC_PLL1SSCGR_TPDFNDIS) == 0U) ? 1UL : 0UL); +} + +/** + * @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 + * @note Cannot be disabled if the PLL2 clock is used as the system clock + * @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 Enable PLL2P + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2PEN LL_RCC_PLL2P_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2P_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2PEN); +} + +/** + * @brief Enable PLL2Q + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2QEN LL_RCC_PLL2Q_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2Q_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2QEN); +} + +/** + * @brief Enable PLL2R + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2REN LL_RCC_PLL2R_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2R_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2REN); +} + +/** + * @brief Enable PLL2S + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2SEN LL_RCC_PLL2S_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2S_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2SEN); +} + +/** + * @brief Enable PLL2T + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2TEN LL_RCC_PLL2T_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2T_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2TEN); +} + +/** + * @brief Enable PLL2 FRACN + * @rmtoll PLLCFGR PLL2FRACEN LL_RCC_PLL2FRACN_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2FRACN_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2FRACEN); +} + +/** + * @brief Check if PLL2 P is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL2PEN) == RCC_PLLCFGR_PLL2PEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 Q is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL2QEN) == RCC_PLLCFGR_PLL2QEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 R is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL2REN) == RCC_PLLCFGR_PLL2REN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 S is enabled + * @rmtoll PLLCFGR PLL2SEN LL_RCC_PLL2S_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2S_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2SEN) == RCC_PLLCFGR_PLL2SEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 T is enabled + * @rmtoll PLLCFGR PLL2TEN LL_RCC_PLL2T_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2T_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2TEN) == RCC_PLLCFGR_PLL2TEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 FRACN is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL2FRACEN) == RCC_PLLCFGR_PLL2FRACEN) ? 1UL : 0UL); +} + +/** + * @brief Disable PLL2P + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2PEN LL_RCC_PLL2P_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2P_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2PEN); +} + +/** + * @brief Disable PLL2Q + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2QEN LL_RCC_PLL2Q_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2Q_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2QEN); +} + +/** + * @brief Disable PLL2R + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2REN LL_RCC_PLL2R_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2R_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2REN); +} + +/** + * @brief Disable PLL2S + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2SEN LL_RCC_PLL2S_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2S_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2SEN); +} + +/** + * @brief Disable PLL2T + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR PLL2TEN LL_RCC_PLL2T_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2T_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2TEN); +} + +/** + * @brief Disable PLL2 FRACN + * @rmtoll PLLCFGR PLL2FRACEN LL_RCC_PLL2FRACN_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2FRACN_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2FRACEN); +} + +/** + * @brief Get PLL2 VCO Input Range + * @rmtoll PLLCFGR PLL2RGE LL_RCC_PLL2_GetVCOInputRange + * @retval Returned value 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 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetVCOInputRange(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2RGE) >> 11U); +} + +/** + * @brief Get PLL2 VCO OutputRange + * @rmtoll PLLCFGR PLL2VCOSEL LL_RCC_PLL2_GetVCOOutputRange + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLLVCORANGE_WIDE + * @arg @ref LL_RCC_PLLVCORANGE_MEDIUM + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetVCOOutputRange(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2VCOSEL) >> 11U); +} + +/** + * @brief Set PLL2 VCO Input Range + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL2RGE, (InputRange << 11U)); +} + +/** + * @brief Set PLL2 VCO OutputRange + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL2VCOSEL, (VCORange << 11U)); +} + +/** + * @brief Get PLL2 N Coefficient + * @rmtoll PLL2DIVR1 DIVN LL_RCC_PLL2_GetN + * @retval A value between 8 and 420 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetN(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVN) >> RCC_PLL2DIVR1_DIVN_Pos) + 1UL); +} + +/** + * @brief Get PLL2 M Coefficient + * @rmtoll PLLCKSELR DIVM2 LL_RCC_PLL2_GetM + * @retval A value between 0 and 63 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetM(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM2) >> RCC_PLLCKSELR_DIVM2_Pos); +} + +/** + * @brief Get PLL2 P Coefficient + * @rmtoll PLL2DIVR1 DIVP LL_RCC_PLL2_GetP + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetP(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVP) >> RCC_PLL2DIVR1_DIVP_Pos) + 1UL); +} + +/** + * @brief Get PLL2 Q Coefficient + * @rmtoll PLL2DIVR1 DIVQ LL_RCC_PLL2_GetQ + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetQ(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVQ) >> RCC_PLL2DIVR1_DIVQ_Pos) + 1UL); +} + +/** + * @brief Get PLL2 R Coefficient + * @rmtoll PLL2DIVR1 DIVR LL_RCC_PLL2_GetR + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetR(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVR) >> RCC_PLL2DIVR1_DIVR_Pos) + 1UL); +} + +/** + * @brief Get PLL2 S Coefficient + * @rmtoll PLL2DIVR2 DIVS LL_RCC_PLL2_GetS + * @retval A value between 1 and 8 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetS(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR2, RCC_PLL2DIVR2_DIVS) >> RCC_PLL2DIVR2_DIVS_Pos) + 1UL); +} + +/** + * @brief Get PLL2 T Coefficient + * @rmtoll PLL2DIVR2 DIVT LL_RCC_PLL2_GetT + * @retval A value between 1 and 8 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetT(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR2, RCC_PLL2DIVR2_DIVT) >> RCC_PLL2DIVR2_DIVT_Pos) + 1UL); +} + +/** + * @brief Get PLL2 FRACN Coefficient + * @rmtoll PLL2FRACR FRACN 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_FRACN) >> RCC_PLL2FRACR_FRACN_Pos); +} + +/** + * @brief Set PLL2 N Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2DIVR1 DIVN LL_RCC_PLL2_SetN + * @param N parameter can be a value between 8 and 420 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetN(uint32_t N) +{ + MODIFY_REG(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVN, (N - 1UL) << RCC_PLL2DIVR1_DIVN_Pos); +} + +/** + * @brief Set PLL2 M Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLLCKSELR DIVM2 LL_RCC_PLL2_SetM + * @param M parameter can be a value between 1 and 64 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetM(uint32_t M) +{ + MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM2, M << RCC_PLLCKSELR_DIVM2_Pos); +} + +/** + * @brief Set PLL2 P Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2DIVR1 DIVP LL_RCC_PLL2_SetP + * @param P parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetP(uint32_t P) +{ + MODIFY_REG(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVP, (P - 1UL) << RCC_PLL2DIVR1_DIVP_Pos); +} + +/** + * @brief Set PLL2 Q Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2DIVR1 DIVQ LL_RCC_PLL2_SetQ + * @param Q parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetQ(uint32_t Q) +{ + MODIFY_REG(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVQ, (Q - 1UL) << RCC_PLL2DIVR1_DIVQ_Pos); +} + +/** + * @brief Set PLL2 R Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2DIVR1 DIVR LL_RCC_PLL2_SetR + * @param R parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetR(uint32_t R) +{ + MODIFY_REG(RCC->PLL2DIVR1, RCC_PLL2DIVR1_DIVR, (R - 1UL) << RCC_PLL2DIVR1_DIVR_Pos); +} + +/** + * @brief Set PLL2 S Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2DIVR2 DIVS LL_RCC_PLL2_SetS + * @param S parameter can be a value between 1 and 8 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetS(uint32_t S) +{ + MODIFY_REG(RCC->PLL2DIVR2, RCC_PLL2DIVR2_DIVS, (S - 1UL) << RCC_PLL2DIVR2_DIVS_Pos); +} + +/** + * @brief Set PLL2 T Coefficient + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2DIVR2 DIVT LL_RCC_PLL2_SetT + * @param T parameter can be a value between 1 and 8 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetT(uint32_t T) +{ + MODIFY_REG(RCC->PLL2DIVR2, RCC_PLL2DIVR2_DIVT, (T - 1UL) << RCC_PLL2DIVR2_DIVT_Pos); +} + +/** + * @brief Set PLL2 FRACN Coefficient + * @rmtoll PLL2FRACR FRACN 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_FRACN, FRACN << RCC_PLL2FRACR_FRACN_Pos); +} + +/** + * @brief Enable Spread Spectrum for PLL2. + * @note Configuration to be done with LL_RCC_PLL2_ConfigSpreadSpectrum + * @rmtoll PLLCFGR PLL2SSCGEN LL_RCC_PLL2_EnableSpreadSpectrum + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_EnableSpreadSpectrum(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2SSCGEN); +} + +/** + * @brief Disable Spread Spectrum for PLL2. + * @rmtoll PLLCFGR PLL2SSCGEN LL_RCC_PLL2_DisableSpreadSpectrum + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_DisableSpreadSpectrum(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2SSCGEN); +} + +/** + * @brief Check if Spread Spectrum for PLL2 is enabled + * @rmtoll PLLCFGR PLL2SSCGEN LL_RCC_PLL2_IsEnabledSpreadSpectrum + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_IsEnabledSpreadSpectrum(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL2SSCGEN) == RCC_PLLCFGR_PLL2SSCGEN) ? 1UL : 0UL); +} + +/** + * @brief Get Spread Spectrum Modulation Period for PLL2 + * @rmtoll PLL2SSCGR MODPER LL_RCC_PLL2_GetModulationPeriod + * @retval Between Min_Data=0 and Max_Data=8191 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetModulationPeriod(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL2SSCGR, RCC_PLL2SSCGR_MODPER)); +} + +/** + * @brief Get Spread Spectrum Increment Step for PLL2 + * @rmtoll PLL2SSCGR INCSTEP LL_RCC_PLL2_GetIncrementStep + * @retval Between Min_Data=0 and Max_Data=32767 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetIncrementStep(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL2SSCGR, RCC_PLL2SSCGR_INCSTEP) >> RCC_PLL2SSCGR_INCSTEP_Pos); +} + +/** + * @brief Get Spread Spectrum Selection for PLL2 + * @rmtoll PLL2SSCGR SPREADSEL LL_RCC_PLL2_GetSpreadSelection + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL_SPREAD_CENTER + * @arg @ref LL_RCC_PLL_SPREAD_DOWN + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetSpreadSelection(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL2SSCGR, RCC_PLL2SSCGR_SPREADSEL)); +} + + +/** + * @brief Check if Dithering RPDF Noise for PLL2 is enabled + * @rmtoll PLL2SSCGR RPDFNDIS LL_RCC_PLL2_IsEnabledRPDFNDithering + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_IsEnabledRPDFNDithering(void) +{ + return ((READ_BIT(RCC->PLL2SSCGR, RCC_PLL2SSCGR_RPDFNDIS) == 0U) ? 1UL : 0UL); +} + +/** + * @brief Check if Dithering TPDF Noise for PLL2 is enabled + * @rmtoll PLL2SSCGR TPDFNDIS LL_RCC_PLL2_IsEnabledTPDFNDithering + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_IsEnabledTPDFNDithering(void) +{ + return ((READ_BIT(RCC->PLL2SSCGR, RCC_PLL2SSCGR_TPDFNDIS) == 0U) ? 1UL : 0UL); +} +/** + * @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 + * @note Cannot be disabled if the PLL3 clock is used as the system clock + * @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 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 Enable PLL3P + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3PEN LL_RCC_PLL3P_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3P_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3PEN); +} + +/** + * @brief Enable PLL3Q + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3QEN LL_RCC_PLL3Q_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3Q_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3QEN); +} + +/** + * @brief Enable PLL3R + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3REN LL_RCC_PLL3R_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3R_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3REN); +} + +/** + * @brief Enable PLL3S + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3SEN LL_RCC_PLL3S_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3S_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3SEN); +} + +/** + * @brief Enable PLL3 FRACN + * @rmtoll PLLCFGR PLL3FRACEN LL_RCC_PLL3FRACN_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3FRACN_Enable(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3FRACEN); +} + +/** + * @brief Check if PLL3 P is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL3PEN) == RCC_PLLCFGR_PLL3PEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL3 Q is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL3QEN) == RCC_PLLCFGR_PLL3QEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL3 R is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL3REN) == RCC_PLLCFGR_PLL3REN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL3 S is enabled + * @rmtoll PLLCFGR PLL3SEN LL_RCC_PLL3S_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3S_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3SEN) == RCC_PLLCFGR_PLL3SEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL3 FRACN is enabled + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL3FRACEN) == RCC_PLLCFGR_PLL3FRACEN) ? 1UL : 0UL); +} + +/** + * @brief Disable PLL3P + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3PEN LL_RCC_PLL3P_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3P_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3PEN); +} + +/** + * @brief Disable PLL3Q + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3QEN LL_RCC_PLL3Q_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3Q_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3QEN); +} + +/** + * @brief Disable PLL3R + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3REN LL_RCC_PLL3R_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3R_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3REN); +} + +/** + * @brief Disable PLL3S + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR PLL3SEN LL_RCC_PLL3S_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3S_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3SEN); +} + +/** + * @brief Disable PLL3 FRACN + * @rmtoll PLLCFGR PLL3FRACEN LL_RCC_PLL3FRACN_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3FRACN_Disable(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3FRACEN); +} + +/** + * @brief Get PLL3 VCO Input Range + * @rmtoll PLLCFGR PLL3RGE LL_RCC_PLL3_GetVCOInputRange + * @retval Returned value 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 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetVCOInputRange(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3RGE) >> 22U); +} + +/** + * @brief Get PLL3 VCO OutputRange + * @rmtoll PLLCFGR PLL3VCOSEL LL_RCC_PLL3_GetVCOOutputRange + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLLVCORANGE_WIDE + * @arg @ref LL_RCC_PLLVCORANGE_MEDIUM + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetVCOOutputRange(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3VCOSEL) >> 22U); +} + +/** + * @brief Set PLL3 VCO Input Range + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL3RGE, (InputRange << 22U)); +} + +/** + * @brief Set PLL3 VCO OutputRange + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCFGR 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->PLLCFGR, RCC_PLLCFGR_PLL3VCOSEL, (VCORange << 22U)); +} + +/** + * @brief Get PLL3 N Coefficient + * @rmtoll PLL3DIVR1 DIVN LL_RCC_PLL3_GetN + * @retval A value between 8 and 420 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetN(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVN) >> RCC_PLL3DIVR1_DIVN_Pos) + 1UL); +} + +/** + * @brief Get PLL3 M Coefficient + * @rmtoll PLLCKSELR DIVM3 LL_RCC_PLL3_GetM + * @retval A value between 0 and 63 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetM(void) +{ + return (uint32_t)(READ_BIT(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM3) >> RCC_PLLCKSELR_DIVM3_Pos); +} + +/** + * @brief Get PLL3 P Coefficient + * @rmtoll PLL3DIVR1 DIVP LL_RCC_PLL3_GetP + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetP(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVP) >> RCC_PLL3DIVR1_DIVP_Pos) + 1UL); +} + +/** + * @brief Get PLL3 Q Coefficient + * @rmtoll PLL3DIVR1 DIVQ LL_RCC_PLL3_GetQ + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetQ(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVQ) >> RCC_PLL3DIVR1_DIVQ_Pos) + 1UL); +} + +/** + * @brief Get PLL3 R Coefficient + * @rmtoll PLL3DIVR1 DIVR LL_RCC_PLL3_GetR + * @retval A value between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetR(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVR) >> RCC_PLL3DIVR1_DIVR_Pos) + 1UL); +} + +/** + * @brief Get PLL3 S Coefficient + * @rmtoll PLL3DIVR2 DIVS LL_RCC_PLL3_GetS + * @retval A value between 1 and 8 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetS(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR2, RCC_PLL3DIVR2_DIVS) >> RCC_PLL3DIVR2_DIVS_Pos) + 1UL); +} + +/** + * @brief Get PLL3 FRACN Coefficient + * @rmtoll PLL3FRACR FRACN 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_FRACN) >> RCC_PLL3FRACR_FRACN_Pos); +} + +/** + * @brief Set PLL3 N Coefficient + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3DIVR1 DIVN LL_RCC_PLL3_SetN + * @param N parameter can be a value between 8 and 420 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetN(uint32_t N) +{ + MODIFY_REG(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVN, (N - 1UL) << RCC_PLL3DIVR1_DIVN_Pos); +} + +/** + * @brief Set PLL3 M Coefficient + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLLCKSELR DIVM3 LL_RCC_PLL3_SetM + * @param M parameter can be a value between 1 and 64 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetM(uint32_t M) +{ + MODIFY_REG(RCC->PLLCKSELR, RCC_PLLCKSELR_DIVM3, M << RCC_PLLCKSELR_DIVM3_Pos); +} + +/** + * @brief Set PLL3 P Coefficient + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3DIVR1 DIVP LL_RCC_PLL3_SetP + * @param P parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetP(uint32_t P) +{ + MODIFY_REG(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVP, (P - 1UL) << RCC_PLL3DIVR1_DIVP_Pos); +} + +/** + * @brief Set PLL3 Q Coefficient + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3DIVR1 DIVQ LL_RCC_PLL3_SetQ + * @param Q parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetQ(uint32_t Q) +{ + MODIFY_REG(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVQ, (Q - 1UL) << RCC_PLL3DIVR1_DIVQ_Pos); +} + +/** + * @brief Set PLL3 R Coefficient + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3DIVR1 DIVR LL_RCC_PLL3_SetR + * @param R parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetR(uint32_t R) +{ + MODIFY_REG(RCC->PLL3DIVR1, RCC_PLL3DIVR1_DIVR, (R - 1UL) << RCC_PLL3DIVR1_DIVR_Pos); +} + +/** + * @brief Set PLL3 S Coefficient + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3DIVR2 DIVS LL_RCC_PLL3_SetS + * @param S parameter can be a value between 1 and 8 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetS(uint32_t S) +{ + MODIFY_REG(RCC->PLL3DIVR2, RCC_PLL3DIVR2_DIVS, (S - 1UL) << RCC_PLL3DIVR2_DIVS_Pos); +} + +/** + * @brief Set PLL3 FRACN Coefficient + * @rmtoll PLL3FRACR FRACN 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_FRACN, FRACN << RCC_PLL3FRACR_FRACN_Pos); +} + + +/** + * @brief Enable Spread Spectrum for PLL3. + * @note Configuration to be done with LL_RCC_PLL3_ConfigSpreadSpectrum + * @rmtoll PLLCFGR PLL3SSCGEN LL_RCC_PLL3_EnableSpreadSpectrum + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_EnableSpreadSpectrum(void) +{ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3SSCGEN); +} + +/** + * @brief Disable Spread Spectrum for PLL3. + * @rmtoll PLLCFGR PLL3SSCGEN LL_RCC_PLL3_DisableSpreadSpectrum + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_DisableSpreadSpectrum(void) +{ + CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3SSCGEN); +} + +/** + * @brief Check if Spread Spectrum for PLL3 is enabled + * @rmtoll PLLCFGR PLL3SSCGEN LL_RCC_PLL3_IsEnabledSpreadSpectrum + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_IsEnabledSpreadSpectrum(void) +{ + return ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL3SSCGEN) == RCC_PLLCFGR_PLL3SSCGEN) ? 1UL : 0UL); +} + +/** + * @brief Get Spread Spectrum Modulation Period for PLL3 + * @rmtoll PLL3SSCGR MODPER LL_RCC_PLL3_GetModulationPeriod + * @retval Between Min_Data=0 and Max_Data=8191 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetModulationPeriod(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL3SSCGR, RCC_PLL3SSCGR_MODPER)); +} + +/** + * @brief Get Spread Spectrum Increment Step for PLL3 + * @rmtoll PLL3SSCGR INCSTEP LL_RCC_PLL3_GetIncrementStep + * @retval Between Min_Data=0 and Max_Data=32767 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetIncrementStep(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL3SSCGR, RCC_PLL3SSCGR_INCSTEP) >> RCC_PLL3SSCGR_INCSTEP_Pos); +} + +/** + * @brief Get Spread Spectrum Selection for PLL3 + * @rmtoll PLL3SSCGR SPREADSEL LL_RCC_PLL3_GetSpreadSelection + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL_SPREAD_CENTER + * @arg @ref LL_RCC_PLL_SPREAD_DOWN + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetSpreadSelection(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL3SSCGR, RCC_PLL3SSCGR_SPREADSEL)); +} + + +/** + * @brief Check if Dithering RPDF Noise for PLL3 is enabled + * @rmtoll PLL3SSCGR RPDFNDIS LL_RCC_PLL3_IsEnabledRPDFNDithering + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_IsEnabledRPDFNDithering(void) +{ + return ((READ_BIT(RCC->PLL3SSCGR, RCC_PLL3SSCGR_RPDFNDIS) == 0U) ? 1UL : 0UL); +} + +/** + * @brief Check if Dithering TPDF Noise for PLL3 is enabled + * @rmtoll PLL3SSCGR TPDFNDIS LL_RCC_PLL3_IsEnabledTPDFNDithering + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_IsEnabledTPDFNDithering(void) +{ + return ((READ_BIT(RCC->PLL3SSCGR, RCC_PLL3SSCGR_TPDFNDIS) == 0U) ? 1UL : 0UL); +} +/** + * @} + */ + + +/** @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 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 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 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); +} + +/** + * @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); +} + +/** + * @brief Clear LSE Clock security system interrupt flag + * @rmtoll CICR LSECSSC LL_RCC_ClearFlag_LSECSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_LSECSS(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_LSECSSC); +} + +/** + * @brief Clear HSE 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 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 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 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); +} + +/** + * @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); +} + +/** + * @brief Check if LSE Clock security system interrupt occurred or not + * @rmtoll CIFR LSECSSF LL_RCC_IsActiveFlag_LSECSS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LSECSS(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_LSECSSF) == RCC_CIFR_LSECSSF) ? 1UL : 0UL); +} + +/** + * @brief Check if HSE 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 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 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 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 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 POR/PDR reset is set or not. + * @rmtoll RSR PORRSTF LL_RCC_IsActiveFlag_PORRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PORRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_PORRSTF) == RCC_RSR_PORRSTF) ? 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 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 all 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 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 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 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); +} + +/** + * @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); +} + +/** + * @brief Enable LSECSS interrupt + * @rmtoll CIER LSECSSIE LL_RCC_EnableIT_LSECSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_LSECSS(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_LSECSSIE); +} + +/** + * @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 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 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 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); +} + +/** + * @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); +} + +/** + * @brief Disable LSECSS interrupt + * @rmtoll CIER LSECSSIE LL_RCC_DisableIT_LSECSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_LSECSS(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_LSECSSIE); +} + +/** + * @brief Checks if LSI ready interrupt source is enabled or disabled. + * @rmtoll CIER LSIRDYIE LL_RCC_IsEnableIT_LSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_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_IsEnableIT_LSERDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_LSERDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_LSERDYIE) == RCC_CIER_LSERDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if HSI ready interrupt source is enabled or disabled. + * @rmtoll CIER HSIRDYIE LL_RCC_IsEnableIT_HSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_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_IsEnableIT_HSERDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_HSERDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_HSERDYIE) == RCC_CIER_HSERDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if CSI ready interrupt source is enabled or disabled. + * @rmtoll CIER CSIRDYIE LL_RCC_IsEnableIT_CSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_CSIRDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_CSIRDYIE) == RCC_CIER_CSIRDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if HSI48 ready interrupt source is enabled or disabled. + * @rmtoll CIER HSI48RDYIE LL_RCC_IsEnableIT_HSI48RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_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_IsEnableIT_PLL1RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_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_IsEnableIT_PLL2RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_PLL2RDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_PLL2RDYIE) == RCC_CIER_PLL2RDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if PLL3 ready interrupt source is enabled or disabled. + * @rmtoll CIER PLL3RDYIE LL_RCC_IsEnableIT_PLL3RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_PLL3RDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_PLL3RDYIE) == RCC_CIER_PLL3RDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if LSECSS interrupt source is enabled or disabled. + * @rmtoll CIER LSECSSIE LL_RCC_IsEnableIT_LSECSS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnableIT_LSECSS(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_LSECSSIE) == RCC_CIER_LSECSSIE) ? 1UL : 0UL); +} +/** + * @} + */ + +/** @defgroup RCC_LL_EF_CALC_FREQ Calculate frequencies + * @{ + */ +/** + * @brief Helper function to calculate the PLL 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 clock frequency (in Hz) + */ +__STATIC_INLINE 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; +} +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_EF_Init De-initialization function + * @{ + */ +void LL_RCC_DeInit(void); +/** + * @} + */ + +/** @defgroup RCC_LL_EF_Get_Freq Get system and peripherals clocks frequency functions + * @{ + */ +void LL_RCC_GetPLL1ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks); +void LL_RCC_GetPLL2ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks); +void LL_RCC_GetPLL3ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks); +void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks); + +void LL_RCC_PLL1_ConfigSpreadSpectrum(const LL_PLL_SpreadSpectrumTypeDef *pConfig); +void LL_RCC_PLL2_ConfigSpreadSpectrum(const LL_PLL_SpreadSpectrumTypeDef *pConfig); +void LL_RCC_PLL3_ConfigSpreadSpectrum(const LL_PLL_SpreadSpectrumTypeDef *pConfig); + +uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource); +uint32_t LL_RCC_GetADFClockFreq(uint32_t ADFxSource); +uint32_t LL_RCC_GetCECClockFreq(uint32_t CECxSource); +uint32_t LL_RCC_GetCLKPClockFreq(uint32_t CLKPxSource); +uint32_t LL_RCC_GetETHPHYClockFreq(uint32_t ETHxSource); +uint32_t LL_RCC_GetFDCANClockFreq(uint32_t FDCANxSource); +uint32_t LL_RCC_GetFMCClockFreq(uint32_t FMCxSource); +uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource); +uint32_t LL_RCC_GetI3CClockFreq(uint32_t I3CxSource); +uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource); +uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource); +uint32_t LL_RCC_GetXSPIClockFreq(uint32_t XSPIxSource); +uint32_t LL_RCC_GetPSSIClockFreq(uint32_t PSSIxSource); +uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource); +uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource); +uint32_t LL_RCC_GetSPDIFRXClockFreq(uint32_t SPDIFRXxSource); +uint32_t LL_RCC_GetSPIClockFreq(uint32_t SPIxSource); +uint32_t LL_RCC_GetUARTClockFreq(uint32_t UARTxSource); +uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource); +uint32_t LL_RCC_GetUSBPHYCClockFreq(uint32_t USBPHYCxSource); + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(RCC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_RCC_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_system.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_system.h new file mode 100644 index 0000000..97fa12d --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_system.h @@ -0,0 +1,2219 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_system.h + * @author MCD Application Team + * @brief Header file of SYSTEM LL 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. + * + ****************************************************************************** + @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 + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7RSxx_LL_SYSTEM_H +#define STM32H7RSxx_LL_SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" + +/** @addtogroup STM32H7RSxx_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_REGISTER_PINPOS_SHFT 16U /*!< Define used to shift pin position in EXTICR register */ +#define LL_SBS_HDPL_INCREMENT_VALUE 0x6AU /*!< Define used for the HDPL increment */ +#define LL_SBS_DBG_UNLOCK (0xB4UL << 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 */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Exported_Constants SYSTEM Exported Constants + * @{ + */ + +/** @defgroup SYSTEM_LL_EC_SBS_HDPL SBS hide protection level + * @{ + */ +#define LL_SBS_HDPL0 0xB4U /*!< Hide protection level 0 */ +#define LL_SBS_HDPL1 0x51U /*!< Hide protection level 1 */ +#define LL_SBS_HDPL2 0x8AU /*!< Hide protection level 2 */ +#define LL_SBS_HDPL3 0x6FU /*!< Hide protection level 3 */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_AXISRAM_WS SBS AXISRAM wait state number (when ECC=0) + * @{ + */ +#define LL_SBS_AXISRAM_NO_WS 0U /*!< No wait state added when accessing AXISRAM */ +#define LL_SBS_AXISRAM_ONE_WS SBS_PMCR_AXISRAM_WS /*!< One wait state added when accessing AXISRAM */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_ETH_PHYSEL SBS Ethernet PHY interface selection + * @{ + */ +#define LL_SBS_ETH_PHYSEL_GMII_MII 0U /*!< GMII or MII interface */ +#define LL_SBS_ETH_PHYSEL_RMII SBS_PMCR_ETH_PHYSEL_2 /*!< RMII interface */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_BOOSTVDDSEL SBS Booster Vdd selection + * @{ + */ +#define LL_SBS_BOOSTVDDSEL_VDDA 0U /*!< Vdda selected as analog switch booster voltage supply */ +#define LL_SBS_BOOSTVDDSEL_VDD SBS_PMCR_BOOSTVDDSEL /*!< Vdd selected as analog switch booster voltage supply */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_XSPI2_COMP_CODESEL SBS XSPI2 compensation cell code selection + * @{ + */ +#define LL_SBS_XSPI2_CODE_CELL 0U /*!< Code applied to compensation cell from cell */ +#define LL_SBS_XSPI2_CODE_REG SBS_CCCSR_XSPI2_COMP_CODESEL /*!< Code applied to compensation cell from register */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_XSPI1_COMP_CODESEL SBS XSPI1 compensation cell code selection + * @{ + */ +#define LL_SBS_XSPI1_CODE_CELL 0U /*!< Code applied to compensation cell from cell */ +#define LL_SBS_XSPI1_CODE_REG SBS_CCCSR_XSPI1_COMP_CODESEL /*!< Code applied to compensation cell from register */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_COMP_CODESEL SBS I/O compensation cell code selection + * @{ + */ +#define LL_SBS_IO_CODE_CELL 0U /*!< Code applied to compensation cell from cell */ +#define LL_SBS_IO_CODE_REG SBS_CCCSR_COMP_CODESEL /*!< Code applied to compensation cell from register */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_TIMBREAK SBS break lockup input timer peripherals + * @{ + */ +#define LL_SBS_TIMBREAK_PVD SBS_BKLOCKR_PVD_BL /*!< Connect the PVD output with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_FLASHECC SBS_BKLOCKR_FLASHECC_BL /*!< Connect the Flash ECC double error detection flag with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_CM7LCKUP SBS_BKLOCKR_CM7LCKUP_BL /*!< Connect the Cortex M7 lockup output with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_BKRAMECC SBS_BKLOCKR_BKRAMECC_BL /*!< Connect the Backup RAM ECC double error detection flag with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_DTCMECC SBS_BKLOCKR_DTCMECC_BL /*!< Connect the DTCM ECC double error detection flag with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_ITCMECC SBS_BKLOCKR_ITCMECC_BL /*!< Connect the ITCM ECC double error detection flag with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_ARAM3ECC SBS_BKLOCKR_ARAM3ECC_BL /*!< Connect the AXISRAM3 ECC double error detection flag with TIM1/15/16/17 break input */ +#define LL_SBS_TIMBREAK_ARAM1ECC SBS_BKLOCKR_ARAM1ECC_BL /*!< Connect the AXISRAM1 ECC double error detection flag with TIM1/15/16/17 break input */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_EXTI_PORT SBS EXTI PORT + * @{ + */ +#define LL_SBS_EXTI_PORTA 0U /*!< EXTI PORT A */ +#define LL_SBS_EXTI_PORTB SBS_EXTICR1_PC_EXTI0_0 /*!< EXTI PORT B */ +#define LL_SBS_EXTI_PORTC SBS_EXTICR1_PC_EXTI0_1 /*!< EXTI PORT C */ +#define LL_SBS_EXTI_PORTD (SBS_EXTICR1_PC_EXTI0_1 | SBS_EXTICR1_PC_EXTI0_0) /*!< EXTI PORT D */ +#define LL_SBS_EXTI_PORTE SBS_EXTICR1_PC_EXTI0_2 /*!< EXTI PORT E */ +#define LL_SBS_EXTI_PORTF (SBS_EXTICR1_PC_EXTI0_2 | SBS_EXTICR1_PC_EXTI0_0) /*!< EXTI PORT F */ +#define LL_SBS_EXTI_PORTG (SBS_EXTICR1_PC_EXTI0_2 | SBS_EXTICR1_PC_EXTI0_1) /*!< EXTI PORT G */ +#define LL_SBS_EXTI_PORTH (SBS_EXTICR1_PC_EXTI0_2 | SBS_EXTICR1_PC_EXTI0_1 | \ + SBS_EXTICR1_PC_EXTI0_0) /*!< EXTI PORT H */ +#define LL_SBS_EXTI_PORTM (SBS_EXTICR1_PC_EXTI0_3 | SBS_EXTICR1_PC_EXTI0_2) /*!< EXTI PORT M */ +#define LL_SBS_EXTI_PORTN (SBS_EXTICR1_PC_EXTI0_3 | SBS_EXTICR1_PC_EXTI0_2 | \ + SBS_EXTICR1_PC_EXTI0_0) /*!< EXTI PORT N */ +#define LL_SBS_EXTI_PORTO (SBS_EXTICR1_PC_EXTI0_3 | SBS_EXTICR1_PC_EXTI0_2 | \ + SBS_EXTICR1_PC_EXTI0_1) /*!< EXTI PORT 0 */ +#define LL_SBS_EXTI_PORTP (SBS_EXTICR1_PC_EXTI0_3 | SBS_EXTICR1_PC_EXTI0_2 | \ + SBS_EXTICR1_PC_EXTI0_1 | SBS_EXTICR1_PC_EXTI0_0) /*!< EXTI PORT P */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_SBS_EXTI_LINE SBS EXTI LINE + * @{ + */ +#define LL_SBS_EXTI_LINE0 ((0UL << LL_SBS_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_0 | EXTICR[0] */ +#define LL_SBS_EXTI_LINE1 ((4UL << LL_SBS_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_8 | EXTICR[0] */ +#define LL_SBS_EXTI_LINE2 ((8UL << LL_SBS_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_16 | EXTICR[0] */ +#define LL_SBS_EXTI_LINE3 ((12UL << LL_SBS_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_24 | EXTICR[0] */ +#define LL_SBS_EXTI_LINE4 ((0UL << LL_SBS_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_0 | EXTICR[1] */ +#define LL_SBS_EXTI_LINE5 ((4UL << LL_SBS_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_8 | EXTICR[1] */ +#define LL_SBS_EXTI_LINE6 ((8UL << LL_SBS_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_16 | EXTICR[1] */ +#define LL_SBS_EXTI_LINE7 ((12UL << LL_SBS_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_24 | EXTICR[1] */ +#define LL_SBS_EXTI_LINE8 ((0UL << LL_SBS_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_0 | EXTICR[2] */ +#define LL_SBS_EXTI_LINE9 ((4UL << LL_SBS_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_8 | EXTICR[2] */ +#define LL_SBS_EXTI_LINE10 ((8UL << LL_SBS_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_16 | EXTICR[2] */ +#define LL_SBS_EXTI_LINE11 ((12UL << LL_SBS_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_24 | EXTICR[2] */ +#define LL_SBS_EXTI_LINE12 ((0UL << LL_SBS_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_0 | EXTICR[3] */ +#define LL_SBS_EXTI_LINE13 ((4UL << LL_SBS_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_8 | EXTICR[3] */ +#define LL_SBS_EXTI_LINE14 ((8UL << LL_SBS_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_16 | EXTICR[3] */ +#define LL_SBS_EXTI_LINE15 ((12UL << LL_SBS_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_24 | EXTICR[3] */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_DBGMCU_DCRT DBGMCU Debug credential reset type + * @{ + */ +#define LL_DBGMCU_DCRT_SYSTEM 0U /*!< System reset revoke the debug authentication credentials */ +#define LL_DBGMCU_DCRT_POWER DBGMCU_CR_DCRT /*!< Power reset revoke the debug authentication credentials */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_DBGMCU_AHB5_STOP DBGMCU AHB5 GRP1 STOP + * @{ + */ +#define LL_DBGMCU_AHB5_GRP1_HPDMA0_STOP DBGMCU_AHB5FZR_HPDMA_0 /*!< The counter clock of HPDMA0 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA1_STOP DBGMCU_AHB5FZR_HPDMA_1 /*!< The counter clock of HPDMA1 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA2_STOP DBGMCU_AHB5FZR_HPDMA_2 /*!< The counter clock of HPDMA2 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA3_STOP DBGMCU_AHB5FZR_HPDMA_3 /*!< The counter clock of HPDMA3 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA4_STOP DBGMCU_AHB5FZR_HPDMA_4 /*!< The counter clock of HPDMA4 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA5_STOP DBGMCU_AHB5FZR_HPDMA_5 /*!< The counter clock of HPDMA5 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA6_STOP DBGMCU_AHB5FZR_HPDMA_6 /*!< The counter clock of HPDMA6 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA7_STOP DBGMCU_AHB5FZR_HPDMA_7 /*!< The counter clock of HPDMA7 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA8_STOP DBGMCU_AHB5FZR_HPDMA_8 /*!< The counter clock of HPDMA8 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA9_STOP DBGMCU_AHB5FZR_HPDMA_9 /*!< The counter clock of HPDMAM9 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA10_STOP DBGMCU_AHB5FZR_HPDMA_10 /*!< The counter clock of HPDMAM10 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA11_STOP DBGMCU_AHB5FZR_HPDMA_11 /*!< The counter clock of HPDMAM11 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA12_STOP DBGMCU_AHB5FZR_HPDMA_12 /*!< The counter clock of HPDMAM12 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA13_STOP DBGMCU_AHB5FZR_HPDMA_13 /*!< The counter clock of HPDMAM13 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA14_STOP DBGMCU_AHB5FZR_HPDMA_14 /*!< The counter clock of HPDMAM14 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB5_GRP1_HPDMA15_STOP DBGMCU_AHB5FZR_HPDMA_15 /*!< The counter clock of HPDMAM15 is stopped when the core is halted*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_DBGMCU_AHB1_STOP DBGMCU AHB1 GRP1 STOP + * @{ + */ +#define LL_DBGMCU_AHB1_GRP1_GPDMA0_STOP DBGMCU_AHB1FZR_GPDMA_0 /*!< The counter clock of GPDMA0 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA1_STOP DBGMCU_AHB1FZR_GPDMA_1 /*!< The counter clock of GPDMA1 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA2_STOP DBGMCU_AHB1FZR_GPDMA_2 /*!< The counter clock of GPDMA2 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA3_STOP DBGMCU_AHB1FZR_GPDMA_3 /*!< The counter clock of GPDMA3 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA4_STOP DBGMCU_AHB1FZR_GPDMA_4 /*!< The counter clock of GPDMA4 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA5_STOP DBGMCU_AHB1FZR_GPDMA_5 /*!< The counter clock of GPDMA5 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA6_STOP DBGMCU_AHB1FZR_GPDMA_6 /*!< The counter clock of GPDMA6 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA7_STOP DBGMCU_AHB1FZR_GPDMA_7 /*!< The counter clock of GPDMA7 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA8_STOP DBGMCU_AHB1FZR_GPDMA_8 /*!< The counter clock of GPDMA8 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA9_STOP DBGMCU_AHB1FZR_GPDMA_9 /*!< The counter clock of GPDMAM9 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA10_STOP DBGMCU_AHB1FZR_GPDMA_10 /*!< The counter clock of GPDMAM10 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA11_STOP DBGMCU_AHB1FZR_GPDMA_11 /*!< The counter clock of GPDMAM11 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA12_STOP DBGMCU_AHB1FZR_GPDMA_12 /*!< The counter clock of GPDMAM12 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA13_STOP DBGMCU_AHB1FZR_GPDMA_13 /*!< The counter clock of GPDMAM13 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA14_STOP DBGMCU_AHB1FZR_GPDMA_14 /*!< The counter clock of GPDMAM14 is stopped when the core is halted*/ +#define LL_DBGMCU_AHB1_GRP1_GPDMA15_STOP DBGMCU_AHB1FZR_GPDMA_15 /*!< The counter clock of GPDMAM15 is stopped when the core is halted*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_DBGMCU_APB1_STOP DBGMCU APB1 GRP1 STOP + * @{ + */ +#define LL_DBGMCU_APB1_GRP1_TIM2_STOP DBGMCU_APB1FZR_TIM2 /*!< The counter clock of TIM2 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM3_STOP DBGMCU_APB1FZR_TIM3 /*!< The counter clock of TIM3 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM4_STOP DBGMCU_APB1FZR_TIM4 /*!< The counter clock of TIM4 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM5_STOP DBGMCU_APB1FZR_TIM5 /*!< The counter clock of TIM5 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM6_STOP DBGMCU_APB1FZR_TIM6 /*!< The counter clock of TIM6 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM7_STOP DBGMCU_APB1FZR_TIM7 /*!< The counter clock of TIM7 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM12_STOP DBGMCU_APB1FZR_TIM12 /*!< The counter clock of TIM12 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM13_STOP DBGMCU_APB1FZR_TIM13 /*!< The counter clock of TIM13 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM14_STOP DBGMCU_APB1FZR_TIM14 /*!< The counter clock of TIM14 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_LPTIM1_STOP DBGMCU_APB1FZR_LPTIM1 /*!< The counter clock of LPTIM1 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_WWDG_STOP DBGMCU_APB1FZR_WWDG /*!< The window watchdog counter clock is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_APB1FZR_I2C1 /*!< The I2C1 SMBus timeout is frozen*/ +#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_APB1FZR_I2C2 /*!< The I2C2 SMBus timeout is frozen*/ +#define LL_DBGMCU_APB1_GRP1_I2C3_STOP DBGMCU_APB1FZR_I2C3 /*!< The I2C3 SMBus timeout is frozen*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_DBGMCU_APB2_STOP DBGMCU APB2 GRP1 STOP + * @{ + */ +#define LL_DBGMCU_APB2_GRP1_TIM1_STOP DBGMCU_APB2FZR_TIM1 /*!< The counter clock of TIM1 is stopped when the core is halted*/ +#define LL_DBGMCU_APB2_GRP1_TIM9_STOP DBGMCU_APB2FZR_TIM9 /*!< The counter clock of TIM9 is stopped when the core is halted*/ +#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZR_TIM15 /*!< The counter clock of TIM15 is stopped when the core is halted*/ +#define LL_DBGMCU_APB2_GRP1_TIM16_STOP DBGMCU_APB2FZR_TIM16 /*!< The counter clock of TIM16 is stopped when the core is halted*/ +#define LL_DBGMCU_APB2_GRP1_TIM17_STOP DBGMCU_APB2FZR_TIM17 /*!< The counter clock of TIM17 is stopped when the core is halted*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_DBGMCU_APB4_STOP DBGMCU APB4 GRP1 STOP + * @{ + */ +#define LL_DBGMCU_APB4_GRP1_LPTIM2_STOP DBGMCU_APB4FZR_LPTIM2 /*!< The counter clock of LPTIM2 is stopped when the core is halted*/ +#define LL_DBGMCU_APB4_GRP1_LPTIM3_STOP DBGMCU_APB4FZR_LPTIM3 /*!< The counter clock of LPTIM2 is stopped when the core is halted*/ +#define LL_DBGMCU_APB4_GRP1_LPTIM4_STOP DBGMCU_APB4FZR_LPTIM4 /*!< The counter clock of LPTIM4 is stopped when the core is halted*/ +#define LL_DBGMCU_APB4_GRP1_LPTIM5_STOP DBGMCU_APB4FZR_LPTIM5 /*!< The counter clock of LPTIM5 is stopped when the core is halted*/ +#define LL_DBGMCU_APB4_GRP1_IWDG_STOP DBGMCU_APB4FZR_IWDG /*!< The counter clock of IWDG is stopped when the core is halted*/ +#define LL_DBGMCU_APB4_GRP1_RTC_STOP DBGMCU_APB4FZR_RTC /*!< The counter clock of RTC is stopped when the core is halted*/ +/** + * @} + */ + + +#if defined(VREFBUF) +/** @defgroup SYSTEM_LL_EC_VOLTAGE VREFBUF VOLTAGE + * @{ + */ +#define LL_VREFBUF_VOLTAGE_SCALE0 VREFBUF_CSR_VRS_OUT1 /*!< Voltage reference scale 0 (VREF_OUT1) */ +#define LL_VREFBUF_VOLTAGE_SCALE1 VREFBUF_CSR_VRS_OUT2 /*!< Voltage reference scale 1 (VREF_OUT2) */ +#define LL_VREFBUF_VOLTAGE_SCALE2 VREFBUF_CSR_VRS_OUT3 /*!< Voltage reference scale 2 (VREF_OUT3) */ +#define LL_VREFBUF_VOLTAGE_SCALE3 VREFBUF_CSR_VRS_OUT4 /*!< Voltage reference scale 3 (VREF_OUT4) */ +/** + * @} + */ +#endif /* VREFBUF */ + +/** @defgroup SYSTEM_LL_EC_LATENCY FLASH LATENCY + * @{ + */ +#define LL_FLASH_LATENCY_0 0 /*!< FLASH Zero wait state */ +#define LL_FLASH_LATENCY_1 FLASH_ACR_LATENCY_0 /*!< FLASH One wait state */ +#define LL_FLASH_LATENCY_2 FLASH_ACR_LATENCY_1 /*!< FLASH Two wait states */ +#define LL_FLASH_LATENCY_3 (FLASH_ACR_LATENCY_1 | FLASH_ACR_LATENCY_0) /*!< FLASH Three wait states */ +#define LL_FLASH_LATENCY_4 FLASH_ACR_LATENCY_2 /*!< FLASH Four wait states */ +#define LL_FLASH_LATENCY_5 (FLASH_ACR_LATENCY_2 | FLASH_ACR_LATENCY_0) /*!< FLASH Five wait state */ +#define LL_FLASH_LATENCY_6 (FLASH_ACR_LATENCY_2 | FLASH_ACR_LATENCY_1) /*!< FLASH Six wait state */ +#define LL_FLASH_LATENCY_7 (FLASH_ACR_LATENCY_2 | FLASH_ACR_LATENCY_1 | FLASH_ACR_LATENCY_0) /*!< FLASH Seven wait states */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Exported_Functions SYSTEM Exported Functions + * @{ + */ + +/** @defgroup SYSTEM_LL_EF_SBS SBS + * @{ + */ + +/** + * @brief Get initial vector for Cortex-M7 + * @rmtoll SBS_BOOTSR INITVTOR LL_SBS_GetBootAddress + * @retval Returned value is the physical boot address used by the Cortex-M7 after reset + */ +__STATIC_INLINE uint32_t LL_SBS_GetBootAddress(void) +{ + return (uint32_t)(READ_BIT(SBS->BOOTSR, SBS_BOOTSR_INITVTOR)); +} + +/** + * @brief Increment hide protection level + * @rmtoll SBS_HDPLCR INCR_HDPL LL_SBS_IncrementHDPL + * @retval None + */ +__STATIC_INLINE void LL_SBS_IncrementHDPL(void) +{ + MODIFY_REG(SBS->HDPLCR, SBS_HDPLCR_INCR_HDPL, LL_SBS_HDPL_INCREMENT_VALUE); +} + +/** + * @brief Get current hide protection level + * @rmtoll SBS_HDPLSR HDPL LL_SBS_GetCurrentHDPL + * @retval Returned value is the current hide protection level of the device: + * @arg @ref LL_SBS_HDPL0 + * @arg @ref LL_SBS_HDPL1 + * @arg @ref LL_SBS_HDPL2 + * @arg @ref LL_SBS_HDPL3 + */ +__STATIC_INLINE uint32_t LL_SBS_GetCurrentHDPL(void) +{ + return (uint32_t)(READ_BIT(SBS->HDPLSR, SBS_HDPLSR_HDPL)); +} + +/** + * @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_HDPL1 + * @arg @ref LL_SBS_HDPL2 + * @arg @ref LL_SBS_HDPL3 + * @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_HDPL1 + * @arg @ref LL_SBS_HDPL2 + * @arg @ref LL_SBS_HDPL3 + */ +__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); +} + +/** + * @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 Unlock the debug configuration + * @rmtoll SBS_DBGLOCKR DBGCFG_LOCK LL_SBS_UnlockDebugConfig + * @retval None + */ +__STATIC_INLINE void LL_SBS_UnlockDebugConfig(void) +{ + MODIFY_REG(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK, LL_SBS_DBG_CONFIG_UNLOCK); +} + +/** + * @brief Check if the debug configuration is unlocked + * @rmtoll SBS_DBGLOCKR DBGCFG_LOCK LL_SBS_IsUnlockedDebugConfig + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsUnlockedDebugConfig(void) +{ + return ((READ_BIT(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK) == LL_SBS_DBG_CONFIG_UNLOCK) ? 1UL : 0UL); +} + +/** + * @brief Set the command to be passed to RSS + * @rmtoll SBS_RSSCMDR RSSCMD LL_SBS_SetRSSCmd + * @param Command This parameter can have a value between 0 and 0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetRSSCmd(uint32_t Command) +{ + MODIFY_REG(SBS->RSSCMDR, SBS_RSSCMDR_RSSCMD, Command); +} + +/** + * @brief Get the command which will be passed to RSS + * @rmtoll SBS_RSSCMDR RSSCMD LL_SBS_GetRSSCmd + * @retval Returned value is the command which will be passed to RSS (value between 0 and 0xFFFF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetRSSCmd(void) +{ + return (uint32_t)(READ_BIT(SBS->RSSCMDR, SBS_RSSCMDR_RSSCMD)); +} + +/** + * @brief Set the number of AXISRAM wait state (when ECC=0) + * @rmtoll SBS_PMCR AXISRAM_WS LL_SBS_SetAXISRAMWaitState + * @param WaitState This parameter can be one of the following values: + * @arg @ref LL_SBS_AXISRAM_NO_WS + * @arg @ref LL_SBS_AXISRAM_ONE_WS + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetAXISRAMWaitState(uint32_t WaitState) +{ + MODIFY_REG(SBS->PMCR, SBS_PMCR_AXISRAM_WS, WaitState); +} + +/** + * @brief Get the number of AXISRAM wait state (when ECC=0) + * @rmtoll SBS_PMCR AXISRAM_WS LL_SBS_GetAXISRAMWaitState + * @retval Returned value is the number of wait state when accessing AXISRAM: + * @arg @ref LL_SBS_AXISRAM_NO_WS + * @arg @ref LL_SBS_AXISRAM_ONE_WS + */ +__STATIC_INLINE uint32_t LL_SBS_GetAXISRAMWaitState(void) +{ + return (uint32_t)(READ_BIT(SBS->PMCR, SBS_PMCR_AXISRAM_WS)); +} + +/** + * @brief Configure the Ethernet PHY interface + * @rmtoll SBS_PMCR ETH_PHYSEL LL_SBS_SetEthernetPhy + * @param Interface This parameter can be one of the following values: + * @arg @ref LL_SBS_ETH_PHYSEL_GMII_MII + * @arg @ref LL_SBS_ETH_PHYSEL_RMII + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetEthernetPhy(uint32_t Interface) +{ + MODIFY_REG(SBS->PMCR, SBS_PMCR_ETH_PHYSEL, Interface); +} + +/** + * @brief Get the selected Ethernet PHY interface + * @rmtoll SBS_PMCR ETH_PHYSEL LL_SBS_GetEthernetPhy + * @retval Returned value is the selected Ethernet PHY interface: + * @arg @ref LL_SBS_ETH_PHYSEL_GMII_MII + * @arg @ref LL_SBS_ETH_PHYSEL_RMII + */ +__STATIC_INLINE uint32_t LL_SBS_GetEthernetPhy(void) +{ + return (uint32_t)(READ_BIT(SBS->PMCR, SBS_PMCR_ETH_PHYSEL)); +} + +/** + * @brief Configure the analog switch supply voltage for booster + * @rmtoll SBS_PMCR BOOSTVDDSEL LL_SBS_SetBoosterVoltage + * @param Voltage This parameter can be one of the following values: + * @arg @ref LL_SBS_BOOSTVDDSEL_VDDA + * @arg @ref LL_SBS_BOOSTVDDSEL_VDD + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetBoosterVoltage(uint32_t Voltage) +{ + MODIFY_REG(SBS->PMCR, SBS_PMCR_BOOSTVDDSEL, Voltage); +} + +/** + * @brief Get the selected analog switch supply voltage for booster + * @rmtoll SBS_PMCR BOOSTVDDSEL LL_SBS_GetBoosterVoltage + * @retval Returned value is the selected analog switch supply voltage: + * @arg @ref LL_SBS_BOOSTVDDSEL_VDDA + * @arg @ref LL_SBS_BOOSTVDDSEL_VDD + */ +__STATIC_INLINE uint32_t LL_SBS_GetBoosterVoltage(void) +{ + return (uint32_t)(READ_BIT(SBS->PMCR, SBS_PMCR_BOOSTVDDSEL)); +} + +/** + * @brief Enable the booster + * @rmtoll SBS_PMCR BOOSTEN LL_SBS_EnableBooster + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableBooster(void) +{ + SET_BIT(SBS->PMCR, SBS_PMCR_BOOSTEN); +} + +/** + * @brief Disable the booster + * @rmtoll SBS_PMCR BOOSTEN LL_SBS_DisableBooster + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableBooster(void) +{ + CLEAR_BIT(SBS->PMCR, SBS_PMCR_BOOSTEN); +} + +/** + * @brief Check if the booster is enabled + * @rmtoll SBS_PMCR BOOSTEN LL_SBS_IsEnabledBooster + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledBooster(void) +{ + return ((READ_BIT(SBS->PMCR, SBS_PMCR_BOOSTEN) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Enable Floating Point Unit Invalid operation Interrupt + * @rmtoll SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 SBS_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 Check if the automatic erase of BKPRAM and PKARAM memories are done + * @rmtoll SBS_MESR MEF LL_SBS_IsDoneMemoryErase + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsDoneMemoryErase(void) +{ + return (READ_BIT(SBS->MESR, SBS_MESR_MEF)); +} + +/** + * @brief Enable the XSPI2 speed optimization + * @rmtoll SBS_CCCSR XSPI2_IOHSLV LL_SBS_EnableXSPI2SpeedOptim + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableXSPI2SpeedOptim(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_IOHSLV); +} + +/** + * @brief Disable the XSPI2 speed optimization + * @rmtoll SBS_CCCSR XSPI2_IOHSLV LL_SBS_DisableXSPI2SpeedOptim + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableXSPI2SpeedOptim(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_IOHSLV); +} + +/** + * @brief Check if the XSPI2 speed optimization is enabled + * @rmtoll SBS_CCCSR XSPI2_IOHSLV LL_SBS_IsEnabledXSPI2SpeedOptim + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledXSPI2SpeedOptim(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_IOHSLV) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Enable the XSPI1 speed optimization + * @rmtoll SBS_CCCSR XSPI1_IOHSLV LL_SBS_EnableXSPI1SpeedOptim + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableXSPI1SpeedOptim(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_IOHSLV); +} + +/** + * @brief Disable the XSPI1 speed optimization + * @rmtoll SBS_CCCSR XSPI1_IOHSLV LL_SBS_DisableXSPI1SpeedOptim + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableXSPI1SpeedOptim(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_IOHSLV); +} + +/** + * @brief Check if the XSPI1 speed optimization is enabled + * @rmtoll SBS_CCCSR XSPI1_IOHSLV LL_SBS_IsEnabledXSPI1SpeedOptim + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledXSPI1SpeedOptim(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_IOHSLV) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Enable the I/O speed optimization + * @rmtoll SBS_CCCSR IOHSLV LL_SBS_EnableIOSpeedOptim + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIOSpeedOptim(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_IOHSLV); +} + +/** + * @brief Disable the I/O speed optimization + * @rmtoll SBS_CCCSR IOHSLV LL_SBS_DisableIOSpeedOptim + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIOSpeedOptim(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_IOHSLV); +} + +/** + * @brief Check if the I/O speed optimization is enabled + * @rmtoll SBS_CCCSR IOHSLV LL_SBS_IsEnabledIOSpeedOptim + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIOSpeedOptim(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_IOHSLV) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Check if the XSPI2 compensation cell is ready + * @rmtoll SBS_CCCSR XSPI2_COMP_RDY LL_SBS_IsReadyXSPI2CompCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsReadyXSPI2CompCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_COMP_RDY) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Check if the XSPI1 compensation cell is ready + * @rmtoll SBS_CCCSR XSPI1_COMP_RDY LL_SBS_IsReadyXSPI1CompCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsReadyXSPI1CompCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_COMP_RDY) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Check if the I/O compensation cell is ready + * @rmtoll SBS_CCCSR COMP_RDY LL_SBS_IsReadyIOCompCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsReadyIOCompCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_COMP_RDY) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Configure the code for the XSPI2 compensation cell + * @rmtoll SBS_CCCSR XSPI2_COMP_CODESEL LL_SBS_SetXSPI2CompCellCode + * @param Code This parameter can be one of the following values: + * @arg @ref LL_SBS_XSPI2_CODE_CELL + * @arg @ref LL_SBS_XSPI2_CODE_REG + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetXSPI2CompCellCode(uint32_t Code) +{ + MODIFY_REG(SBS->CCCSR, SBS_CCCSR_XSPI2_COMP_CODESEL, Code); +} + +/** + * @brief Get the selected code for the XSPI2 compensation cell + * @rmtoll SBS_CCCSR XSPI2_COMP_CODESEL LL_SBS_GetXSPI2CompCellCode + * @retval Returned value is the selected code for the XSPI2 compensation cell: + * @arg @ref LL_SBS_XSPI2_CODE_CELL + * @arg @ref LL_SBS_XSPI2_CODE_REG + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI2CompCellCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_COMP_CODESEL)); +} + +/** + * @brief Enable the XSPI2 compensation cell + * @rmtoll SBS_PMCR XSPI2_COMP_EN LL_SBS_EnableXSPI2CompCell + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableXSPI2CompCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_COMP_EN); +} + +/** + * @brief Disable the XSPI2 compensation cell + * @rmtoll SBS_CCCSR XSPI2_COMP_EN LL_SBS_DisableXSPI2CompCell + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableXSPI2CompCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_COMP_EN); +} + +/** + * @brief Check if the XSPI2 compensation cell is enabled + * @rmtoll SBS_CCCSR XSPI2_COMP_EN LL_SBS_IsEnabledXSPI2CompCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledXSPI2CompCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI2_COMP_EN) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Configure the code for the XSPI1 compensation cell + * @rmtoll SBS_CCCSR XSPI1_COMP_CODESEL LL_SBS_SetXSPI1CompCellCode + * @param Code This parameter can be one of the following values: + * @arg @ref LL_SBS_XSPI1_CODE_CELL + * @arg @ref LL_SBS_XSPI1_CODE_REG + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetXSPI1CompCellCode(uint32_t Code) +{ + MODIFY_REG(SBS->CCCSR, SBS_CCCSR_XSPI1_COMP_CODESEL, Code); +} + +/** + * @brief Get the selected code for the XSPI2 compensation cell + * @rmtoll SBS_CCCSR XSPI1_COMP_CODESEL LL_SBS_GetXSPI1CompCellCode + * @retval Returned value is the selected code for the XSPI1 compensation cell: + * @arg @ref LL_SBS_XSPI1_CODE_CELL + * @arg @ref LL_SBS_XSPI1_CODE_REG + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI1CompCellCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_COMP_CODESEL)); +} + +/** + * @brief Enable the XSPI1 compensation cell + * @rmtoll SBS_PMCR XSPI1_COMP_EN LL_SBS_EnableXSPI1CompCell + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableXSPI1CompCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_COMP_EN); +} + +/** + * @brief Disable the XSPI1 compensation cell + * @rmtoll SBS_CCCSR XSPI1_COMP_EN LL_SBS_DisableXSPI1CompCell + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableXSPI1CompCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_COMP_EN); +} + +/** + * @brief Check if the XSPI1 compensation cell is enabled + * @rmtoll SBS_CCCSR XSPI1_COMP_EN LL_SBS_IsEnabledXSPI1CompCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledXSPI1CompCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_XSPI1_COMP_EN) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Configure the code for the I/O compensation cell + * @rmtoll SBS_CCCSR COMP_CODESEL LL_SBS_SetIOCompCellCode + * @param Code This parameter can be one of the following values: + * @arg @ref LL_SBS_IO_CODE_CELL + * @arg @ref LL_SBS_IO_CODE_REG + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetIOCompCellCode(uint32_t Code) +{ + MODIFY_REG(SBS->CCCSR, SBS_CCCSR_COMP_CODESEL, Code); +} + +/** + * @brief Get the selected code for the I/O compensation cell + * @rmtoll SBS_CCCSR COMP_CODESEL LL_SBS_GetIOCompCellCode + * @retval Returned value is the selected code for the I/O compensation cell: + * @arg @ref LL_SBS_IO_CODE_CELL + * @arg @ref LL_SBS_IO_CODE_REG + */ +__STATIC_INLINE uint32_t LL_SBS_GetIOCompCellCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCCSR, SBS_CCCSR_COMP_CODESEL)); +} + +/** + * @brief Enable the I/O compensation cell + * @rmtoll SBS_PMCR COMP_EN LL_SBS_EnableIOCompCell + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIOCompCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_COMP_EN); +} + +/** + * @brief Disable the I/O compensation cell + * @rmtoll SBS_CCCSR COMP_EN LL_SBS_DisableIOCompCell + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIOCompCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_COMP_EN); +} + +/** + * @brief Check if the I/O compensation cell is enabled + * @rmtoll SBS_CCCSR COMP_EN LL_SBS_IsEnabledIOCompCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIOCompCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_COMP_EN) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Get the XSPI2 PMOS compensation + * @rmtoll SBS_CCVALR XSPI2_PSRC LL_SBS_GetXSPI2PmosComp + * @retval Returned value is the slew-rate compensation for XSPI2 PMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI2PmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCVALR, SBS_CCVALR_XSPI2_PSRC)) >> SBS_CCVALR_XSPI2_PSRC_Pos); +} + +/** + * @brief Get the XSPI2 NMOS compensation + * @rmtoll SBS_CCVALR XSPI2_NSRC LL_SBS_GetXSPI2NmosComp + * @retval Returned value is the slew-rate compensation for XSPI2 NMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI2NmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCVALR, SBS_CCVALR_XSPI2_NSRC)) >> SBS_CCVALR_XSPI2_NSRC_Pos); +} + +/** + * @brief Get the XSPI1 PMOS compensation + * @rmtoll SBS_CCVALR XSPI1_PSRC LL_SBS_GetXSPI1PmosComp + * @retval Returned value is the slew-rate compensation for XSPI1 PMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI1PmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCVALR, SBS_CCVALR_XSPI1_PSRC)) >> SBS_CCVALR_XSPI1_PSRC_Pos); +} + +/** + * @brief Get the XSPI NMOS compensation + * @rmtoll SBS_CCVALR XSPI1_NSRC LL_SBS_GetXSPI1NmosComp + * @retval Returned value is the slew-rate compensation for XSPI1 NMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI1NmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCVALR, SBS_CCVALR_XSPI1_NSRC)) >> SBS_CCVALR_XSPI1_NSRC_Pos); +} + +/** + * @brief Get the I/O PMOS compensation + * @rmtoll SBS_CCVALR PSRC LL_SBS_GetIOPmosComp + * @retval Returned value is the slew-rate compensation for I/O PMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetIOPmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCVALR, SBS_CCVALR_PSRC)) >> SBS_CCVALR_PSRC_Pos); +} + +/** + * @brief Get the I/O NMOS compensation + * @rmtoll SBS_CCVALR NSRC LL_SBS_GetIONmosComp + * @retval Returned value is the slew-rate compensation for I/O NMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetIONmosComp(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_NSRC)); +} + +/** + * @brief Set the XSPI2 software PMOS compensation + * @rmtoll SBS_CCSWVALR XSPI2_SW_PSRC LL_SBS_SetXSPI2SwPmosComp + * @param Compensation This parameter can have a value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetXSPI2SwPmosComp(uint32_t Compensation) +{ + MODIFY_REG(SBS->CCSWVALR, SBS_CCSWVALR_XSPI2_SW_PSRC, (Compensation << SBS_CCSWVALR_XSPI2_SW_PSRC_Pos)); +} + +/** + * @brief Get the XSPI2 PMOS compensation + * @rmtoll SBS_CCSWVALR XSPI2_SW_PSRC LL_SBS_GetXSPI2SwPmosComp + * @retval Returned value is the slew-rate compensation for XSPI2 PMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI2SwPmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCSWVALR, SBS_CCSWVALR_XSPI2_SW_PSRC)) >> SBS_CCSWVALR_XSPI2_SW_PSRC_Pos); +} + +/** + * @brief Set the XSPI2 software NMOS compensation + * @rmtoll SBS_CCSWVALR XSPI2_SW_NSRC LL_SBS_SetXSPI2SwNmosComp + * @param Compensation This parameter can have a value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetXSPI2SwNmosComp(uint32_t Compensation) +{ + MODIFY_REG(SBS->CCSWVALR, SBS_CCSWVALR_XSPI2_SW_NSRC, (Compensation << SBS_CCSWVALR_XSPI2_SW_NSRC_Pos)); +} + +/** + * @brief Get the XSPI2 software NMOS compensation + * @rmtoll SBS_CCSWVALR XSPI2_SW_NSRC LL_SBS_GetXSPI2SwNmosComp + * @retval Returned value is the slew-rate compensation for XSPI2 NMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI2SwNmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCSWVALR, SBS_CCSWVALR_XSPI2_SW_NSRC)) >> SBS_CCSWVALR_XSPI2_SW_NSRC_Pos); +} + +/** + * @brief Set the XSPI1 software PMOS compensation + * @rmtoll SBS_CCSWVALR XSPI2_SW_PSRC LL_SBS_SetXSPI1SwPmosComp + * @param Compensation This parameter can have a value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetXSPI1SwPmosComp(uint32_t Compensation) +{ + MODIFY_REG(SBS->CCSWVALR, SBS_CCSWVALR_XSPI1_SW_PSRC, (Compensation << SBS_CCSWVALR_XSPI1_SW_PSRC_Pos)); +} + +/** + * @brief Get the XSPI1 PMOS compensation + * @rmtoll SBS_CCSWVALR XSPI1_SW_PSRC LL_SBS_GetXSPI1SwPmosComp + * @retval Returned value is the slew-rate compensation for XSPI1 PMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI1SwPmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCSWVALR, SBS_CCSWVALR_XSPI1_SW_PSRC)) >> SBS_CCSWVALR_XSPI1_SW_PSRC_Pos); +} + +/** + * @brief Set the XSPI1 software NMOS compensation + * @rmtoll SBS_CCSWVALR XSPI1_SW_NSRC LL_SBS_SetXSPI1SwNmosComp + * @param Compensation This parameter can have a value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetXSPI1SwNmosComp(uint32_t Compensation) +{ + MODIFY_REG(SBS->CCSWVALR, SBS_CCSWVALR_XSPI1_SW_NSRC, (Compensation << SBS_CCSWVALR_XSPI1_SW_NSRC_Pos)); +} + +/** + * @brief Get the XSPI1 software NMOS compensation + * @rmtoll SBS_CCSWVALR XSPI1_SW_NSRC LL_SBS_GetXSPI1SwNmosComp + * @retval Returned value is the slew-rate compensation for XSPI1 NMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetXSPI1SwNmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCSWVALR, SBS_CCSWVALR_XSPI1_SW_NSRC)) >> SBS_CCSWVALR_XSPI1_SW_NSRC_Pos); +} + +/** + * @brief Set the I/O software PMOS compensation + * @rmtoll SBS_CCSWVALR SW_PSRC LL_SBS_SetIOSwPmosComp + * @param Compensation This parameter can have a value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetIOSwPmosComp(uint32_t Compensation) +{ + MODIFY_REG(SBS->CCSWVALR, SBS_CCSWVALR_SW_PSRC, (Compensation << SBS_CCSWVALR_SW_PSRC_Pos)); +} + +/** + * @brief Get the I/O PMOS compensation + * @rmtoll SBS_CCSWVALR SW_PSRC LL_SBS_GetIOSwPmosComp + * @retval Returned value is the slew-rate compensation for I/O PMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetIOSwPmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCSWVALR, SBS_CCSWVALR_SW_PSRC)) >> SBS_CCSWVALR_SW_PSRC_Pos); +} + +/** + * @brief Set the I/O software NMOS compensation + * @rmtoll SBS_CCSWVALR SW_NSRC LL_SBS_SetIOSwNmosComp + * @param Compensation This parameter can have a value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetIOSwNmosComp(uint32_t Compensation) +{ + MODIFY_REG(SBS->CCSWVALR, SBS_CCSWVALR_SW_NSRC, (Compensation << SBS_CCSWVALR_SW_NSRC_Pos)); +} + +/** + * @brief Get the I/O software NMOS compensation + * @rmtoll SBS_CCSWVALR SW_NSRC LL_SBS_GetIOSwNmosComp + * @retval Returned value is the slew-rate compensation for I/O NMOS transistors (value between 0 and 0xF) + */ +__STATIC_INLINE uint32_t LL_SBS_GetIOSwNmosComp(void) +{ + return (uint32_t)((READ_BIT(SBS->CCSWVALR, SBS_CCSWVALR_SW_NSRC)) >> SBS_CCSWVALR_SW_NSRC_Pos); +} + +/** + * @brief Set connections to TIM1/15/16/17 Break inputs + * @rmtoll SBS_BKLOCKR PVD_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR FLASHECC_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR CM7LCKUP_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR BKRAMECC_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR DTCMECC_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR ITCMECC_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR ARAM3ECC_BL LL_SBS_SetTIMBreakInputs\n + * SBS_BKLOCKR ARAM1ECC_BL LL_SBS_SetTIMBreakInputs + * @param Break This parameter can be a combination of the following values: + * @arg @ref LL_SBS_TIMBREAK_PVD + * @arg @ref LL_SBS_TIMBREAK_FLASHECC + * @arg @ref LL_SBS_TIMBREAK_CM7LCKUP + * @arg @ref LL_SBS_TIMBREAK_BKRAMECC + * @arg @ref LL_SBS_TIMBREAK_DTCMECC + * @arg @ref LL_SBS_TIMBREAK_ITCMECC + * @arg @ref LL_SBS_TIMBREAK_ARAM3ECC + * @arg @ref LL_SBS_TIMBREAK_ARAM1ECC + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetTIMBreakInputs(uint32_t Break) +{ + MODIFY_REG(SBS->BKLOCKR, + (SBS_BKLOCKR_PVD_BL | SBS_BKLOCKR_FLASHECC_BL | SBS_BKLOCKR_CM7LCKUP_BL | SBS_BKLOCKR_BKRAMECC_BL | \ + SBS_BKLOCKR_DTCMECC_BL | SBS_BKLOCKR_ITCMECC_BL | SBS_BKLOCKR_ARAM3ECC_BL | SBS_BKLOCKR_ARAM1ECC_BL) + , Break); +} + +/** + * @brief Get connections to TIM1/15/16/17 Break inputs + * @rmtoll SBS_BKLOCKR CLL LL_SBS_GetTIMBreakInputs\n + * SBS_BKLOCKR SPL LL_SBS_GetTIMBreakInputs\n + * SBS_BKLOCKR PVDL LL_SBS_GetTIMBreakInputs\n + * SBS_BKLOCKR ECCL LL_SBS_GetTIMBreakInputs + * @retval Returned value can be can be a combination of the following values: + * @arg @ref LL_SBS_TIMBREAK_PVD + * @arg @ref LL_SBS_TIMBREAK_FLASHECC + * @arg @ref LL_SBS_TIMBREAK_CM7LCKUP + * @arg @ref LL_SBS_TIMBREAK_BKRAMECC + * @arg @ref LL_SBS_TIMBREAK_DTCMECC + * @arg @ref LL_SBS_TIMBREAK_ITCMECC + * @arg @ref LL_SBS_TIMBREAK_ARAM3ECC + * @arg @ref LL_SBS_TIMBREAK_ARAM1ECC + */ +__STATIC_INLINE uint32_t LL_SBS_GetTIMBreakInputs(void) +{ + return (uint32_t)(READ_BIT(SBS->BKLOCKR, + (SBS_BKLOCKR_PVD_BL | SBS_BKLOCKR_FLASHECC_BL | SBS_BKLOCKR_CM7LCKUP_BL | \ + SBS_BKLOCKR_BKRAMECC_BL | SBS_BKLOCKR_DTCMECC_BL | SBS_BKLOCKR_ITCMECC_BL | \ + SBS_BKLOCKR_ARAM3ECC_BL | SBS_BKLOCKR_ARAM1ECC_BL))); +} + +/** + * @brief Configure source input for the EXTI external interrupt. + * @rmtoll SBS_EXTICR1 EXTI0 LL_SBS_SetEXTISource\n + * SBS_EXTICR1 EXTI1 LL_SBS_SetEXTISource\n + * SBS_EXTICR1 EXTI2 LL_SBS_SetEXTISource\n + * SBS_EXTICR1 EXTI3 LL_SBS_SetEXTISource\n + * SBS_EXTICR2 EXTI4 LL_SBS_SetEXTISource\n + * SBS_EXTICR2 EXTI5 LL_SBS_SetEXTISource\n + * SBS_EXTICR2 EXTI6 LL_SBS_SetEXTISource\n + * SBS_EXTICR2 EXTI7 LL_SBS_SetEXTISource\n + * SBS_EXTICR3 EXTI8 LL_SBS_SetEXTISource\n + * SBS_EXTICR3 EXTI9 LL_SBS_SetEXTISource\n + * SBS_EXTICR3 EXTI10 LL_SBS_SetEXTISource\n + * SBS_EXTICR3 EXTI11 LL_SBS_SetEXTISource\n + * SBS_EXTICR4 EXTI12 LL_SBS_SetEXTISource\n + * SBS_EXTICR4 EXTI13 LL_SBS_SetEXTISource\n + * SBS_EXTICR4 EXTI14 LL_SBS_SetEXTISource\n + * SBS_EXTICR4 EXTI15 LL_SBS_SetEXTISource + * @param Port This parameter can be one of the following values: + * @arg @ref LL_SBS_EXTI_PORTA + * @arg @ref LL_SBS_EXTI_PORTB + * @arg @ref LL_SBS_EXTI_PORTC + * @arg @ref LL_SBS_EXTI_PORTD + * @arg @ref LL_SBS_EXTI_PORTE + * @arg @ref LL_SBS_EXTI_PORTF + * @arg @ref LL_SBS_EXTI_PORTG + * @arg @ref LL_SBS_EXTI_PORTH + * @arg @ref LL_SBS_EXTI_PORTM + * @arg @ref LL_SBS_EXTI_PORTN + * @arg @ref LL_SBS_EXTI_PORTO + * @arg @ref LL_SBS_EXTI_PORTP + * + * (*) value not defined in all devices + * @param Line This parameter can be one of the following values: + * @arg @ref LL_SBS_EXTI_LINE0 + * @arg @ref LL_SBS_EXTI_LINE1 + * @arg @ref LL_SBS_EXTI_LINE2 + * @arg @ref LL_SBS_EXTI_LINE3 + * @arg @ref LL_SBS_EXTI_LINE4 + * @arg @ref LL_SBS_EXTI_LINE5 + * @arg @ref LL_SBS_EXTI_LINE6 + * @arg @ref LL_SBS_EXTI_LINE7 + * @arg @ref LL_SBS_EXTI_LINE8 + * @arg @ref LL_SBS_EXTI_LINE9 + * @arg @ref LL_SBS_EXTI_LINE10 + * @arg @ref LL_SBS_EXTI_LINE11 + * @arg @ref LL_SBS_EXTI_LINE12 + * @arg @ref LL_SBS_EXTI_LINE13 + * @arg @ref LL_SBS_EXTI_LINE14 + * @arg @ref LL_SBS_EXTI_LINE15 + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetEXTISource(uint32_t Port, uint32_t Line) +{ + MODIFY_REG(SBS->EXTICR[Line & 0x03U], + SBS_EXTICR1_PC_EXTI0 << (Line >> LL_SBS_REGISTER_PINPOS_SHFT), + Port << (Line >> LL_SBS_REGISTER_PINPOS_SHFT)); +} + +/** + * @brief Get the configured defined for specific EXTI Line + * @rmtoll SBS_EXTICR1 EXTI0 LL_SBS_GetEXTISource\n + * SBS_EXTICR1 EXTI1 LL_SBS_GetEXTISource\n + * SBS_EXTICR1 EXTI2 LL_SBS_GetEXTISource\n + * SBS_EXTICR1 EXTI3 LL_SBS_GetEXTISource\n + * SBS_EXTICR2 EXTI4 LL_SBS_GetEXTISource\n + * SBS_EXTICR2 EXTI5 LL_SBS_GetEXTISource\n + * SBS_EXTICR2 EXTI6 LL_SBS_GetEXTISource\n + * SBS_EXTICR2 EXTI7 LL_SBS_GetEXTISource\n + * SBS_EXTICR3 EXTI8 LL_SBS_GetEXTISource\n + * SBS_EXTICR3 EXTI9 LL_SBS_GetEXTISource\n + * SBS_EXTICR3 EXTI10 LL_SBS_GetEXTISource\n + * SBS_EXTICR3 EXTI11 LL_SBS_GetEXTISource\n + * SBS_EXTICR4 EXTI12 LL_SBS_GetEXTISource\n + * SBS_EXTICR4 EXTI13 LL_SBS_GetEXTISource\n + * SBS_EXTICR4 EXTI14 LL_SBS_GetEXTISource\n + * SBS_EXTICR4 EXTI15 LL_SBS_GetEXTISource + * @param Line This parameter can be one of the following values: + * @arg @ref LL_SBS_EXTI_LINE0 + * @arg @ref LL_SBS_EXTI_LINE1 + * @arg @ref LL_SBS_EXTI_LINE2 + * @arg @ref LL_SBS_EXTI_LINE3 + * @arg @ref LL_SBS_EXTI_LINE4 + * @arg @ref LL_SBS_EXTI_LINE5 + * @arg @ref LL_SBS_EXTI_LINE6 + * @arg @ref LL_SBS_EXTI_LINE7 + * @arg @ref LL_SBS_EXTI_LINE8 + * @arg @ref LL_SBS_EXTI_LINE9 + * @arg @ref LL_SBS_EXTI_LINE10 + * @arg @ref LL_SBS_EXTI_LINE11 + * @arg @ref LL_SBS_EXTI_LINE12 + * @arg @ref LL_SBS_EXTI_LINE13 + * @arg @ref LL_SBS_EXTI_LINE14 + * @arg @ref LL_SBS_EXTI_LINE15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_SBS_EXTI_PORTA + * @arg @ref LL_SBS_EXTI_PORTB + * @arg @ref LL_SBS_EXTI_PORTC + * @arg @ref LL_SBS_EXTI_PORTD + * @arg @ref LL_SBS_EXTI_PORTE + * @arg @ref LL_SBS_EXTI_PORTF + * @arg @ref LL_SBS_EXTI_PORTG + * @arg @ref LL_SBS_EXTI_PORTH + * @arg @ref LL_SBS_EXTI_PORTM + * @arg @ref LL_SBS_EXTI_PORTN + * @arg @ref LL_SBS_EXTI_PORTO + * @arg @ref LL_SBS_EXTI_PORTP + */ +__STATIC_INLINE uint32_t LL_SBS_GetEXTISource(uint32_t Line) +{ + return (uint32_t)(READ_BIT(SBS->EXTICR[Line & 0x03U], + (SBS_EXTICR1_PC_EXTI0 << (Line >> LL_SBS_REGISTER_PINPOS_SHFT))) >> (Line >> LL_SBS_REGISTER_PINPOS_SHFT)); +} + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EF_DBGMCU 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 sleep mode + * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_EnableDBGSleepMode + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableDBGSleepMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Disable the Debug Module during sleep mode + * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_DisableDBGSleepMode + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableDBGSleepMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Indicate if the Debug Module during sleep mode is enabled + * @rmtoll DBGMCU_CR DBG_SLEEP LL_DBGMCU_IsEnabledDBGSleepMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DBGMCU_IsEnabledDBGSleepMode(void) +{ + return ((READ_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP) == (DBGMCU_CR_DBG_SLEEP)) ? 1UL : 0UL); +} + +/** + * @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 Indicate if the Debug Module during STOP mode is enabled + * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_IsEnabledDBGStopMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DBGMCU_IsEnabledDBGStopMode(void) +{ + return ((READ_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP) == (DBGMCU_CR_DBG_STOP)) ? 1UL : 0UL); +} + +/** + * @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 Indicate if the Debug Module during STANDBY mode is enabled + * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_IsEnabledDBGStandbyMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DBGMCU_IsEnabledDBGStandbyMode(void) +{ + return ((READ_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY) == (DBGMCU_CR_DBG_STANDBY)) ? 1UL : 0UL); +} + +/** + * @brief Configure the debug credentials reset type + * @rmtoll DBGMCU_CR DCRT LL_DBGMCU_SetDbgCredentialResetType + * @param Type This parameter can be one of the following values: + * @arg @ref LL_DBGMCU_DCRT_SYSTEM + * @arg @ref LL_DBGMCU_DCRT_POWER + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_SetDbgCredentialResetType(uint32_t Type) +{ + MODIFY_REG(DBGMCU->CR, DBGMCU_CR_DCRT, Type); +} + +/** + * @brief Get the selected debug credentials reset type + * @rmtoll DBGMCU_CR DCRT LL_DBGMCU_GetDbgCredentialResetType + * @retval Returned value is the debug credentials reset type: + * @arg @ref LL_DBGMCU_DCRT_SYSTEM + * @arg @ref LL_DBGMCU_DCRT_POWER + */ +__STATIC_INLINE uint32_t LL_DBGMCU_GetDbgCredentialResetType(void) +{ + return (uint32_t)(READ_BIT(DBGMCU->CR, DBGMCU_CR_DCRT)); +} + +/** + * @brief Enable the clock for Trace port + * @rmtoll DBGMCU_CR TRACECLKEN LL_DBGMCU_EnableTraceClock + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableTraceClock(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_TRACECLKEN); +} + +/** + * @brief Disable the clock for Trace port + * @rmtoll DBGMCU_CR TRACECLKEN LL_DBGMCU_DisableTraceClock + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableTraceClock(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_TRACECLKEN); +} + +/** + * @brief Indicate if the clock for Trace port is enabled + * @rmtoll DBGMCU_CR TRACE_EN 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_TRACECLKEN) == (DBGMCU_CR_TRACECLKEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable the clock for debug port + * @rmtoll DBGMCU_CR D1DBGCKEN LL_DBGMCU_EnableDebugClock + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableDebugClock(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBGCKEN); +} + +/** + * @brief Disable the clock for debug port + * @rmtoll DBGMCU_CR D1DBGCKEN LL_DBGMCU_DisableDebugClock + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableDebugClock(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBGCKEN); +} + +/** + * @brief Indicate if the clock for debug port is enabled + * @rmtoll DBGMCU_CR D1DBGCKEN LL_DBGMCU_IsEnabledDebugClock + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DBGMCU_IsEnabledDebugClock(void) +{ + return ((READ_BIT(DBGMCU->CR, DBGMCU_CR_DBGCKEN) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Enable the external trigger output + * @rmtoll DBGMCU_CR TRGOEN LL_DBGMCU_EnableTriggerOutput + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableTriggerOutput(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_TRGOEN); +} + +/** + * @brief Disable the external trigger output + * @rmtoll DBGMCU_CR TRGOEN LL_DBGMCU_DisableTriggerOutput + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableTriggerOutput(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_TRGOEN); +} + +/** + * @brief Indicate if the external trigger output is enabled + * @rmtoll DBGMCU_CR TRGOEN LL_DBGMCU_IsEnabledTriggerOutput + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DBGMCU_IsEnabledTriggerOutput(void) +{ + return ((READ_BIT(DBGMCU->CR, DBGMCU_CR_TRGOEN) != 0UL) ? 1UL : 0UL); +} + +/** + * @brief Freeze APB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB1FZR 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_LPTIM1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C3_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->APB1FZR, Periphs); +} + +/** + * @brief UnFreeze APB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB1FZR 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_LPTIM1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C3_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->APB1FZR, Periphs); +} + +/** + * @brief Freeze APB4 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB4FZR DBG_xxxx_STOP LL_DBGMCU_APB4_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM2_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM3_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM4_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM5_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_RTC_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB4_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->APB4FZR, Periphs); +} + +/** + * @brief UnFreeze APB4 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB4FZR DBG_xxxx_STOP LL_DBGMCU_APB4_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM2_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM3_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM4_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_LPTIM5_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB4_GRP1_RTC_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB4_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->APB4FZR, Periphs); +} + +/** + * @brief freeze APB2 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB2FZR DBG_xxxx_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_TIM9_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_TIM9_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 AHB5 peripherals (group1 peripherals) + * @rmtoll DBGMCU_AHB5FZR DBG_xxxx_STOP LL_DBGMCU_AHB5_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA0_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA1_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA2_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA3_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA4_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA5_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA6_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA7_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA8_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA9_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA10_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA11_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA12_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA13_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA14_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA15_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_AHB5_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->AHB5FZR, Periphs); +} + +/** + * @brief Unfreeze AHB5 peripherals (group1 peripherals) + * @rmtoll DBGMCU_AHB5FZR DBG_xxxx_STOP LL_DBGMCU_AHB5_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA0_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA1_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA2_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA3_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA4_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA5_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA6_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA7_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA8_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA9_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA10_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA11_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA12_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA13_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA14_STOP + * @arg @ref LL_DBGMCU_AHB5_GRP1_HPDMA15_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_AHB5_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->AHB5FZR, Periphs); +} + +/** + * @brief freeze AHB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_AHB1FZR DBG_xxxx_STOP LL_DBGMCU_AHB1_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA0_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA1_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA2_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA3_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA4_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA5_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA6_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA7_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA8_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA9_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA10_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA11_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA12_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA13_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA14_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA15_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_AHB1_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->AHB1FZR, Periphs); +} + +/** + * @brief Unfreeze AHB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_AHB1FZR DBG_xxxx_STOP LL_DBGMCU_AHB1_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA0_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA1_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA2_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA3_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA4_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA5_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA6_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA7_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA8_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA9_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA10_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA11_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA12_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA13_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA14_STOP + * @arg @ref LL_DBGMCU_AHB1_GRP1_GPDMA15_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_AHB1_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->AHB1FZR, Periphs); +} + +/** + * @} + */ + +#if defined(VREFBUF) +/** @defgroup SYSTEM_LL_EF_VREFBUF 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_EF_FLASH 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 + * @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 + */ +__STATIC_INLINE uint32_t LL_FLASH_GetLatency(void) +{ + return (uint32_t)(READ_BIT(FLASH->ACR, FLASH_ACR_LATENCY)); +} + +/** + * @brief Unlock the Flash + * @rmtoll FLASH_KEYR CUKEY LL_FLASH_Unlock + * @retval None + */ +__STATIC_INLINE void LL_FLASH_Unlock(void) +{ + /* Unlock Flash */ + FLASH->KEYR = 0x45670123U; + FLASH->KEYR = 0xCDEF89ABU; +} + +/** + * @brief Lock the Flash + * @rmtoll FLASH_CR LOCK LL_FLASH_Lock + * @retval None + */ +__STATIC_INLINE void LL_FLASH_Lock(void) +{ + /* Lock Flash */ + SET_BIT(FLASH->CR, FLASH_CR_LOCK); +} + +/** + * @brief Check if Flash is locked + * @rmtoll FLASH_CR LOCK LL_FLASH_IsLocked + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FLASH_IsLocked(void) +{ + return ((READ_BIT(FLASH->CR, FLASH_CR_LOCK) == FLASH_CR_LOCK) ? 1UL : 0UL); +} + +/** + * @brief Unlock the Option Bytes update + * @rmtoll FLASH_OPTKEYR OCUKEY LL_FLASH_OptionBytes_Unlock + * @retval None + */ +__STATIC_INLINE void LL_FLASH_OptionBytes_Unlock(void) +{ + /* Unlock Option Bytes */ + FLASH->OPTKEYR = 0x08192A3BU; + FLASH->OPTKEYR = 0x4C5D6E7FU; +} + +/** + * @brief Lock the Option Bytes update + * @rmtoll FLASH_OPTCR OPTLOCK LL_FLASH_OptionBytes_Lock + * @retval None + */ +__STATIC_INLINE void LL_FLASH_OptionBytes_Lock(void) +{ + /* Lock option bytes */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK); +} + +/** + * @brief Check if Option Bytes update is locked + * @rmtoll FLASH_OPTCR OPTLOCK LL_FLASH_OptionBytes_IsLocked + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FLASH_OptionBytes_IsLocked(void) +{ + return ((READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) == FLASH_OPTCR_OPTLOCK) ? 1UL : 0UL); +} + +/** + * @brief Enable Option Bytes programming + * @rmtoll FLASH_OPTCR PG_OPT LL_FLASH_OptionBytes_EnableProg + * @retval None + */ +__STATIC_INLINE void LL_FLASH_OptionBytes_EnableProg(void) +{ + /* Set PG_OPT Bit */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); +} + +/** + * @brief Disable Option Bytes programming + * @rmtoll FLASH_OPTCR PG_OPT LL_FLASH_OptionBytes_DisableProg + * @retval None + */ +__STATIC_INLINE void LL_FLASH_OptionBytes_DisableProg(void) +{ + /* Clear PG_OPT Bit */ + CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); +} + +/** + * @brief Check if Option Bytes programming is enabled + * @rmtoll FLASH_OPTCR PG_OPT LL_FLASH_OptionBytes_IsEnabledProg + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FLASH_OptionBytes_IsEnabledProg(void) +{ + return ((READ_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT) == FLASH_OPTCR_PG_OPT) ? 1UL : 0UL); +} + +/** + * @brief Check if operation pending + * @rmtoll FLASH_SR QW LL_FLASH_IsPendingOperation + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FLASH_IsPendingOperation(void) +{ + return ((READ_BIT(FLASH->SR, FLASH_SR_QW) == FLASH_SR_QW) ? 1UL : 0UL); +} + +/** + * @brief Enable the I2C in Flash User Option bytes + * @rmtoll FLASH_OBW2SR I2C_NI3C LL_FLASH_OptionBytes_EnableI2C + * @retval None + */ +__STATIC_INLINE void LL_FLASH_OptionBytes_EnableI2C(void) +{ + /* Set I2C_N3C Bit */ + SET_BIT(FLASH->OBW2SRP, FLASH_OBW2SRP_I2C_NI3C); +} + +/** + * @brief Enable the I3C in Flash User Option bytes + * @rmtoll FLASH_OBW2SR I2C_NI3C LL_FLASH_OptionBytes_EnableI3C + * @retval None + */ +__STATIC_INLINE void LL_FLASH_OptionBytes_EnableI3C(void) +{ + /* Clear I2C_N3C Bit */ + CLEAR_BIT(FLASH->OBW2SRP, FLASH_OBW2SRP_I2C_NI3C); +} + +/** + * @brief Check if I2C is enabled in Flash User Option Bytes + * @rmtoll FLASH_OBW2SR I2C_NI3C LL_FLASH_OptionBytes_IsI2CEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FLASH_OptionBytes_IsI2CEnabled(void) +{ + return ((READ_BIT(FLASH->OBW2SR, FLASH_OBW2SR_I2C_NI3C) == FLASH_OBW2SR_I2C_NI3C) ? 1UL : 0UL); +} + +/** + * @brief Check if I3C is enabled in Flash User Option Bytes + * @rmtoll FLASH_OBW2SR I2C_NI3C LL_FLASH_OptionBytes_IsI3CEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FLASH_OptionBytes_IsI3CEnabled(void) +{ + return ((READ_BIT(FLASH->OBW2SR, FLASH_OBW2SR_I2C_NI3C) == 0U) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (FLASH) || defined (SBS) || defined (DBGMCU) || defined (VREFBUF) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_SYSTEM_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_utils.h b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_utils.h new file mode 100644 index 0000000..343ed14 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Inc/stm32h7rsxx_ll_utils.h @@ -0,0 +1,368 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_ll_utils.h + * @author MCD Application Team + * @brief Header file of UTILS LL 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. + * + ****************************************************************************** + @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 + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7RSxx_LL_UTILS_H +#define STM32H7RSxx_LL_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx.h" +#include "stm32h7rsxx_ll_system.h" +#include "stm32h7rsxx_ll_bus.h" +#include "stm32h7rsxx_ll_rcc.h" + +/** @addtogroup STM32H7RSxx_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 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 = 0 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_PLLVCORANGE + + 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 PLL output. + 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_SetSysPrescaler(). */ + + 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_LL_EC_AHB_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 APB4CLKDivider; /*!< The APB4 clock (PCLK4) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_LL_EC_APB4_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_SetAPB4Prescaler(). */ + + uint32_t APB5CLKDivider; /*!< The APB5 clock (PCLK5) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_LL_EC_APB5_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_SetAPB5Prescaler(). */ + +} 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 is enabled */ +/** + * @} + */ + +/** @defgroup UTILS_EC_PACKAGETYPE PACKAGE TYPE + * @{ + */ +#define LL_UTILS_PACKAGETYPE_VFQFPN68_GP 0U /*!< VFQFPN68 GP package type */ +#define LL_UTILS_PACKAGETYPE_TFBGA100_SMPS_GP 1U /*!< TFBGA100 SMPS GP package type */ +#define LL_UTILS_PACKAGETYPE_LQFP100_GP 2U /*!< LQFP100 GP package type */ +#define LL_UTILS_PACKAGETYPE_LQFP144_GP 3U /*!< LQFP144 GP package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA144_SMPS_GP 4U /*!< UFBGA144 SMPS GP package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA144_SMPS_GFX 5U /*!< UFBGA144 SMPS GFX package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA169_SMPS_GFX 6U /*!< UFBGA169 SMPS GFX package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA169_SMPS_GP 7U /*!< UFBGA169 SMPS GP package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA176_25_SMPS_GP 8U /*!< UFBGA176+25 SMPS GP package type */ +#define LL_UTILS_PACKAGETYPE_LQFP176_SMPS_GP 9U /*!< LQFP176 SMPS GP package type */ +#define LL_UTILS_PACKAGETYPE_LQFP176_SMPS_GFX 10U /*!< LQFP176 SMPS GFX package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA176_25_SMPS_GFX 11U /*!< UFBGA176+25 SMPS GFX package type */ +#define LL_UTILS_PACKAGETYPE_TFBGA225_OCTO 12U /*!< TFBGA225 OCTO package type */ +#define LL_UTILS_PACKAGETYPE_TFBGA225_HEXA 13U /*!< TFBGA225 HEXA package type */ +#define LL_UTILS_PACKAGETYPE_WLCSP_SMPS_GP 14U /*!< WLCSP SMPS GP 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) + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @retval UID[31:0] + */ +__STATIC_INLINE uint32_t LL_GetUID_Word0(void) +{ + return (uint32_t)(READ_REG(*((__IO uint32_t *)UID_BASE_ADDRESS))); +} + +/** + * @brief Get Word1 of the unique device identifier (UID based on 96 bits) + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @retval UID[63:32] + */ +__STATIC_INLINE uint32_t LL_GetUID_Word1(void) +{ + return (uint32_t)(READ_REG(*((__IO uint32_t *)(UID_BASE_ADDRESS + 4U)))); +} + +/** + * @brief Get Word2 of the unique device identifier (UID based on 96 bits) + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @retval UID[95:64] + */ +__STATIC_INLINE uint32_t LL_GetUID_Word2(void) +{ + return (uint32_t)(READ_REG(*((__IO uint32_t *)(UID_BASE_ADDRESS + 8U)))); +} + +/** + * @brief Get Package type + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @retval Returned value can be one of the following values: + * @arg @ref LL_UTILS_PACKAGETYPE_VFQFPN68_GP + * @arg @ref LL_UTILS_PACKAGETYPE_TFBGA100_SMPS_GP + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP100_GP + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP144_GP + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA144_SMPS_GP + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA144_SMPS_GFX + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA169_SMPS_GFX + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA169_SMPS_GP + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA176_25_SMPS_GP + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP176_SMPS_GP + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP176_SMPS_GFX + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA176_25_SMPS_GFX + * @arg @ref LL_UTILS_PACKAGETYPE_TFBGA225_OCTO + * @arg @ref LL_UTILS_PACKAGETYPE_TFBGA225_HEXA + * @arg @ref LL_UTILS_PACKAGETYPE_WLCSP_SMPS_GP + */ +__STATIC_INLINE uint32_t LL_GetPackageType(void) +{ + return (uint32_t)((READ_REG(*((__IO uint32_t *)PACKAGE_BASE_ADDRESS)) & 0x000F0000UL) >> 16UL); +} + +/** + * @} + */ + +/** @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) +{ + if (Ticks > 0U) + { + /* 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 CPU_Frequency); +void LL_mDelay(uint32_t Delay); + +/** + * @} + */ + +/** @defgroup UTILS_EF_SYSTEM SYSTEM + * @{ + */ + +void LL_SetSystemCoreClock(uint32_t CPU_Frequency); +ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency); +ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +ErrorStatus LL_PLL_ConfigSystemClock_CSI(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); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7RSxx_LL_UTILS_H */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/LICENSE.md b/Drivers/STM32H7RSxx_HAL_Driver/LICENSE.md new file mode 100644 index 0000000..c7f3b96 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/LICENSE.md @@ -0,0 +1,3 @@ +# Copyright (c) 2020 STMicroelectronics + +This software component is licensed by STMicroelectronics under the **BSD-3-Clause** license. You may not use this software except in compliance with this license. You may obtain a copy of the license [here](https://opensource.org/licenses/BSD-3-Clause). \ No newline at end of file diff --git a/Drivers/STM32H7RSxx_HAL_Driver/LICENSE.txt b/Drivers/STM32H7RSxx_HAL_Driver/LICENSE.txt new file mode 100644 index 0000000..3edc4d1 --- /dev/null +++ b/Drivers/STM32H7RSxx_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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c new file mode 100644 index 0000000..855ec2a --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c @@ -0,0 +1,1552 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal.c + * @author MCD Application Team + * @brief HAL module driver. + * This is the common part of the HAL initialization + * + ****************************************************************************** + * @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 ##### + ============================================================================== + [..] + 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 (Version, Init, Tick) + (+) Services HAL APIs (DBGMCU, SBS) + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup HAL HAL + * @brief HAL module driver + * @{ + */ + +#ifdef HAL_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +#define VREFBUF_TIMEOUT_VALUE (uint32_t)10 /* 10 ms */ + +/* 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 + +/* Mask for SBS_BKLOCKR register update */ +#define SBS_BKLOCKR_MASK (SBS_BKLOCKR_PVD_BL | \ + SBS_BKLOCKR_FLASHECC_BL | \ + SBS_BKLOCKR_CM7LCKUP_BL | \ + SBS_BKLOCKR_BKRAMECC_BL | \ + SBS_BKLOCKR_DTCMECC_BL | \ + SBS_BKLOCKR_ITCMECC_BL | \ + SBS_BKLOCKR_ARAM3ECC_BL | \ + SBS_BKLOCKR_ARAM1ECC_BL) + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup SBS_Private_Macros Private Macros + * @{ + */ +#define IS_SBS_TIMER_BREAK_INPUT(__VALUE__) \ + ((((__VALUE__) & SBS_BKLOCKR_MASK) != 0U) && \ + (((__VALUE__) & ~SBS_BKLOCKR_MASK) == 0U)) + +#define IS_SBS_IO_COMPENSATION_CODE(__VALUE__) \ + (((__VALUE__) == SBS_IO_CELL_CODE) || \ + ((__VALUE__) == SBS_IO_REGISTER_CODE)) + +#define IS_SBS_IO_COMPENSATION_CELL_PMOS_VALUE(__VALUE__) (((__VALUE__) < 16U)) +#define IS_SBS_IO_COMPENSATION_CELL_NMOS_VALUE(__VALUE__) (((__VALUE__) < 16U)) + +#define IS_SBS_ETHERNET_PHY(__VALUE__) \ + (((__VALUE__) == SBS_ETHERNET_PHY_GMII_OR_MII) || \ + ((__VALUE__) == SBS_ETHERNET_PHY_RMII)) + +#define IS_SBS_AXISRAM_WS(__VALUE__) \ + (((__VALUE__) == SBS_AXISRAM_WS_0) || \ + ((__VALUE__) == SBS_AXISRAM_WS_1)) +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/* Exported variables --------------------------------------------------------*/ + +/** @defgroup HAL_Exported_Variables HAL Exported Variables + * @{ + */ +__IO uint32_t uwTick; +uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid priority */ +HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ +/** + * @} + */ + +/* 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: + (+) Initialize the Flash interface the NVIC allocation and initial time base + clock configuration. + (+) De-initialize 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 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 + * stm32h7rsxx_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) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Set Interrupt Group Priority */ + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* Use SysTick as time base source and configure 1ms tick */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) + { + status = HAL_ERROR; + } + else + { + /* Init the low level hardware */ + HAL_MspInit(); + } + + /* Return function status */ + return status; +} + +/** + * @brief De-initialize common part of the HAL and stop the source of time base. + * @note 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_APB4_FORCE_RESET(); + __HAL_RCC_APB4_RELEASE_RESET(); + + __HAL_RCC_APB5_FORCE_RESET(); + __HAL_RCC_APB5_RELEASE_RESET(); + + __HAL_RCC_AHB1_FORCE_RESET(); + __HAL_RCC_AHB1_RELEASE_RESET(); + + __HAL_RCC_AHB2_FORCE_RESET(); + __HAL_RCC_AHB2_RELEASE_RESET(); + + __HAL_RCC_AHB3_FORCE_RESET(); + __HAL_RCC_AHB3_RELEASE_RESET(); + + __HAL_RCC_AHB4_FORCE_RESET(); + __HAL_RCC_AHB4_RELEASE_RESET(); + + __HAL_RCC_AHB5_FORCE_RESET(); + __HAL_RCC_AHB5_RELEASE_RESET(); + + /* De-Init the low level hardware */ + HAL_MspDeInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize 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 DeInitialize 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) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that doesn't take the value zero)*/ + if ((uint32_t)uwTickFreq != 0U) + { + /*Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / (uint32_t)uwTickFreq)) == 0U) + { + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_ERROR; + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_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 Provide 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. + * @param Freq tick frequency + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_TickFreqTypeDef prevTickFreq; + + 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 period to ensure 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 Return the HAL revision. + * @retval version : 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t HAL_GetHalVersion(void) +{ + return STM32H7RSXX_HAL_VERSION; +} + +/** + * @brief Return the device revision identifier. + * @retval Device revision identifier + */ +uint32_t HAL_GetREVID(void) +{ + return ((DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> DBGMCU_IDCODE_REV_ID_Pos); +} + +/** + * @brief Return 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) + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @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) + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @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) + * @note The read address belongs to an area which may contain virgin data generating + * double ECC error (as never programmed). Thus, in case of cache activation + * the address range 0x08FFF000-0x08FFFFFF should be defined as non-cacheable + * through the MPU. + * @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 SLEEP mode + (+) Enable/Disable Debug module during STOP mode + (+) Enable/Disable Debug module during STANDBY mode + +@endverbatim + * @{ + */ + +/** + * @brief Enable the Debug Module during SLEEP mode. + * @retval None + */ +void HAL_DBGMCU_EnableDBGSleepMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Disable the Debug Module during SLEEP mode. + * @retval None + */ +void HAL_DBGMCU_DisableDBGSleepMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @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 SBS configuration functions + * @brief HAL SBS configuration functions + * +@verbatim + =============================================================================== + ##### HAL SBS configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Increment/get the HDPL value + (+) Configure the debug access + (+) Configure timer break inputs + (+) Enable/Disable the I/O analog switch voltage booster + (+) Enable/Disable the I/O analog switch supplied by VDD + (+) Configure/Enable/Disable the compensation cell (IO, XSPI1, XSPI2) + +@endverbatim + * @{ + */ + +/** + * @brief Get the boot address holding the initial vector table for Cortex-M7. + * @retval Physical boot address used by the Cortex-M7 after reset + */ +uint32_t HAL_SBS_GetBootAddress(void) +{ + return SBS->BOOTSR; +} + +/** + * @brief Increment hise protection level. + * @retval None + */ +void HAL_SBS_IncrementHDPLValue(void) +{ + MODIFY_REG(SBS->HDPLCR, SBS_HDPLCR_INCR_HDPL, SBS_HDPL_INCREMENT_VALUE); +} + +/** + * @brief Get the current value of the hide protection level. + * @retval Current hide protection level + * This value is one of @ref SBS_HDPL_Value + */ +uint32_t HAL_SBS_GetHDPLValue(void) +{ + return (SBS->HDPLSR & SBS_HDPLSR_HDPL); +} + +/** + * @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, ((uint32_t)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 Unlock the access to the debug control register. + * @note This function can be only used when device state is Closed. + * @retval None + */ +void HAL_SBS_UnlockDebugConfig(void) +{ + MODIFY_REG(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK, SBS_DEBUG_UNLOCK_VALUE); +} + +/** + * @brief Lock the access to the debug control register. + * @note This function can be only used when device state is Closed. + * @retval None + */ +void HAL_SBS_LockDebugConfig(void) +{ + MODIFY_REG(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK, SBS_DEBUG_LOCK_VALUE); +} + +/** + * @brief Configure the command passed to the RSS for execution at next reset. + * @param Cmd Command passed to the RSS for execution at next reset + * This value is between 0 and 0xFFFF + * @retval None + */ +void HAL_SBS_ConfigRSSCommand(uint32_t Cmd) +{ + MODIFY_REG(SBS->RSSCMDR, SBS_RSSCMDR_RSSCMD, Cmd); +} + +/** + * @brief Get the command passed to the RSS for execution at next reset. + * @retval Command passed to the RSS for execution at next reset + */ +uint32_t HAL_SBS_GetRSSCommand(void) +{ + return (SBS->RSSCMDR & SBS_RSSCMDR_RSSCMD); +} + +/** + * @brief Enable the I/O analog switch voltage booster + * @note Insure low VDDA voltage operation with I/O analog switch control + * @retval None + */ +void HAL_SBS_EnableIOAnalogBooster(void) +{ + MODIFY_REG(SBS->PMCR, (SBS_PMCR_BOOSTEN | SBS_PMCR_BOOSTVDDSEL), SBS_PMCR_BOOSTEN); +} + +/** + * @brief Disable the I/O analog switch voltage booster + * @retval None + */ +void HAL_SBS_DisableIOAnalogBooster(void) +{ + CLEAR_BIT(SBS->PMCR, SBS_PMCR_BOOSTEN); +} + +/** + * @brief Enable the I/O analog switch supplied by VDD + * @note To be used when I/O analog switch voltage booster is not enabled + * @retval None + */ +void HAL_SBS_EnableIOAnalogSwitchVdd(void) +{ + MODIFY_REG(SBS->PMCR, (SBS_PMCR_BOOSTEN | SBS_PMCR_BOOSTVDDSEL), SBS_PMCR_BOOSTVDDSEL); +} + +/** + * @brief Disable the I/O analog switch supplied by VDD + * @retval None + */ +void HAL_SBS_DisableIOAnalogSwitchVdd(void) +{ + CLEAR_BIT(SBS->PMCR, SBS_PMCR_BOOSTVDDSEL); +} + +/** + * @brief Configure the Ethernet PHY interface + * @param Config specifies the Ethernet PHY interface + * This parameter can be one of the following values: + * @arg SBS_ETHERNET_PHY_GMII_OR_MII GMMI or MII selection + * @arg SBS_ETHERNET_PHY_RMII RMII selection + * @retval None + */ +void HAL_SBS_ConfigEthernetPHY(uint32_t Config) +{ + /* Check the parameter */ + assert_param(IS_SBS_ETHERNET_PHY(Config)); + + MODIFY_REG(SBS->PMCR, SBS_PMCR_ETH_PHYSEL, Config); +} + +/** + * @brief Configure the ECC AXISRAMs wait state when ECC=0 + * @param Config specifies the number of wait state + * This parameter can be one of the following values: + * @arg SBS_AXISRAM_WS_0 0 wait state selection + * @arg SBS_AXISRAM_WS_1 1 wait state selection + * @retval None + */ +void HAL_SBS_ConfigAXISRAMWaitState(uint32_t Config) +{ + /* Check the parameter */ + assert_param(IS_SBS_AXISRAM_WS(Config)); + + MODIFY_REG(SBS->PMCR, SBS_PMCR_AXISRAM_WS, Config); +} + +/** + * @brief Enable the compensation cell + * @param Selection specifies the concerned compensation cell + * This parameter can the combination of the following values: + * @arg SBS_IO_ANALOG_CELL Compensation cell for the I/O analog switches + * @arg SBS_IO_XSPI1_CELL Compensation cell for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_CELL Compensation cell for the I/O of the XSPI2 + * @retval None + */ +void HAL_SBS_EnableCompensationCell(uint32_t Selection) +{ + /* Check the parameter */ + assert_param(IS_SBS_COMPENSATION_CELL(Selection)); + + SET_BIT(SBS->CCCSR, Selection); +} + +/** + * @brief Disable the compensation cell + * @param Selection specifies the concerned compensation cell + * This parameter can the combination of the following values: + * @arg SBS_IO_ANALOG_CELL Compensation cell for the I/O analog switches + * @arg SBS_IO_XSPI1_CELL Compensation cell for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_CELL Compensation cell for the I/O of the XSPI2 + * @retval None + */ +void HAL_SBS_DisableCompensationCell(uint32_t Selection) +{ + /* Check the parameter */ + assert_param(IS_SBS_COMPENSATION_CELL(Selection)); + + MODIFY_REG(SBS->CCCSR, Selection, 0U); +} + +/** + * @brief Get the compensation cell ready status + * @param Selection specifies the concerned compensation cell + * This parameter can one of the following values: + * @arg SBS_IO_ANALOG_CELL_READY Compensation cell for the I/O analog switches + * @arg SBS_IO_XSPI1_CELL_READY Compensation cell for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_CELL_READY Compensation cell for the I/O of the XSPI2 + * @retval Ready status (1 or 0) + */ +uint32_t HAL_SBS_GetCompensationCellReadyStatus(uint32_t Selection) +{ + /* Check the parameter */ + assert_param(IS_SBS_COMPENSATION_CELL_READY(Selection)); + + return (((SBS->CCCSR & Selection) == 0U) ? 0UL : 1UL); +} + +/** + * @brief Configure the code selection for the compensation cell + * @param Selection specifies the concerned compensation cell + * This parameter can one of the following values: + * @arg SBS_IO_ANALOG_CELL Compensation cell for the I/O analog switches + * @arg SBS_IO_XSPI1_CELL Compensation cell for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_CELL Compensation cell for the I/O of the XSPI2 + * @param Code code selection to be applied for the I/O compensation cell + * This parameter can be one of the following values: + * @arg SBS_IO_CELL_CODE Code from the cell (available in the SBS_CCVALR) + * @arg SBS_IO_REGISTER_CODE Code from the compensation cell code register (SBS_CCSWVALR) + * @param NmosValue In case SBS_IO_REGISTER_CODE is selected, it provides the Nmos value + * to apply in range 0 to 15 else this parameter is not used + * @param PmosValue In case SBS_IO_REGISTER_CODE is selected, it provides the Pmos value + * to apply in range 0 to 15 else this parameter is not used + * @retval None + */ +void HAL_SBS_ConfigCompensationCell(uint32_t Selection, uint32_t Code, uint32_t NmosValue, uint32_t PmosValue) +{ + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_SBS_COMPENSATION_CELL(Selection)); + assert_param(IS_SBS_IO_COMPENSATION_CODE(Code)); + + if (Code == SBS_IO_REGISTER_CODE) + { + /* Check the parameters */ + assert_param(IS_SBS_IO_COMPENSATION_CELL_NMOS_VALUE(NmosValue)); + assert_param(IS_SBS_IO_COMPENSATION_CELL_PMOS_VALUE(PmosValue)); + + offset = ((Selection == SBS_IO_ANALOG_CELL) ? 0U : ((Selection == SBS_IO_XSPI1_CELL) ? 8U : 16U)); + + MODIFY_REG(SBS->CCSWVALR, (0xFFUL << offset), ((NmosValue << offset) | (PmosValue << (offset + 4U)))); + } + + MODIFY_REG(SBS->CCCSR, (Selection << 1U), (Code << (POSITION_VAL(Selection) + 1U))); +} + +/** + * @brief Get the code selection for the compensation cell + * @param Selection specifies the concerned compensation cell + * This parameter can one of the following values: + * @arg SBS_IO_ANALOG_CELL Compensation cell for the I/O analog switches + * @arg SBS_IO_XSPI1_CELL Compensation cell for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_CELL Compensation cell for the I/O of the XSPI2 + * @param pCode pointer code selection + * This parameter can be one of the following values: + * @arg SBS_IO_CELL_CODE Code from the cell (available in the SBS_CCVALR) + * @arg SBS_IO_REGISTER_CODE Code from the compensation cell code register (SBS_CCSWVALR) + * @param pNmosValue pointer to the Nmos value in range 0 to 15 + * @param pPmosValue pointer to the Pmos value in range 0 to 15 + * @retval HAL_OK (all values available) or HAL_ERROR (check parameters) + */ +HAL_StatusTypeDef HAL_SBS_GetCompensationCell(uint32_t Selection, uint32_t *pCode, uint32_t *pNmosValue, + uint32_t *pPmosValue) +{ + uint32_t reg; + uint32_t offset; + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check parameters */ + if ((pCode != NULL) && (pNmosValue != NULL) && (pPmosValue != NULL)) + { + *pCode = ((SBS->CCCSR & (Selection << 1U)) == 0U) ? SBS_IO_CELL_CODE : SBS_IO_REGISTER_CODE; + + reg = (*pCode == SBS_IO_CELL_CODE) ? (SBS->CCVALR) : (SBS->CCSWVALR); + offset = ((Selection == SBS_IO_ANALOG_CELL) ? 0U : ((Selection == SBS_IO_XSPI1_CELL) ? 8U : 16U)); + + *pNmosValue = ((reg >> offset) & 0xFU); + *pPmosValue = ((reg >> (offset + 4U)) & 0xFU); + + status = HAL_OK; + } + return status; +} + +/** + * @brief Enable the high speed at low voltage + * @param Selection specifies the concerned IOs + * This parameter can the combination of the following values: + * @arg SBS_IO_ANALOG_HSLV High speed at low voltage for the I/O analog switches + * @arg SBS_IO_XSPI1_HSLV High speed at low voltage for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_HSLV High speed at low voltage for the I/O of the XSPI2 + * @retval None + */ +void HAL_SBS_EnableIOSpeedOptimize(uint32_t Selection) +{ + /* Check the parameter */ + assert_param(IS_SBS_IOHSLV(Selection)); + + SET_BIT(SBS->CCCSR, Selection); +} + +/** + * @brief Disable the high speed at low voltage + * @param Selection specifies the concerned IOs + * This parameter can the combination of the following values: + * @arg SBS_IO_ANALOG_HSLV High speed at low voltage for the I/O analog switches + * @arg SBS_IO_XSPI1_HSLV High speed at low voltage for the I/O of the XSPI1 + * @arg SBS_IO_XSPI2_HSLV High speed at low voltage for the I/O of the XSPI2 + * @retval None + */ +void HAL_SBS_DisableIOSpeedOptimize(uint32_t Selection) +{ + /* Check the parameter */ + assert_param(IS_SBS_IOHSLV(Selection)); + + MODIFY_REG(SBS->CCCSR, Selection, 0U); +} + +/** + * @brief Configure the Timer Break input for error flag(s). + * @note When a configuration is set, only a system reset can reset it. + * @param Input input configuration + * This parameter can be one or a combinartion of the following values: + * @arg SBS_TIMER_BREAK_LOCK_PVD PVD flag + * @arg SBS_TIMER_BREAK_LOCK_FLASH FLASH double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_CORE M7 LOCKUP (Hardfault) output + * @arg SBS_TIMER_BREAK_LOCK_ITCM ITCM double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_DTCM DTCM double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_AXISRAM1 AXISRAM1 double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_AXISRAM3 AXISRAM3 double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_BKPRAM Backup SRAM double ECC error flag + * @retval None + */ +void HAL_SBS_ConfigTimerBreakInput(uint32_t Input) +{ + /* Check the parameter */ + assert_param(IS_SBS_TIMER_BREAK_INPUT(Input)); + + SET_BIT(SBS->BKLOCKR, Input); +} + +/** + * @brief Get the Timer Break input configuration. + * @note When a configuration is set, only a system reset can reset it. + * @retval Timer break input configuration + * This return value can be one or a combinartion of the following values: + * @arg SBS_TIMER_BREAK_LOCK_PVD PVD flag + * @arg SBS_TIMER_BREAK_LOCK_FLASH FLASH double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_CORE M7 LOCKUP (Hardfault) output + * @arg SBS_TIMER_BREAK_LOCK_ITCM ITCM double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_DTCM DTCM double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_AXISRAM1 AXISRAM1 double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_AXISRAM3 AXISRAM3 double ECC error flag + * @arg SBS_TIMER_BREAK_LOCK_BKPRAM Backup SRAM double ECC error flag + */ +uint32_t HAL_SBS_GetTimerBreakInputConfig(void) +{ + return (SBS->BKLOCKR & SBS_BKLOCKR_MASK); +} + +/** + * @brief Configure the source input used for EXTI. + * @param Exti EXTI event to be configured + * This parameter should be between 0 and 15 + * @param Port Port whom pin is used + * This parameter can be one of the following values: + * @arg SBS_EXTI_PIN_PORTA Port A pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTB Port B pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTC Port C pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTD Port D pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTE Port E pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTF Port F pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTG Port G pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTH Port H pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTM Port M pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTN Port N pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTO Port O pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTP Port P pin input of EXTI event detection + * @retval None + */ +void HAL_SBS_EXTIConfig(uint32_t Exti, uint32_t Port) +{ + uint32_t reg; + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_SBS_EXTI_INPUT(Exti)); + assert_param(IS_SBS_EXTI_PIN(Port)); + + reg = (Exti / 4U); + offset = (4U * (Exti % 4U)); + + MODIFY_REG(SBS->EXTICR[reg], (0xFUL << offset), (Port << offset)); +} + +/** + * @brief Get the source input used for EXTI. + * @param Exti EXTI configuration requested + * This parameter should be between 0 and 15 + * @retval Return value is port whom pin is used + * This return value can be one of the following values: + * @arg SBS_EXTI_PIN_PORTA Port A pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTB Port B pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTC Port C pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTD Port D pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTE Port E pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTF Port F pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTG Port G pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTH Port H pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTM Port M pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTN Port N pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTO Port O pin input of EXTI event detection + * @arg SBS_EXTI_PIN_PORTP Port P pin input of EXTI event detection + */ +uint32_t HAL_SBS_GetEXTIConfig(uint32_t Exti) +{ + uint32_t reg; + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_SBS_EXTI_INPUT(Exti)); + + reg = (Exti / 4U); + offset = (4U * (Exti % 4U)); + + return ((SBS->EXTICR[reg] & (0xFUL << offset)) >> offset); +} +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group5 VREFBUF Control functions + * @brief HAL Control functions + * +@verbatim + =============================================================================== + ##### HAL Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the internal voltage reference buffer voltage scale + (+) Configure the internal voltage reference buffer high impedance mode + (+) Tune the Internal Voltage Reference buffer + (+) Enable the Internal Voltage Reference buffer + (+) Disable the Internal Voltage Reference buffer + +@endverbatim + * @{ + */ + +/** + * @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_VREFBUF_Enable(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_VREFBUF_Disable(void) +{ + CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); +} +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group6 HAL AXIM configuration functions + * @brief HAL AXI Interconnect Matrix (AXIM) configuration functions + * +@verbatim + =============================================================================== + ##### HAL AXIM configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configures ASIB (AMBA slave interface blocks) and AMIB (AMBA master interface blocks) parameters, + such as the QoS (quality of service) level. +@endverbatim + * @{ + */ + +/** + * @brief Enable packing for ASIB. + * @note Normal operation, Enable packing of beats to match the output data width. + * @param AsibInstance specifies the ASIB to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_1 : ASIB 1 connected to AHB master + * @arg AXIM_ASIB_2 : ASIB 2 connected to SDMMC1 master + * @retval None + */ +void HAL_AXIM_ASIB_EnablePacking(AXIM_ASIB_TypeDef *AsibInstance) +{ + /* Check the parameters */ + assert_param(IS_AXIM_ASIB_ALL_INSTANCE(AsibInstance)); + + /* Apply packing configuration for the selected ASIB */ + WRITE_REG(AsibInstance->FNMOD2, 0U); +} + +/** + * @brief Disable packing for ASIB. + * @note Network does not perform any packing of beats to match the output data width. + * @note Unaligned transactions are not realigned to the input data word boundary. + * @param AsibInstance specifies the ASIB to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_1 : ASIB 1 connected to AHB master + * @arg AXIM_ASIB_2 : ASIB 2 connected to SDMMC1 master + * @retval None + */ +void HAL_AXIM_ASIB_DisablePacking(AXIM_ASIB_TypeDef *AsibInstance) +{ + /* Check the parameters */ + assert_param(IS_AXIM_ASIB_ALL_INSTANCE(AsibInstance)); + + /* Apply packing configuration for the selected ASIB */ + WRITE_REG(AsibInstance->FNMOD2, AXIM_ASIB_FNMOD2_BYPASS_MERGE); +} + +/** + * @brief Configure ASIB read/write issuing capability. + * @param AsibInstance specifies the ASIB to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_1 : ASIB 1 connected to AHB master + * @arg AXIM_ASIB_2 : ASIB 2 connected to SDMMC1 master + * @arg AXIM_ASIB_3 : ASIB 3 connected to HPDMA master + * @arg AXIM_ASIB_4 : ASIB 4 connected to C-M7 master + * @arg AXIM_ASIB_5 : ASIB 5 connected to GPU master + * @arg AXIM_ASIB_6 : ASIB 6 connected to GPU master + * @arg AXIM_ASIB_7 : ASIB 7 connected to GPU master + * @arg AXIM_ASIB_8 : ASIB 8 connected to DCMIPP master + * @arg AXIM_ASIB_9 : ASIB 9 connected to GFXMMU master + * @arg AXIM_ASIB_10 : ASIB 10 connected to LTDC master + * @arg AXIM_ASIB_11 : ASIB 11 connected to DMA2D master + * @param ReadIssuing specifies the Read issuing capability to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_READ_ISS_NORMAL : Normal issuing capability, default value. + * @arg AXIM_ASIB_READ_ISS_FORCE_TO_1: Force issuing capability to 1. + * @param WriteIssuing specifies the write issuing capability to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_WRITE_ISS_NORMAL : Normal issuing capability, default value. + * @arg AXIM_ASIB_WRITE_ISS_FORCE_TO_1: Force issuing capability to 1. + * @retval None + */ +void HAL_AXIM_ASIB_IssuingConfig(AXIM_ASIB_TypeDef *AsibInstance, uint32_t ReadIssuing, uint32_t WriteIssuing) +{ + /* Check the parameters */ + assert_param(IS_AXIM_ASIB_ALL_INSTANCE(AsibInstance)); + assert_param(IS_AXIM_ASIB_READ_ISS(ReadIssuing)); + assert_param(IS_AXIM_ASIB_WRITE_ISS(WriteIssuing)); + + /* Apply read/write issuing configuration for the selected ASIB */ + WRITE_REG(AsibInstance->FNMOD, (ReadIssuing | WriteIssuing)); +} + +/** + * @brief Configure ASIB read QOS priority. + * @param AsibInstance specifies the ASIB to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_1 : ASIB 1 connected to AHB master + * @arg AXIM_ASIB_2 : ASIB 2 connected to SDMMC1 master + * @arg AXIM_ASIB_3 : ASIB 3 connected to HPDMA master + * @arg AXIM_ASIB_4 : ASIB 4 connected to C-M7 master + * @arg AXIM_ASIB_5 : ASIB 5 connected to GPU master + * @arg AXIM_ASIB_6 : ASIB 6 connected to GPU master + * @arg AXIM_ASIB_7 : ASIB 7 connected to GPU master + * @arg AXIM_ASIB_8 : ASIB 8 connected to DCMIPP master + * @arg AXIM_ASIB_9 : ASIB 9 connected to GFXMMU master + * @arg AXIM_ASIB_10 : ASIB 10 connected to LTDC master + * @arg AXIM_ASIB_11 : ASIB 11 connected to DMA2D master + * @param QosPriority specifies read channel QoS setting + * This parameter can be a value between 0 to 15. + * With 0 value (default value) for the lowest priority and 15 value for Highest priority. + * @retval None + */ +void HAL_AXIM_ASIB_ReadQoSConfig(AXIM_ASIB_TypeDef *AsibInstance, uint32_t QosPriority) +{ + /* Check the parameters */ + assert_param(IS_AXIM_ASIB_ALL_INSTANCE(AsibInstance)); + assert_param(IS_AXIM_QOS(QosPriority)); + + /* Apply read QOS priority setting for the selected ASIB */ + WRITE_REG(AsibInstance->READQOS, QosPriority); +} + +/** + * @brief Configure ASIB write QOS priority. + * @param AsibInstance specifies the ASIB to configure + * This parameter can be one of the following values: + * @arg AXIM_ASIB_1 : ASIB 1 connected to AHB master + * @arg AXIM_ASIB_2 : ASIB 2 connected to SDMMC1 master + * @arg AXIM_ASIB_3 : ASIB 3 connected to HPDMA master + * @arg AXIM_ASIB_4 : ASIB 4 connected to C-M7 master + * @arg AXIM_ASIB_5 : ASIB 5 connected to GPU master + * @arg AXIM_ASIB_6 : ASIB 6 connected to GPU master + * @arg AXIM_ASIB_7 : ASIB 7 connected to GPU master + * @arg AXIM_ASIB_8 : ASIB 8 connected to DCMIPP master + * @arg AXIM_ASIB_9 : ASIB 9 connected to GFXMMU master + * @arg AXIM_ASIB_10 : ASIB 10 connected to LTDC master + * @arg AXIM_ASIB_11 : ASIB 11 connected to DMA2D master + * @param QosPriority specifies write channel QoS setting + * This parameter can be a value between 0 to 15. + * With 0 value (default value) for the lowest priority and 15 value for highest priority. + * + * @retval None + */ +void HAL_AXIM_ASIB_WriteQoSConfig(AXIM_ASIB_TypeDef *AsibInstance, uint32_t QosPriority) +{ + /* Check the parameters */ + assert_param(IS_AXIM_ASIB_ALL_INSTANCE(AsibInstance)); + assert_param(IS_AXIM_QOS(QosPriority)); + + /* Apply write QOS priority setting for the selected ASIB */ + WRITE_REG(AsibInstance->WRITEQOS, QosPriority); +} + +/** + * @brief Enable Packing for AMIB. + * @note Normal operation, Enable packing of beats to match the output data width. + * @param AmibInstance specifies the AMIB to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_2 : AMIB 2 connected to AHB Sram slave + * @retval None + */ +void HAL_AXIM_AMIB_EnablePacking(AXIM_AMIB_TypeDef *AmibInstance) +{ + /* Check the parameters */ + assert_param(IS_AXIM_AMIB_ALL_INSTANCE(AmibInstance)); + + /* Apply packing configuration for the selected AMIB */ + WRITE_REG(AmibInstance->FNMOD2, 0U); +} + +/** + * @brief Disable Packing for AMIB. + * @note Network does not perform any packing of beats to match the output data width. + * @note Unaligned transactions are not realigned to the input data word boundary. + * @param AmibInstance specifies the AMIB to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_2 : AMIB 2 connected to AHB Sram slave + * @retval None + */ +void HAL_AXIM_AMIB_DisablePacking(AXIM_AMIB_TypeDef *AmibInstance) +{ + /* Check the parameters */ + assert_param(IS_AXIM_AMIB_ALL_INSTANCE(AmibInstance)); + + /* Apply packing configuration for the selected AMIB */ + WRITE_REG(AmibInstance->FNMOD2, AXIM_AMIB_FNMOD2_BYPASS_MERGE); +} + +/** + * @brief Configure AMIB read/write issuing capability. + * @param AmibInstance specifies the AMIB to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_1 : AMIB 1 connected to GFXMMU slave + * @arg AXIM_AMIB_2 : AMIB 2 connected to AHB Sram slave + * @arg AXIM_AMIB_3 : AMIB 3 connected to FMC slave + * @arg AXIM_AMIB_4 : AMIB 4 connected to XSPI1 slave + * @arg AXIM_AMIB_5 : AMIB 5 connected to XSPI2 slave + * @arg AXIM_AMIB_6 : AMIB 6 connected to AXI SRAM4 slave + * @arg AXIM_AMIB_7 : AMIB 7 connected to AXI SRAM3 slave + * @arg AXIM_AMIB_8 : AMIB 8 connected to AXI SRAM2 slave + * @arg AXIM_AMIB_9 : AMIB 9 connected to AXI SRAM1 slave + * @arg AXIM_AMIB_10 : AMIB 10 connected to FLASH slave + * @param ReadIssuing specifies the Read issuing capability to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_READ_ISS_NORMAL : Normal issuing capability, default value. + * @arg AXIM_AMIB_READ_ISS_FORCE_TO_1: Force issuing capability to 1. + * @param WriteIssuing specifies the write issuing capability to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_WRITE_ISS_NORMAL : Normal issuing capability, default value. + * @arg AXIM_AMIB_WRITE_ISS_FORCE_TO_1: Force issuing capability to 1. + * @retval None + */ +void HAL_AXIM_AMIB_IssuingConfig(AXIM_AMIB_TypeDef *AmibInstance, uint32_t ReadIssuing, uint32_t WriteIssuing) +{ + /* Check the parameters */ + assert_param(IS_AXIM_AMIB_ALL_INSTANCE(AmibInstance)); + assert_param(IS_AXIM_AMIB_READ_ISS(ReadIssuing)); + assert_param(IS_AXIM_AMIB_WRITE_ISS(WriteIssuing)); + + /* Apply read/write issuing configuration for the selected AMIB */ + WRITE_REG(AmibInstance->FNMOD, (ReadIssuing | WriteIssuing)); +} + +/** + * @brief Configure AMIB read/write issuing bus matrix capability. + * @param AmibInstance specifies the AMIB to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_1 : AMIB 1 connected to GFXMMU slave + * @arg AXIM_AMIB_2 : AMIB 2 connected to AHB Sram slave + * @arg AXIM_AMIB_3 : AMIB 3 connected to FMC slave + * @arg AXIM_AMIB_4 : AMIB 4 connected to XSPI1 slave + * @arg AXIM_AMIB_5 : AMIB 5 connected to XSPI2 slave + * @arg AXIM_AMIB_6 : AMIB 6 connected to AXI SRAM4 slave + * @arg AXIM_AMIB_7 : AMIB 7 connected to AXI SRAM3 slave + * @arg AXIM_AMIB_8 : AMIB 8 connected to AXI SRAM2 slave + * @arg AXIM_AMIB_9 : AMIB 9 connected to AXI SRAM1 slave + * @arg AXIM_AMIB_10 : AMIB 10 connected to FLASH slave + * @param ReadIssuing specifies the Read issuing capability to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_READ_ISS_NORMAL : Normal issuing capability, default value. + * @arg AXIM_AMIB_READ_ISS_FORCE_TO_1: Force issuing capability to 1. + * @param WriteIssuing specifies the write issuing capability to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_WRITE_ISS_NORMAL : Normal issuing capability, default value. + * @arg AXIM_AMIB_WRITE_ISS_FORCE_TO_1: Force issuing capability to 1. + * @retval None + */ +void HAL_AXIM_AMIB_IssuingConfigBusMatrix(AXIM_AMIB_TypeDef *AmibInstance, uint32_t ReadIssuing, uint32_t WriteIssuing) +{ + /* Check the parameters */ + assert_param(IS_AXIM_AMIB_ALL_INSTANCE(AmibInstance)); + assert_param(IS_AXIM_AMIB_READ_ISS_BM(ReadIssuing)); + assert_param(IS_AXIM_AMIB_WRITE_ISS_BM(WriteIssuing)); + + /* Apply read/write issuing configuration for the selected AMIB */ + WRITE_REG(AmibInstance->FNMODBMISS, (ReadIssuing | WriteIssuing)); +} + +/** + * @brief Enable Long burst for AMIB. + * @note Long bursts can be generated at the output of the AMIB. + * @param AmibInstance specifies the AMIB to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_2 : AMIB 2 connected to AHB Sram slave + * @retval None + */ +void HAL_AXIM_AMIB_EnableLongBurst(AXIM_AMIB_TypeDef *AmibInstance) +{ + /* Check the parameters */ + assert_param(IS_AXIM_AMIB_ALL_INSTANCE(AmibInstance)); + + /* Apply Long burst configuration for the selected AMIB */ + WRITE_REG(AmibInstance->FNMODLB, AXIM_AMIB_FNMODLB_LONG_BURST); +} + +/** + * @brief Disable Long burst for AMIB. + * @note Long bursts can not be generated at the output of the AMIB. + * @param AmibInstance specifies the AMIB to configure + * This parameter can be one of the following values: + * @arg AXIM_AMIB_2 : AMIB 2 connected to AHB Sram slave + * @retval None + */ +void HAL_AXIM_AMIB_DisableLongBurst(AXIM_AMIB_TypeDef *AmibInstance) +{ + /* Check the parameters */ + assert_param(IS_AXIM_AMIB_ALL_INSTANCE(AmibInstance)); + + /* Apply Long burst configuration for the selected AMIB */ + WRITE_REG(AmibInstance->FNMODLB, 0U); +} +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group7 HAL FMC configuration functions + * @brief HAL FMC configuration functions + * +@verbatim + =============================================================================== + ##### HAL FMC configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the FMC Memory Bank Swapping mode + (+) Get current FMC Memory Bank Swapping Mode used +@endverbatim + * @{ + */ + +/** + * @brief Set the FMC Memory Bank Swapping mode. + * @param BankMapConfig specifies the FMC Memory Bank Swapping mode to configure + * This parameter can be one of the following values: + * @arg FMC_SWAPBANK_MODE0 : FMC memory default mapping is used + * @arg FMC_SWAPBANK_MODE1 : NOR/SRAM/PSRAM bank and SDRAM bank1 are swapped + * @note FMC bank mapping options + * | Start-End address | FMC_SWAPBANK_MODE0 | FMC_SWAPBANK_MODE1 | + * |-----------------------|---------------------|-----------------------| + * | 0x60000000-0x6FFFFFFF | NOR/SRAM/PSRAM bank | SDRAM bank1 | + * | 0x70000000-0x7FFFFFFF | Not used by FMC | + * | 0x80000000-0x8FFFFFFF | NAND bank | NAND bank | + * | 0x90000000-0x9FFFFFFF | Not used by FMC | + * | 0xC0000000-0xCFFFFFFF | SDRAM bank1 | NOR/SRAM/PSRAM bank | + * | 0xD0000000-0xDFFFFFFF | SDRAM bank2 | SDRAM bank2 | + * @retval None + */ +void HAL_FMC_SetBankSwapConfig(uint32_t BankMapConfig) +{ + /* Check the parameter */ + assert_param(IS_FMC_SWAPBANK_MODE(BankMapConfig)); + + /* Apply Memory Bank Swapping configuration */ + MODIFY_REG(FMC_Bank1_R->BTCR[0], FMC_BCR1_BMAP, BankMapConfig); +} + +/** + * @brief Get the FMC Memory Bank Swapping mode. + * @retval Return value is FMC Memory Bank Swapping mode + * This return value can be one of the following values: + * @arg FMC_SWAPBANK_MODE0 : FMC memory default mapping is used + * @arg FMC_SWAPBANK_MODE1 : NOR/SRAM/PSRAM bank and SDRAM bank1 are swapped + */ +uint32_t HAL_FMC_GetBankSwapConfig(void) +{ + return READ_BIT(FMC_Bank1_R->BTCR[0], FMC_BCR1_BMAP); +} +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c new file mode 100644 index 0000000..ef80238 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c @@ -0,0 +1,569 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + ============================================================================== + + [..] + *** How to configure Interrupts using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to configure the NVIC interrupts (IRQ). + The Cortex-M7 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 stm32h7rsxx_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 + + @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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup CORTEX + * @brief CORTEX HAL module driver + * @{ + */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup CORTEX_Exported_Functions + * @{ + */ + + +/** @addtogroup CORTEX_Exported_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions allowing to configure Interrupts + SysTick 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 (stm32h7rsxxxx.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_PRIO_INTERRUPT(IRQn)); + prioritygroup = NVIC_GetPriorityGrouping(); + assert_param(IS_NVIC_SUB_PRIORITY(SubPriority, prioritygroup)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority, prioritygroup)); + + 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 (stm32h7rsxxxx.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 (stm32h7rsxxxx.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 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); +} +/** + * @} + */ + +/** @addtogroup CORTEX_Exported_Functions_Group2 + * @brief Cortex control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the CORTEX + (NVIC, SYSTICK, MPU) functionalities. + + +@endverbatim + * @{ + */ + +/** + * @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 (stm32h7rsxxxx.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 *pPreemptPriority, uint32_t *pSubPriority) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIO_INTERRUPT(IRQn)); + 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 (stm32h7rsxxxx.h)) + * @retval None + */ +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(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 (stm32h7rsxxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(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 (stm32h7rsxxxx.h)) + * @retval None + */ +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(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 (stm32h7rsxxxx.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); +} + +/** + * @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_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)); + + MODIFY_REG(SysTick->CTRL, SysTick_CTRL_CLKSOURCE_Msk, CLKSource); +} + +/** + * @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 + */ +} + +/** + * @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) +{ + /* Force any outstanding transfers to complete before enabling MPU */ + __DMB(); + + /* Enable the MPU */ + MPU->CTRL = (MPU_Control | MPU_CTRL_ENABLE_Msk); + + /* Enable fault exceptions */ + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + /* Ensure MPU setting take effects */ + __DSB(); + __ISB(); +} + +/** + * @brief Disable the MPU. + * @retval None + */ +void HAL_MPU_Disable(void) +{ + /* Force any outstanding transfers to complete before disabling MPU */ + __DMB(); + + /* Disable fault exceptions */ + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; + + /* Disable the MPU and clear the control register */ + MPU->CTRL = 0U; + + /* Ensure MPU setting take effects */ + __DSB(); + __ISB(); +} + +/** + * @brief Enable the MPU Region. + * @retval None + */ +void HAL_MPU_EnableRegion(uint32_t RegionNumber) +{ + /* Check the parameters */ + assert_param(IS_MPU_REGION_NUMBER(RegionNumber)); + + /* Set the Region number */ + MPU->RNR = RegionNumber; + + /* Enable the Region */ + SET_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk); +} + +/** + * @brief Disable the MPU Region. + * @retval None + */ +void HAL_MPU_DisableRegion(uint32_t RegionNumber) +{ + /* Check the parameters */ + assert_param(IS_MPU_REGION_NUMBER(RegionNumber)); + + /* Set the Region number */ + MPU->RNR = RegionNumber; + + /* Disable the Region */ + CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk); +} + +/** + * @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. + * @note The region base address must be aligned to the size of the region. + * @retval None + */ +void HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef *pMPU_RegionInit) +{ + /* Check the parameters */ + assert_param(IS_MPU_REGION_NUMBER(pMPU_RegionInit->Number)); + assert_param(IS_MPU_REGION_ENABLE(pMPU_RegionInit->Enable)); + + /* Set the Region number */ + MPU->RNR = pMPU_RegionInit->Number; + + /* 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_TEX_LEVEL(pMPU_RegionInit->TypeExtField)); + assert_param(IS_MPU_ACCESS_SHAREABLE(pMPU_RegionInit->IsShareable)); + assert_param(IS_MPU_ACCESS_CACHEABLE(pMPU_RegionInit->IsCacheable)); + assert_param(IS_MPU_ACCESS_BUFFERABLE(pMPU_RegionInit->IsBufferable)); + assert_param(IS_MPU_SUB_REGION_DISABLE(pMPU_RegionInit->SubRegionDisable)); + assert_param(IS_MPU_REGION_SIZE(pMPU_RegionInit->Size)); + assert_param(IS_MPU_ADDRESS_MULTIPLE_SIZE(pMPU_RegionInit->BaseAddress, pMPU_RegionInit->Size)); + + /* Disable the Region */ + CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk); + + /* Disable the Region */ + CLEAR_BIT(MPU->RASR, MPU_RASR_ENABLE_Msk); + MPU->RBAR = pMPU_RegionInit->BaseAddress; + MPU->RASR = ((uint32_t)pMPU_RegionInit->DisableExec << MPU_RASR_XN_Pos) | + ((uint32_t)pMPU_RegionInit->AccessPermission << MPU_RASR_AP_Pos) | + ((uint32_t)pMPU_RegionInit->TypeExtField << MPU_RASR_TEX_Pos) | + ((uint32_t)pMPU_RegionInit->IsShareable << MPU_RASR_S_Pos) | + ((uint32_t)pMPU_RegionInit->IsCacheable << MPU_RASR_C_Pos) | + ((uint32_t)pMPU_RegionInit->IsBufferable << MPU_RASR_B_Pos) | + ((uint32_t)pMPU_RegionInit->SubRegionDisable << MPU_RASR_SRD_Pos) | + ((uint32_t)pMPU_RegionInit->Size << MPU_RASR_SIZE_Pos) | + ((uint32_t)pMPU_RegionInit->Enable << MPU_RASR_ENABLE_Pos); +} + +/** + * @brief Clear pending events. + * @retval None + */ +void HAL_CORTEX_ClearEvent(void) +{ + __SEV(); + __WFE(); +} +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CORTEX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c new file mode 100644 index 0000000..ea2b166 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c @@ -0,0 +1,520 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + =============================================================================== + [..] + (+) 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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_REG(hcrc->Instance->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 */ + } + else 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; + } + else 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 */ + } + else + { + /* Nothing to do */ + } + } + + /* 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c new file mode 100644 index 0000000..1b988bb --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c @@ -0,0 +1,230 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### +================================================================================ + [..] + (+) Set user-defined generating polynomial through HAL_CRCEx_Polynomial_Set() + (+) Configure Input or Output data inversion + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c new file mode 100644 index 0000000..8b771b0 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c @@ -0,0 +1,1755 @@ +/** + ********************************************************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + ====================================================================================================================== + [..] + (#) GPDMA and HPDMA are made available on this series. + Transfer could be done thanks to AXI or AHB ports. + + HPDMA support transmission through: + AXI port 0. + AHB port 1. + GPDMA allows transmission through: + GPDMA_P = port-0. + GPDMA_M = port-1 + + The following table list the supported configurations for HPDMA. + HPDMA support the following transfer + Table 1. HPDMA: supported transfer with source (SAP in CTR1 register) + / (DAP in CTR1 register) destination settings. + +-----------------------------------------------------------------------+ + | Destination|0 1 2 3 | 4 5 | 6 | 7 | 8 | 9 | + | Source | | | | | | | + |-----------------|--------|--------|--------|--------|--------|--------| + | 0 1 2 3 |0/0 |0/0-1 |0/0-1 |0/1 |0/0 |0/1 | + |-----------------|--------|--------|--------|--------|--------|--------| + | 4 5 |0-1/0 |0-1/0-1 |0-1/0-1 |0-1/1 |0-1/0 |0-1/1 | + +-----------------------------------------------------------------------+ + | 6 |0-1/0 |0-1/0-1 |0-1/0-1 |0-1/1 |0-1/0 |0-1/1 | + +-----------------------------------------------------------------------+ + | 7 |1/0 |1/0-1 |1/0-1 |1/1 |1/0 |1/1 | + +-----------------------------------------------------------------------+ + | 8 9 |0/0 |0/0-1 |0/0-1 |0/1 |0/0 |0/1 | + +-----------------------------------------------------------------------+ + | 10 11 |1/0 |1/0-1 |1/0-1 |1/1 |1/0 |1/1 | + +-----------------------------------------------------------------------+ + + Source: + 0 AXI_SRAM_IC1_L1 + 1 AXI_SRAM_IC2_L2 + 2 AXI_SRAM_IC3_L3 + 3 AXI_SRAM_IC4_L4 + 4 AHB_SRAM1_IC2_L0 + 5 AHB_SRAM2_IC2_L1 + 6 BACKUP_SRAM + 7 DTCM + 8 FLASH_IC1_L0 + 9 GFXMMU_RAM + 10 FDCAN_SRAM + 11 ITCM + + Destination: + 0 AXI_SRAM_IC1_L1 + 1 AXI_SRAM_IC2_L2 + 2 AXI_SRAM_IC3_L3 + 3 AXI_SRAM_IC4_L4 + 4 AHB_SRAM1_IC2_L0 + 5 AHB_SRAM2_IC2_L1 + 6 BACKUP_SRAM + 7 DTCM + 8 GFXMMU_RAM + 9 FDCAN_SRAM + + The following table list the supported configurations for GPDMA. + GPDMA support the following transfer + Table 2. GPDMA: supported transfer with source (SAP in CTR1 register) + / (DAP in CTR1 register) destination settings. + +-----------------------------------------------------------------------+ + | Destination|0 1 2 3 | 4 5 | 6 | 7 | 8 | 9 | + | Source | | | | | | | + |-----------------|--------|--------|--------|--------|--------|--------| + | 0 1 2 3 |0-1/0 |0-1/0-1 |0-1/0-1 | XXX | XXX |0-1/0-1 | + |-----------------|--------|--------|--------|--------|--------|--------| + | 4 5 |0-1/0 |0-1/0-1 |0-1/0-1 | XXX | XXX |0-1/0-1 | + +-----------------------------------------------------------------------+ + | 6 |0-1/0 |0-1/0-1 |0-1/0-1 | XXX | XXX |0-1/0-1 | + +-----------------------------------------------------------------------+ + | 7 | XXX | XXX | XXX | XXX | XXX | XXX | + +-----------------------------------------------------------------------+ + | 8 |0-1/0 |0-1/0-1 |0-1/0-1 | XXX | XXX |0-1/0-1 | + +-----------------------------------------------------------------------+ + | 9 | XXX | XXX | XXX | XXX | XXX | XXX | + +-----------------------------------------------------------------------+ + | 10 |0-1/0 |0-1/0-1 |0-1/0-1 | XXX | XXX |0-1/0-1 | + +-----------------------------------------------------------------------+ + | 11 | XXX | XXX | XXX | XXX | XXX | XXX | + +-----------------------------------------------------------------------+ + + Link-list transfer requires the nodes to be located in a memory than be be + accessed by the HPDMA or GPDMA. + + Table 3. HPDMA: supported linked-list node memory location versus Linked-List + allocated port (LPA in CCR register). + +--------------------------+ + | | Port | + | Node location | | + |-----------------|--------| + | 0 1 2 3 | 0 | + |-----------------|--------| + | 4 5 | 0-1 | + +--------------------------- + | 6 | 0-1 | + +--------------------------- + | 7 | 1 | + +--------------------------- + | 8 9 | 0 | + +--------------------------- + | 10 11 | 1 | + +--------------------------+ + + Table 4. GPDMA: supported linked-list node memory location versus Linked-List + allocated port (LPA in CCR register). + +--------------------------+ + | | Port | + | Node location | | + |-----------------|--------| + | 0 1 2 3 | 0-1 | + |-----------------|--------| + | 4 5 | 0-1 | + +--------------------------- + | 6 | 0-1 | + +--------------------------- + | 7 | XXX | + +--------------------------- + | 8 | 0-1 | + +--------------------------- + | 9 | XXX | + +--------------------------- + | 10 | 0-1 | + +--------------------------- + | 11 | XXX | + +--------------------------+ + + + When the HPDMA is used with the following peripherals: JPEG, XSPI1, XSPI2, + SPI3, SPI4, ADC1, ADC2, ADF1, UART4, UART5, UART7 or LPTIM2, + the AHB port 1 should be selected on the peripheral side. + + + + [..] + 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 one of the following modes : + (+++) DMA_NORMAL : Normal Mode + (+++) DMA_PFCTRL : Peripheral Flow Control (peripheral early termination) 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. + + + *** Privilege attributes *** + ========================================= + [..] + (+) Use HAL_DMA_ConfigChannelAttributes() function to configure privilege attribute. + (++) 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 privilege attribute + 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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_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)); + if (hdma->Init.Mode == DMA_PFCTRL) + { + assert_param(IS_DMA_PFREQ_INSTANCE(hdma->Instance)); + } + /* Check DMA channel instance */ + if ((IS_HPDMA_INSTANCE(hdma->Instance) != 0U) || (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); + + /* Initialize the callbacks */ + if (hdma->State == HAL_DMA_STATE_RESET) + { + /* Clean all callbacks */ + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + hdma->XferSuspendCallback = NULL; + } + + /* 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) +{ + 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)); + /* 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 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); + + /* Global Interrupt Flag management *********************************************************************************/ + if (IS_DMA_GLOBAL_ACTIVE_FLAG(p_dma_instance, global_it_flag) == 0U) + { + 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; + + /* 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; + + /* 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 privilege attribute. + (+) Get DMA channel privilege attribute. + (+) Lock DMA channel privilege attribute configuration. + (+) Check whether DMA channel privilege attribute configuration is locked or not. + + [..] + (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel privilege attribute. + (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel privilege attribute + configuration. + (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel privilege attribute. + (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel privilege attribute lock + status. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the DMA channel privilege attribute. + * @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 privilege attribute. + * 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); + } + } + + return HAL_OK; +} + +/** + * @brief Get the DMA channel privilege attribute. + * @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; + /* return value */ + *pChannelAttributes = attributes; + + return HAL_OK; +} + + +/** + * @brief Lock the DMA channel privilege attribute. + * @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 attribute */ + p_dma_instance->RCFGLOCKR |= channel_idx; + + return HAL_OK; +} + + +/** + * @brief Get the 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) +{ + const 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; +} +/** + * @} + */ + +/** + * @} + */ + + +/* 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 HPDMA and GPDMA */ + if ((IS_HPDMA_INSTANCE(hdma->Instance) != 0U) || (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) */ + WRITE_REG(hdma->Instance->CTR1, tmpreg); + + /* 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_HPDMA_INSTANCE(hdma->Instance) != 0U) || (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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c new file mode 100644 index 0000000..58c05b8 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c @@ -0,0 +1,2186 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_dma2d.c + * @author MCD Application Team + * @brief DMA2D HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the DMA2D peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors 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 + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Program the required configuration through the following parameters: + the transfer mode, the output color mode and the output offset using + HAL_DMA2D_Init() function. + + (#) Program the required configuration through the following parameters: + the input color mode, the input color, the input alpha value, the alpha mode, + the red/blue swap mode, the inverted alpha mode and the input offset using + HAL_DMA2D_ConfigLayer() function for foreground or/and background layer. + + *** Polling mode IO operation *** + ================================= + [..] + (#) Configure pdata parameter (explained hereafter), destination and data length + and enable the transfer using HAL_DMA2D_Start(). + (#) Wait for end of transfer using HAL_DMA2D_PollForTransfer(), at this stage + user can specify the value of timeout according to his end application. + + *** Interrupt mode IO operation *** + =================================== + [..] + (#) Configure pdata parameter, destination and data length and enable + the transfer using HAL_DMA2D_Start_IT(). + (#) Use HAL_DMA2D_IRQHandler() called under DMA2D_IRQHandler() interrupt subroutine. + (#) At the end of data transfer HAL_DMA2D_IRQHandler() function is executed and user can + add his own function by customization of function pointer XferCpltCallback (member + of DMA2D handle structure). + (#) In case of error, the HAL_DMA2D_IRQHandler() function calls the callback + XferErrorCallback. + + -@- In Register-to-Memory transfer mode, pdata parameter is the register + color, in Memory-to-memory or Memory-to-Memory with pixel format + conversion pdata is the source address. + + -@- Configure the foreground source address, the background source address, + the destination and data length then Enable the transfer using + HAL_DMA2D_BlendingStart() in polling mode and HAL_DMA2D_BlendingStart_IT() + in interrupt mode. + + -@- HAL_DMA2D_BlendingStart() and HAL_DMA2D_BlendingStart_IT() functions + are used if the memory to memory with blending transfer mode is selected. + + (#) Optionally, configure and enable the CLUT using HAL_DMA2D_CLUTLoad() in polling + mode or HAL_DMA2D_CLUTLoad_IT() in interrupt mode. + + (#) Optionally, configure the line watermark in using the API HAL_DMA2D_ProgramLineEvent(). + + (#) Optionally, configure the dead time value in the AHB clock cycle inserted between two + consecutive accesses on the AHB master port in using the API HAL_DMA2D_ConfigDeadTime() + and enable/disable the functionality with the APIs HAL_DMA2D_EnableDeadTime() or + HAL_DMA2D_DisableDeadTime(). + + (#) The transfer can be suspended, resumed and aborted using the following + functions: HAL_DMA2D_Suspend(), HAL_DMA2D_Resume(), HAL_DMA2D_Abort(). + + (#) The CLUT loading can be suspended, resumed and aborted using the following + functions: HAL_DMA2D_CLUTLoading_Suspend(), HAL_DMA2D_CLUTLoading_Resume(), + HAL_DMA2D_CLUTLoading_Abort(). + + (#) To control the DMA2D state, use the following function: HAL_DMA2D_GetState(). + + (#) To read the DMA2D error code, use the following function: HAL_DMA2D_GetError(). + + *** DMA2D HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DMA2D HAL driver : + + (+) __HAL_DMA2D_ENABLE: Enable the DMA2D peripheral. + (+) __HAL_DMA2D_GET_FLAG: Get the DMA2D pending flags. + (+) __HAL_DMA2D_CLEAR_FLAG: Clear the DMA2D pending flags. + (+) __HAL_DMA2D_ENABLE_IT: Enable the specified DMA2D interrupts. + (+) __HAL_DMA2D_DISABLE_IT: Disable the specified DMA2D interrupts. + (+) __HAL_DMA2D_GET_IT_SOURCE: Check whether the specified DMA2D interrupt is enabled or not. + + *** Callback registration *** + =================================== + [..] + (#) The compilation define USE_HAL_DMA2D_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use function @ref HAL_DMA2D_RegisterCallback() to register a user callback. + + (#) Function @ref HAL_DMA2D_RegisterCallback() allows to register following callbacks: + (+) XferCpltCallback : callback for transfer complete. + (+) XferErrorCallback : callback for transfer error. + (+) LineEventCallback : callback for line event. + (+) CLUTLoadingCpltCallback : callback for CLUT loading completion. + (+) MspInitCallback : DMA2D MspInit. + (+) MspDeInitCallback : DMA2D 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_DMA2D_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. + @ref HAL_DMA2D_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) XferCpltCallback : callback for transfer complete. + (+) XferErrorCallback : callback for transfer error. + (+) LineEventCallback : callback for line event. + (+) CLUTLoadingCpltCallback : callback for CLUT loading completion. + (+) MspInitCallback : DMA2D MspInit. + (+) MspDeInitCallback : DMA2D MspDeInit. + + (#) By default, after the @ref HAL_DMA2D_Init and if the state is HAL_DMA2D_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions: + examples @ref HAL_DMA2D_LineEventCallback(), @ref HAL_DMA2D_CLUTLoadingCpltCallback() + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the @ref HAL_DMA2D_Init + and @ref HAL_DMA2D_DeInit only when these callbacks are null (not registered beforehand) + If not, MspInit or MspDeInit are not null, the @ref HAL_DMA2D_Init and @ref HAL_DMA2D_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + Exception as well for Transfer Completion and Transfer Error callbacks that are not defined + as weak (overridden) functions. They must be defined by the user to be resorted to. + + 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 @ref HAL_DMA2D_RegisterCallback before calling @ref HAL_DMA2D_DeInit + or @ref HAL_DMA2D_Init function. + + When The compilation define USE_HAL_DMA2D_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + [..] + (@) You can refer to the DMA2D HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +#ifdef HAL_DMA2D_MODULE_ENABLED +#if defined (DMA2D) + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup DMA2D DMA2D + * @brief DMA2D HAL module driver + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Constants DMA2D Private Constants + * @{ + */ + +/** @defgroup DMA2D_TimeOut DMA2D Time Out + * @{ + */ +#define DMA2D_TIMEOUT_ABORT (1000U) /*!< 1s */ +#define DMA2D_TIMEOUT_SUSPEND (1000U) /*!< 1s */ +/** + * @} + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup DMA2D_Private_Functions DMA2D Private Functions + * @{ + */ +static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, + uint32_t Height); +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Functions DMA2D Exported Functions + * @{ + */ + +/** @defgroup DMA2D_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the DMA2D + (+) De-initialize the DMA2D + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DMA2D according to the specified + * parameters in the DMA2D_InitTypeDef and create the associated handle. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d) +{ + /* Check the DMA2D peripheral state */ + if (hdma2d == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA2D_ALL_INSTANCE(hdma2d->Instance)); + assert_param(IS_DMA2D_MODE(hdma2d->Init.Mode)); + assert_param(IS_DMA2D_CMODE(hdma2d->Init.ColorMode)); + assert_param(IS_DMA2D_OFFSET(hdma2d->Init.OutputOffset)); + assert_param(IS_DMA2D_ALPHA_INVERTED(hdma2d->Init.AlphaInverted)); + assert_param(IS_DMA2D_RB_SWAP(hdma2d->Init.RedBlueSwap)); + assert_param(IS_DMA2D_LOM_MODE(hdma2d->Init.LineOffsetMode)); + assert_param(IS_DMA2D_BYTES_SWAP(hdma2d->Init.BytesSwap)); + +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) + if (hdma2d->State == HAL_DMA2D_STATE_RESET) + { + /* Reset Callback pointers in HAL_DMA2D_STATE_RESET only */ + hdma2d->LineEventCallback = HAL_DMA2D_LineEventCallback; + hdma2d->CLUTLoadingCpltCallback = HAL_DMA2D_CLUTLoadingCpltCallback; + if (hdma2d->MspInitCallback == NULL) + { + hdma2d->MspInitCallback = HAL_DMA2D_MspInit; + } + + /* Init the low level hardware */ + hdma2d->MspInitCallback(hdma2d); + } +#else + if (hdma2d->State == HAL_DMA2D_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hdma2d->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_DMA2D_MspInit(hdma2d); + } +#endif /* (USE_HAL_DMA2D_REGISTER_CALLBACKS) */ + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* DMA2D CR register configuration -------------------------------------------*/ + MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_MODE | DMA2D_CR_LOM, hdma2d->Init.Mode | hdma2d->Init.LineOffsetMode); + + /* DMA2D OPFCCR register configuration ---------------------------------------*/ + MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_CM | DMA2D_OPFCCR_SB, + hdma2d->Init.ColorMode | hdma2d->Init.BytesSwap); + + /* DMA2D OOR register configuration ------------------------------------------*/ + MODIFY_REG(hdma2d->Instance->OOR, DMA2D_OOR_LO, hdma2d->Init.OutputOffset); + /* DMA2D OPFCCR AI and RBS fields setting (Output Alpha Inversion)*/ + MODIFY_REG(hdma2d->Instance->OPFCCR, (DMA2D_OPFCCR_AI | DMA2D_OPFCCR_RBS), + ((hdma2d->Init.AlphaInverted << DMA2D_OPFCCR_AI_Pos) | \ + (hdma2d->Init.RedBlueSwap << DMA2D_OPFCCR_RBS_Pos))); + + + /* Update error code */ + hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE; + + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Deinitializes the DMA2D peripheral registers to their default reset + * values. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ + +HAL_StatusTypeDef HAL_DMA2D_DeInit(DMA2D_HandleTypeDef *hdma2d) +{ + + /* Check the DMA2D peripheral state */ + if (hdma2d == NULL) + { + return HAL_ERROR; + } + + /* Before aborting any DMA2D transfer or CLUT loading, check + first whether or not DMA2D clock is enabled */ + if (__HAL_RCC_DMA2D_IS_CLK_ENABLED() == 1U) + { + /* Abort DMA2D transfer if any */ + if ((hdma2d->Instance->CR & DMA2D_CR_START) == DMA2D_CR_START) + { + if (HAL_DMA2D_Abort(hdma2d) != HAL_OK) + { + /* Issue when aborting DMA2D transfer */ + return HAL_ERROR; + } + } + else + { + /* Abort background CLUT loading if any */ + if ((hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START) == DMA2D_BGPFCCR_START) + { + if (HAL_DMA2D_CLUTLoading_Abort(hdma2d, 0U) != HAL_OK) + { + /* Issue when aborting background CLUT loading */ + return HAL_ERROR; + } + } + else + { + /* Abort foreground CLUT loading if any */ + if ((hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START) == DMA2D_FGPFCCR_START) + { + if (HAL_DMA2D_CLUTLoading_Abort(hdma2d, 1U) != HAL_OK) + { + /* Issue when aborting foreground CLUT loading */ + return HAL_ERROR; + } + } + } + } + } + + /* Reset DMA2D control registers*/ + hdma2d->Instance->CR = 0U; + hdma2d->Instance->IFCR = 0x3FU; + hdma2d->Instance->FGOR = 0U; + hdma2d->Instance->BGOR = 0U; + hdma2d->Instance->FGPFCCR = 0U; + hdma2d->Instance->BGPFCCR = 0U; + hdma2d->Instance->OPFCCR = 0U; + +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) + + if (hdma2d->MspDeInitCallback == NULL) + { + hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit; + } + + /* DeInit the low level hardware */ + hdma2d->MspDeInitCallback(hdma2d); + +#else + /* Carry on with de-initialization of low level hardware */ + HAL_DMA2D_MspDeInit(hdma2d); +#endif /* (USE_HAL_DMA2D_REGISTER_CALLBACKS) */ + + /* Update error code */ + hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE; + + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Initializes the DMA2D MSP. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ +__weak void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_DMA2D_MspInit can be implemented in the user file. + */ +} + +/** + * @brief DeInitializes the DMA2D MSP. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ +__weak void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_DMA2D_MspDeInit can be implemented in the user file. + */ +} + +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User DMA2D Callback + * To be used instead of the weak (overridden) predefined callback + * @param hdma2d DMA2D handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_DMA2D_TRANSFERCOMPLETE_CB_ID DMA2D transfer complete Callback ID + * @arg @ref HAL_DMA2D_TRANSFERERROR_CB_ID DMA2D transfer error Callback ID + * @arg @ref HAL_DMA2D_LINEEVENT_CB_ID DMA2D line event Callback ID + * @arg @ref HAL_DMA2D_CLUTLOADINGCPLT_CB_ID DMA2D CLUT loading completion Callback ID + * @arg @ref HAL_DMA2D_MSPINIT_CB_ID DMA2D MspInit callback ID + * @arg @ref HAL_DMA2D_MSPDEINIT_CB_ID DMA2D MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @note No weak predefined callbacks are defined for HAL_DMA2D_TRANSFERCOMPLETE_CB_ID or HAL_DMA2D_TRANSFERERROR_CB_ID + * @retval status + */ +HAL_StatusTypeDef HAL_DMA2D_RegisterCallback(DMA2D_HandleTypeDef *hdma2d, HAL_DMA2D_CallbackIDTypeDef CallbackID, + pDMA2D_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hdma2d); + + if (HAL_DMA2D_STATE_READY == hdma2d->State) + { + switch (CallbackID) + { + case HAL_DMA2D_TRANSFERCOMPLETE_CB_ID : + hdma2d->XferCpltCallback = pCallback; + break; + + case HAL_DMA2D_TRANSFERERROR_CB_ID : + hdma2d->XferErrorCallback = pCallback; + break; + + case HAL_DMA2D_LINEEVENT_CB_ID : + hdma2d->LineEventCallback = pCallback; + break; + + case HAL_DMA2D_CLUTLOADINGCPLT_CB_ID : + hdma2d->CLUTLoadingCpltCallback = pCallback; + break; + + case HAL_DMA2D_MSPINIT_CB_ID : + hdma2d->MspInitCallback = pCallback; + break; + + case HAL_DMA2D_MSPDEINIT_CB_ID : + hdma2d->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_DMA2D_STATE_RESET == hdma2d->State) + { + switch (CallbackID) + { + case HAL_DMA2D_MSPINIT_CB_ID : + hdma2d->MspInitCallback = pCallback; + break; + + case HAL_DMA2D_MSPDEINIT_CB_ID : + hdma2d->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hdma2d); + return status; +} + +/** + * @brief Unregister a DMA2D Callback + * DMA2D Callback is redirected to the weak (overridden) predefined callback + * @param hdma2d DMA2D handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_DMA2D_TRANSFERCOMPLETE_CB_ID DMA2D transfer complete Callback ID + * @arg @ref HAL_DMA2D_TRANSFERERROR_CB_ID DMA2D transfer error Callback ID + * @arg @ref HAL_DMA2D_LINEEVENT_CB_ID DMA2D line event Callback ID + * @arg @ref HAL_DMA2D_CLUTLOADINGCPLT_CB_ID DMA2D CLUT loading completion Callback ID + * @arg @ref HAL_DMA2D_MSPINIT_CB_ID DMA2D MspInit callback ID + * @arg @ref HAL_DMA2D_MSPDEINIT_CB_ID DMA2D MspDeInit callback ID + * @note No weak predefined callbacks are defined for HAL_DMA2D_TRANSFERCOMPLETE_CB_ID or HAL_DMA2D_TRANSFERERROR_CB_ID + * @retval status + */ +HAL_StatusTypeDef HAL_DMA2D_UnRegisterCallback(DMA2D_HandleTypeDef *hdma2d, HAL_DMA2D_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdma2d); + + if (HAL_DMA2D_STATE_READY == hdma2d->State) + { + switch (CallbackID) + { + case HAL_DMA2D_TRANSFERCOMPLETE_CB_ID : + hdma2d->XferCpltCallback = NULL; + break; + + case HAL_DMA2D_TRANSFERERROR_CB_ID : + hdma2d->XferErrorCallback = NULL; + break; + + case HAL_DMA2D_LINEEVENT_CB_ID : + hdma2d->LineEventCallback = HAL_DMA2D_LineEventCallback; + break; + + case HAL_DMA2D_CLUTLOADINGCPLT_CB_ID : + hdma2d->CLUTLoadingCpltCallback = HAL_DMA2D_CLUTLoadingCpltCallback; + break; + + case HAL_DMA2D_MSPINIT_CB_ID : + hdma2d->MspInitCallback = HAL_DMA2D_MspInit; /* Legacy weak (overridden) Msp Init */ + break; + + case HAL_DMA2D_MSPDEINIT_CB_ID : + hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit; /* Legacy weak (overridden) Msp DeInit */ + break; + + default : + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_DMA2D_STATE_RESET == hdma2d->State) + { + switch (CallbackID) + { + case HAL_DMA2D_MSPINIT_CB_ID : + hdma2d->MspInitCallback = HAL_DMA2D_MspInit; /* Legacy weak (overridden) Msp Init */ + break; + + case HAL_DMA2D_MSPDEINIT_CB_ID : + hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit; /* Legacy weak (overridden) Msp DeInit */ + break; + + default : + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hdma2d); + return status; +} +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ + +/** + * @} + */ + + +/** @defgroup DMA2D_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the pdata, destination address and data size then + start the DMA2D transfer. + (+) Configure the source for foreground and background, destination address + and data size then start a MultiBuffer DMA2D transfer. + (+) Configure the pdata, destination address and data size then + start the DMA2D transfer with interrupt. + (+) Configure the source for foreground and background, destination address + and data size then start a MultiBuffer DMA2D transfer with interrupt. + (+) Abort DMA2D transfer. + (+) Suspend DMA2D transfer. + (+) Resume DMA2D transfer. + (+) Enable CLUT transfer. + (+) Configure CLUT loading then start transfer in polling mode. + (+) Configure CLUT loading then start transfer in interrupt mode. + (+) Abort DMA2D CLUT loading. + (+) Suspend DMA2D CLUT loading. + (+) Resume DMA2D CLUT loading. + (+) Poll for transfer complete. + (+) handle DMA2D interrupt request. + (+) Transfer watermark callback. + (+) CLUT Transfer Complete callback. + + +@endverbatim + * @{ + */ + +/** + * @brief Start the DMA2D Transfer. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param pdata Configure the source memory Buffer address if + * Memory-to-Memory or Memory-to-Memory with pixel format + * conversion mode is selected, or configure + * the color value if Register-to-Memory mode is selected. + * @param DstAddress The destination memory Buffer address. + * @param Width The width of data to be transferred from source + * to destination (expressed in number of pixels per line). + * @param Height The height of data to be transferred from source to destination (expressed in number of lines). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Start(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, + uint32_t Height) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Start the DMA2D Transfer with interrupt enabled. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param pdata Configure the source memory Buffer address if + * the Memory-to-Memory or Memory-to-Memory with pixel format + * conversion mode is selected, or configure + * the color value if Register-to-Memory mode is selected. + * @param DstAddress The destination memory Buffer address. + * @param Width The width of data to be transferred from source + * to destination (expressed in number of pixels per line). + * @param Height The height of data to be transferred from source to destination (expressed in number of lines). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, + uint32_t Height) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height); + + /* Enable the transfer complete, transfer error and configuration error interrupts */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Start the multi-source DMA2D Transfer. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param SrcAddress1 The source memory Buffer address for the foreground layer. + * @param SrcAddress2 The source memory Buffer address for the background layer. + * @param DstAddress The destination memory Buffer address. + * @param Width The width of data to be transferred from source + * to destination (expressed in number of pixels per line). + * @param Height The height of data to be transferred from source to destination (expressed in number of lines). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_BlendingStart(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, + uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG) + { + /*blending & fixed FG*/ + WRITE_REG(hdma2d->Instance->FGCOLR, SrcAddress1); + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress2, DstAddress, Width, Height); + } + else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_BG) + { + /*blending & fixed BG*/ + WRITE_REG(hdma2d->Instance->BGCOLR, SrcAddress2); + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height); + } + else + { + /* Configure DMA2D Stream source2 address */ + WRITE_REG(hdma2d->Instance->BGMAR, SrcAddress2); + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height); + } + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Start the multi-source DMA2D Transfer with interrupt enabled. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param SrcAddress1 The source memory Buffer address for the foreground layer. + * @param SrcAddress2 The source memory Buffer address for the background layer. + * @param DstAddress The destination memory Buffer address. + * @param Width The width of data to be transferred from source + * to destination (expressed in number of pixels per line). + * @param Height The height of data to be transferred from source to destination (expressed in number of lines). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, + uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG) + { + /*blending & fixed FG*/ + WRITE_REG(hdma2d->Instance->FGCOLR, SrcAddress1); + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress2, DstAddress, Width, Height); + } + else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_BG) + { + /*blending & fixed BG*/ + WRITE_REG(hdma2d->Instance->BGCOLR, SrcAddress2); + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height); + } + else + { + WRITE_REG(hdma2d->Instance->BGMAR, SrcAddress2); + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height); + } + + /* Enable the transfer complete, transfer error and configuration error interrupts */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Abort the DMA2D Transfer. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Abort(DMA2D_HandleTypeDef *hdma2d) +{ + uint32_t tickstart; + + /* Abort the DMA2D transfer */ + /* START bit is reset to make sure not to set it again, in the event the HW clears it + between the register read and the register write by the CPU (writing 0 has no + effect on START bitvalue) */ + MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_ABORT | DMA2D_CR_START, DMA2D_CR_ABORT); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the DMA2D is effectively disabled */ + while ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U) + { + if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_ABORT) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_TIMEOUT; + } + } + + /* Disable the Transfer Complete, Transfer Error and Configuration Error interrupts */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE); + + /* Change the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Suspend the DMA2D Transfer. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Suspend(DMA2D_HandleTypeDef *hdma2d) +{ + uint32_t tickstart; + + /* Suspend the DMA2D transfer */ + /* START bit is reset to make sure not to set it again, in the event the HW clears it + between the register read and the register write by the CPU (writing 0 has no + effect on START bitvalue). */ + MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_SUSP | DMA2D_CR_START, DMA2D_CR_SUSP); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the DMA2D is effectively suspended */ + while ((hdma2d->Instance->CR & (DMA2D_CR_SUSP | DMA2D_CR_START)) == DMA2D_CR_START) + { + if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_SUSPEND) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + + /* Check whether or not a transfer is actually suspended and change the DMA2D state accordingly */ + if ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U) + { + hdma2d->State = HAL_DMA2D_STATE_SUSPEND; + } + else + { + /* Make sure SUSP bit is cleared since it is meaningless + when no transfer is on-going */ + CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP); + } + + return HAL_OK; +} + +/** + * @brief Resume the DMA2D Transfer. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Resume(DMA2D_HandleTypeDef *hdma2d) +{ + /* Check the SUSP and START bits */ + if ((hdma2d->Instance->CR & (DMA2D_CR_SUSP | DMA2D_CR_START)) == (DMA2D_CR_SUSP | DMA2D_CR_START)) + { + /* Ongoing transfer is suspended: change the DMA2D state before resuming */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + } + + /* Resume the DMA2D transfer */ + /* START bit is reset to make sure not to set it again, in the event the HW clears it + between the register read and the register write by the CPU (writing 0 has no + effect on START bitvalue). */ + CLEAR_BIT(hdma2d->Instance->CR, (DMA2D_CR_SUSP | DMA2D_CR_START)); + + return HAL_OK; +} + + +/** + * @brief Enable the DMA2D CLUT Transfer. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_EnableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Enable the background CLUT loading */ + SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START); + } + else + { + /* Enable the foreground CLUT loading */ + SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START); + } + + return HAL_OK; +} + +/** + * @brief Start DMA2D CLUT Loading. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param CLUTCfg Pointer to a DMA2D_CLUTCfgTypeDef structure that contains + * the configuration information for the color look up table. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad(DMA2D_HandleTypeDef *hdma2d, const DMA2D_CLUTCfgTypeDef *CLUTCfg, + uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_CLUT_CM(CLUTCfg->CLUTColorMode)); + assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg->Size)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the CLUT of the background DMA2D layer */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Write background CLUT memory address */ + WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg->pCLUT); + + /* Write background CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM), + ((CLUTCfg->Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the background */ + SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START); + } + /* Configure the CLUT of the foreground DMA2D layer */ + else + { + /* Write foreground CLUT memory address */ + WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg->pCLUT); + + /* Write foreground CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), + ((CLUTCfg->Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START); + } + + return HAL_OK; +} + +/** + * @brief Start DMA2D CLUT Loading with interrupt enabled. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param CLUTCfg Pointer to a DMA2D_CLUTCfgTypeDef structure that contains + * the configuration information for the color look up table. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad_IT(DMA2D_HandleTypeDef *hdma2d, const DMA2D_CLUTCfgTypeDef *CLUTCfg, + uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_CLUT_CM(CLUTCfg->CLUTColorMode)); + assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg->Size)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the CLUT of the background DMA2D layer */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Write background CLUT memory address */ + WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg->pCLUT); + + /* Write background CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM), + ((CLUTCfg->Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos))); + + /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE); + + /* Enable the CLUT loading for the background */ + SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START); + } + /* Configure the CLUT of the foreground DMA2D layer */ + else + { + /* Write foreground CLUT memory address */ + WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg->pCLUT); + + /* Write foreground CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), + ((CLUTCfg->Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START); + } + + return HAL_OK; +} + +/** + * @brief Start DMA2D CLUT Loading. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param CLUTCfg Pointer to a DMA2D_CLUTCfgTypeDef structure that contains + * the configuration information for the color look up table. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @note API obsolete and maintained for compatibility with legacy. User is + * invited to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from + * code compactness, code size and improved heap usage. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTLoad(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode)); + assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the CLUT of the background DMA2D layer */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Write background CLUT memory address */ + WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT); + + /* Write background CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM), + ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the background */ + SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START); + } + /* Configure the CLUT of the foreground DMA2D layer */ + else + { + /* Write foreground CLUT memory address */ + WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT); + + /* Write foreground CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), + ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START); + } + + return HAL_OK; +} + +/** + * @brief Start DMA2D CLUT Loading with interrupt enabled. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param CLUTCfg Pointer to a DMA2D_CLUTCfgTypeDef structure that contains + * the configuration information for the color look up table. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @note API obsolete and maintained for compatibility with legacy. User is + * invited to resort to HAL_DMA2D_CLUTStartLoad_IT() instead to benefit + * from code compactness, code size and improved heap usage. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTLoad_IT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode)); + assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the CLUT of the background DMA2D layer */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Write background CLUT memory address */ + WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT); + + /* Write background CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM), + ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos))); + + /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE); + + /* Enable the CLUT loading for the background */ + SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START); + } + /* Configure the CLUT of the foreground DMA2D layer */ + else + { + /* Write foreground CLUT memory address */ + WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT); + + /* Write foreground CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), + ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos))); + + /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE); + + /* Enable the CLUT loading for the foreground */ + SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START); + } + + return HAL_OK; +} + +/** + * @brief Abort the DMA2D CLUT loading. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Abort(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + uint32_t tickstart; + const __IO uint32_t *reg = &(hdma2d->Instance->BGPFCCR); /* by default, point at background register */ + + /* Abort the CLUT loading */ + SET_BIT(hdma2d->Instance->CR, DMA2D_CR_ABORT); + + /* If foreground CLUT loading is considered, update local variables */ + if (LayerIdx == DMA2D_FOREGROUND_LAYER) + { + reg = &(hdma2d->Instance->FGPFCCR); + } + + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the CLUT loading is aborted */ + while ((*reg & DMA2D_BGPFCCR_START) != 0U) + { + if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_ABORT) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_TIMEOUT; + } + } + + /* Disable the CLUT Transfer Complete, Transfer Error, Configuration Error and CLUT Access Error interrupts */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE); + + /* Change the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Suspend the DMA2D CLUT loading. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Suspend(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + uint32_t tickstart; + uint32_t loadsuspended; + const __IO uint32_t *reg = &(hdma2d->Instance->BGPFCCR); /* by default, point at background register */ + + /* Suspend the CLUT loading */ + SET_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP); + + /* If foreground CLUT loading is considered, update local variables */ + if (LayerIdx == DMA2D_FOREGROUND_LAYER) + { + reg = &(hdma2d->Instance->FGPFCCR); + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the CLUT loading is suspended */ + /* 1st condition: Suspend Check */ + loadsuspended = ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) ? 1UL : 0UL; + /* 2nd condition: Not Start Check */ + loadsuspended |= ((*reg & DMA2D_BGPFCCR_START) != DMA2D_BGPFCCR_START) ? 1UL : 0UL; + while (loadsuspended == 0UL) + { + if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_SUSPEND) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + /* 1st condition: Suspend Check */ + loadsuspended = ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) ? 1UL : 0UL; + /* 2nd condition: Not Start Check */ + loadsuspended |= ((*reg & DMA2D_BGPFCCR_START) != DMA2D_BGPFCCR_START) ? 1UL : 0UL; + } + + /* Check whether or not a transfer is actually suspended and change the DMA2D state accordingly */ + if ((*reg & DMA2D_BGPFCCR_START) != 0U) + { + hdma2d->State = HAL_DMA2D_STATE_SUSPEND; + } + else + { + /* Make sure SUSP bit is cleared since it is meaningless + when no transfer is on-going */ + CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP); + } + + return HAL_OK; +} + +/** + * @brief Resume the DMA2D CLUT loading. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Resume(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + /* Check the SUSP and START bits for background or foreground CLUT loading */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Background CLUT loading suspension check */ + if ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) + { + if ((hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START) == DMA2D_BGPFCCR_START) + { + /* Ongoing CLUT loading is suspended: change the DMA2D state before resuming */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + } + } + } + else + { + /* Foreground CLUT loading suspension check */ + if ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) + { + if ((hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START) == DMA2D_FGPFCCR_START) + { + /* Ongoing CLUT loading is suspended: change the DMA2D state before resuming */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + } + } + } + + /* Resume the CLUT loading */ + CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP); + + return HAL_OK; +} + + +/** + + * @brief Polling for transfer complete or CLUT loading. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t layer_start; + __IO uint32_t isrflags = 0x0U; + + /* Polling for DMA2D transfer */ + if ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while (__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TC) == 0U) + { + isrflags = READ_REG(hdma2d->Instance->ISR); + if ((isrflags & (DMA2D_FLAG_CE | DMA2D_FLAG_TE)) != 0U) + { + if ((isrflags & DMA2D_FLAG_CE) != 0U) + { + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE; + } + if ((isrflags & DMA2D_FLAG_TE) != 0U) + { + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE; + } + /* Clear the transfer and configuration error flags */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_ERROR; + } + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_TIMEOUT; + } + } + } + } + /* Polling for CLUT loading (foreground or background) */ + layer_start = hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START; + layer_start |= hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START; + if (layer_start != 0U) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while (__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CTC) == 0U) + { + isrflags = READ_REG(hdma2d->Instance->ISR); + if ((isrflags & (DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE)) != 0U) + { + if ((isrflags & DMA2D_FLAG_CAE) != 0U) + { + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE; + } + if ((isrflags & DMA2D_FLAG_CE) != 0U) + { + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE; + } + if ((isrflags & DMA2D_FLAG_TE) != 0U) + { + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE; + } + /* Clear the CLUT Access Error, Configuration Error and Transfer Error flags */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE); + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_ERROR; + } + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_TIMEOUT; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_TIMEOUT; + } + } + } + } + + /* Clear the transfer complete and CLUT loading flags */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC | DMA2D_FLAG_CTC); + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} +/** + * @brief Handle DMA2D interrupt request. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +void HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef *hdma2d) +{ + uint32_t isrflags = READ_REG(hdma2d->Instance->ISR); + uint32_t crflags = READ_REG(hdma2d->Instance->CR); + + /* Transfer Error Interrupt management ***************************************/ + if ((isrflags & DMA2D_FLAG_TE) != 0U) + { + if ((crflags & DMA2D_IT_TE) != 0U) + { + /* Disable the transfer Error interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TE); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE; + + /* Clear the transfer error flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TE); + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if (hdma2d->XferErrorCallback != NULL) + { + /* Transfer error Callback */ + hdma2d->XferErrorCallback(hdma2d); + } + } + } + /* Configuration Error Interrupt management **********************************/ + if ((isrflags & DMA2D_FLAG_CE) != 0U) + { + if ((crflags & DMA2D_IT_CE) != 0U) + { + /* Disable the Configuration Error interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CE); + + /* Clear the Configuration error flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE; + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if (hdma2d->XferErrorCallback != NULL) + { + /* Transfer error Callback */ + hdma2d->XferErrorCallback(hdma2d); + } + } + } + /* CLUT access Error Interrupt management ***********************************/ + if ((isrflags & DMA2D_FLAG_CAE) != 0U) + { + if ((crflags & DMA2D_IT_CAE) != 0U) + { + /* Disable the CLUT access error interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CAE); + + /* Clear the CLUT access error flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE; + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if (hdma2d->XferErrorCallback != NULL) + { + /* Transfer error Callback */ + hdma2d->XferErrorCallback(hdma2d); + } + } + } + /* Transfer watermark Interrupt management **********************************/ + if ((isrflags & DMA2D_FLAG_TW) != 0U) + { + if ((crflags & DMA2D_IT_TW) != 0U) + { + /* Disable the transfer watermark interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TW); + + /* Clear the transfer watermark flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TW); + + /* Transfer watermark Callback */ +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) + hdma2d->LineEventCallback(hdma2d); +#else + HAL_DMA2D_LineEventCallback(hdma2d); +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ + + } + } + /* Transfer Complete Interrupt management ************************************/ + if ((isrflags & DMA2D_FLAG_TC) != 0U) + { + if ((crflags & DMA2D_IT_TC) != 0U) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TC); + + /* Clear the transfer complete flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE; + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if (hdma2d->XferCpltCallback != NULL) + { + /* Transfer complete Callback */ + hdma2d->XferCpltCallback(hdma2d); + } + } + } + /* CLUT Transfer Complete Interrupt management ******************************/ + if ((isrflags & DMA2D_FLAG_CTC) != 0U) + { + if ((crflags & DMA2D_IT_CTC) != 0U) + { + /* Disable the CLUT transfer complete interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CTC); + + /* Clear the CLUT transfer complete flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CTC); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE; + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + /* CLUT Transfer complete Callback */ +#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1) + hdma2d->CLUTLoadingCpltCallback(hdma2d); +#else + HAL_DMA2D_CLUTLoadingCpltCallback(hdma2d); +#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */ + } + } + +} + +/** + * @brief Transfer watermark callback. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ +__weak void HAL_DMA2D_LineEventCallback(DMA2D_HandleTypeDef *hdma2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_DMA2D_LineEventCallback can be implemented in the user file. + */ +} + +/** + * @brief CLUT Transfer Complete callback. + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ +__weak void HAL_DMA2D_CLUTLoadingCpltCallback(DMA2D_HandleTypeDef *hdma2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_DMA2D_CLUTLoadingCpltCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup DMA2D_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the DMA2D foreground or background layer parameters. + (+) Configure the DMA2D CLUT transfer. + (+) Configure the line watermark + (+) Configure the dead time value. + (+) Enable or disable the dead time value functionality. + + +@endverbatim + * @{ + */ + +/** + * @brief Configure the DMA2D Layer according to the specified + * parameters in the DMA2D_HandleTypeDef. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + const DMA2D_LayerCfgTypeDef *pLayerCfg; + uint32_t regMask; + uint32_t regValue; + + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_OFFSET(hdma2d->LayerCfg[LayerIdx].InputOffset)); + if (hdma2d->Init.Mode != DMA2D_R2M) + { + assert_param(IS_DMA2D_INPUT_COLOR_MODE(hdma2d->LayerCfg[LayerIdx].InputColorMode)); + if (hdma2d->Init.Mode != DMA2D_M2M) + { + assert_param(IS_DMA2D_ALPHA_MODE(hdma2d->LayerCfg[LayerIdx].AlphaMode)); + } + } + assert_param(IS_DMA2D_ALPHA_INVERTED(hdma2d->LayerCfg[LayerIdx].AlphaInverted)); + assert_param(IS_DMA2D_RB_SWAP(hdma2d->LayerCfg[LayerIdx].RedBlueSwap)); + + if ((LayerIdx == DMA2D_FOREGROUND_LAYER) && (hdma2d->LayerCfg[LayerIdx].InputColorMode == DMA2D_INPUT_YCBCR)) + { + assert_param(IS_DMA2D_CHROMA_SUB_SAMPLING(hdma2d->LayerCfg[LayerIdx].ChromaSubSampling)); + } + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + pLayerCfg = &hdma2d->LayerCfg[LayerIdx]; + + /* Prepare the value to be written to the BGPFCCR or FGPFCCR register */ + regValue = pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << DMA2D_BGPFCCR_AM_Pos) | \ + (pLayerCfg->AlphaInverted << DMA2D_BGPFCCR_AI_Pos) | (pLayerCfg->RedBlueSwap << DMA2D_BGPFCCR_RBS_Pos); + regMask = (DMA2D_BGPFCCR_CM | DMA2D_BGPFCCR_AM | DMA2D_BGPFCCR_ALPHA | DMA2D_BGPFCCR_AI | DMA2D_BGPFCCR_RBS); + + + if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8)) + { + regValue |= (pLayerCfg->InputAlpha & DMA2D_BGPFCCR_ALPHA); + } + else + { + regValue |= (pLayerCfg->InputAlpha << DMA2D_BGPFCCR_ALPHA_Pos); + } + + /* Configure the background DMA2D layer */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Write DMA2D BGPFCCR register */ + MODIFY_REG(hdma2d->Instance->BGPFCCR, regMask, regValue); + + /* DMA2D BGOR register configuration -------------------------------------*/ + WRITE_REG(hdma2d->Instance->BGOR, pLayerCfg->InputOffset); + + /* DMA2D BGCOLR register configuration -------------------------------------*/ + if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8)) + { + WRITE_REG(hdma2d->Instance->BGCOLR, pLayerCfg->InputAlpha & (DMA2D_BGCOLR_BLUE | DMA2D_BGCOLR_GREEN | \ + DMA2D_BGCOLR_RED)); + } + } + /* Configure the foreground DMA2D layer */ + else + { + + if (pLayerCfg->InputColorMode == DMA2D_INPUT_YCBCR) + { + regValue |= (pLayerCfg->ChromaSubSampling << DMA2D_FGPFCCR_CSS_Pos); + regMask |= DMA2D_FGPFCCR_CSS; + } + + /* Write DMA2D FGPFCCR register */ + MODIFY_REG(hdma2d->Instance->FGPFCCR, regMask, regValue); + + /* DMA2D FGOR register configuration -------------------------------------*/ + WRITE_REG(hdma2d->Instance->FGOR, pLayerCfg->InputOffset); + + /* DMA2D FGCOLR register configuration -------------------------------------*/ + if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8)) + { + WRITE_REG(hdma2d->Instance->FGCOLR, pLayerCfg->InputAlpha & (DMA2D_FGCOLR_BLUE | DMA2D_FGCOLR_GREEN | \ + DMA2D_FGCOLR_RED)); + } + } + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Configure the DMA2D CLUT Transfer. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param CLUTCfg Pointer to a DMA2D_CLUTCfgTypeDef structure that contains + * the configuration information for the color look up table. + * @param LayerIdx DMA2D Layer index. + * This parameter can be one of the following values: + * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) + * @note API obsolete and maintained for compatibility with legacy. User is invited + * to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from code compactness, + * code size and improved heap usage. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode)); + assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size)); + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Configure the CLUT of the background DMA2D layer */ + if (LayerIdx == DMA2D_BACKGROUND_LAYER) + { + /* Write background CLUT memory address */ + WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT); + + /* Write background CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM), + ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos))); + } + /* Configure the CLUT of the foreground DMA2D layer */ + else + { + /* Write foreground CLUT memory address */ + WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT); + + /* Write foreground CLUT size and CLUT color mode */ + MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), + ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos))); + } + + /* Set the DMA2D state to Ready*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + + +/** + * @brief Configure the line watermark. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param Line Line Watermark configuration (maximum 16-bit long value expected). + * @note HAL_DMA2D_ProgramLineEvent() API enables the transfer watermark interrupt. + * @note The transfer watermark interrupt is disabled once it has occurred. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef *hdma2d, uint32_t Line) +{ + /* Check the parameters */ + if (Line > DMA2D_LWR_LW) + { + return HAL_ERROR; + } + else + { + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Sets the Line watermark configuration */ + WRITE_REG(hdma2d->Instance->LWR, Line); + + /* Enable the Line interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TW); + + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; + } +} + +/** + * @brief Enable DMA2D dead time feature. + * @param hdma2d DMA2D handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_EnableDeadTime(DMA2D_HandleTypeDef *hdma2d) +{ + /* Process Locked */ + __HAL_LOCK(hdma2d); + + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Set DMA2D_AMTCR EN bit */ + SET_BIT(hdma2d->Instance->AMTCR, DMA2D_AMTCR_EN); + + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Disable DMA2D dead time feature. + * @param hdma2d DMA2D handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_DisableDeadTime(DMA2D_HandleTypeDef *hdma2d) +{ + /* Process Locked */ + __HAL_LOCK(hdma2d); + + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Clear DMA2D_AMTCR EN bit */ + CLEAR_BIT(hdma2d->Instance->AMTCR, DMA2D_AMTCR_EN); + + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Configure dead time. + * @note The dead time value represents the guaranteed minimum number of cycles between + * two consecutive transactions on the AHB bus. + * @param hdma2d DMA2D handle. + * @param DeadTime dead time value. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_ConfigDeadTime(DMA2D_HandleTypeDef *hdma2d, uint8_t DeadTime) +{ + /* Process Locked */ + __HAL_LOCK(hdma2d); + + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Set DMA2D_AMTCR DT field */ + MODIFY_REG(hdma2d->Instance->AMTCR, DMA2D_AMTCR_DT, (((uint32_t) DeadTime) << DMA2D_AMTCR_DT_Pos)); + + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @} + */ + + +/** @defgroup DMA2D_Exported_Functions_Group4 Peripheral State and Error functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to: + (+) Get the DMA2D state + (+) Get the DMA2D error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the DMA2D state + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL state + */ +HAL_DMA2D_StateTypeDef HAL_DMA2D_GetState(const DMA2D_HandleTypeDef *hdma2d) +{ + return hdma2d->State; +} + +/** + * @brief Return the DMA2D error code + * @param hdma2d pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for DMA2D. + * @retval DMA2D Error Code + */ +uint32_t HAL_DMA2D_GetError(const DMA2D_HandleTypeDef *hdma2d) +{ + return hdma2d->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + + +/** @defgroup DMA2D_Private_Functions DMA2D Private Functions + * @{ + */ + +/** + * @brief Set the DMA2D transfer parameters. + * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the specified DMA2D. + * @param pdata The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param Width The width of data to be transferred from source to destination. + * @param Height The height of data to be transferred from source to destination. + * @retval HAL status + */ +static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, + uint32_t Height) +{ + uint32_t tmp; + uint32_t tmp1; + uint32_t tmp2; + uint32_t tmp3; + uint32_t tmp4; + + /* Configure DMA2D data size */ + MODIFY_REG(hdma2d->Instance->NLR, (DMA2D_NLR_NL | DMA2D_NLR_PL), (Height | (Width << DMA2D_NLR_PL_Pos))); + + /* Configure DMA2D destination address */ + WRITE_REG(hdma2d->Instance->OMAR, DstAddress); + + /* Register to memory DMA2D mode selected */ + if (hdma2d->Init.Mode == DMA2D_R2M) + { + tmp1 = pdata & DMA2D_OCOLR_ALPHA_1; + tmp2 = pdata & DMA2D_OCOLR_RED_1; + tmp3 = pdata & DMA2D_OCOLR_GREEN_1; + tmp4 = pdata & DMA2D_OCOLR_BLUE_1; + + /* Prepare the value to be written to the OCOLR register according to the color mode */ + if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_ARGB8888) + { + tmp = (tmp3 | tmp2 | tmp1 | tmp4); + } + else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_RGB888) + { + tmp = (tmp3 | tmp2 | tmp4); + } + else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_RGB565) + { + tmp2 = (tmp2 >> 19U); + tmp3 = (tmp3 >> 10U); + tmp4 = (tmp4 >> 3U); + tmp = ((tmp3 << 5U) | (tmp2 << 11U) | tmp4); + } + else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_ARGB1555) + { + tmp1 = (tmp1 >> 31U); + tmp2 = (tmp2 >> 19U); + tmp3 = (tmp3 >> 11U); + tmp4 = (tmp4 >> 3U); + tmp = ((tmp3 << 5U) | (tmp2 << 10U) | (tmp1 << 15U) | tmp4); + } + else /* Dhdma2d->Init.ColorMode = DMA2D_OUTPUT_ARGB4444 */ + { + tmp1 = (tmp1 >> 28U); + tmp2 = (tmp2 >> 20U); + tmp3 = (tmp3 >> 12U); + tmp4 = (tmp4 >> 4U); + tmp = ((tmp3 << 4U) | (tmp2 << 8U) | (tmp1 << 12U) | tmp4); + } + /* Write to DMA2D OCOLR register */ + WRITE_REG(hdma2d->Instance->OCOLR, tmp); + } + else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG) /*M2M_blending with fixed color FG DMA2D Mode selected*/ + { + WRITE_REG(hdma2d->Instance->BGMAR, pdata); + } + else /* M2M, M2M_PFC,M2M_Blending or M2M_blending with fixed color BG DMA2D Mode */ + { + /* Configure DMA2D source address */ + WRITE_REG(hdma2d->Instance->FGMAR, pdata); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* DMA2D */ +#endif /* HAL_DMA2D_MODULE_ENABLED */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c new file mode 100644 index 0000000..0c1aad8 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c @@ -0,0 +1,4680 @@ +/** + ********************************************************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + ====================================================================================================================== + [..] + 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, half-word and 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) + In addition, in case of double-word, Exchange data at word level on the destination is also + available. + Considering source and destination are both double-word type. + word exchange only (Source : 0xAB12CD34EF567890 ------> Destination : 0xEF567890AB12CD34) + + (+) 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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); +#if defined ( __GNUC__ ) && !defined (__CC_ARM) +static __attribute__((noinline)) uint32_t DMA_List_CheckNodesBaseAddresses(DMA_NodeTypeDef const *const pNode1, \ + DMA_NodeTypeDef const *const pNode2, \ + DMA_NodeTypeDef const *const pNode3); +#else +static uint32_t DMA_List_CheckNodesBaseAddresses(DMA_NodeTypeDef const *const pNode1, + DMA_NodeTypeDef const *const pNode2, + DMA_NodeTypeDef const *const pNode3); +#endif /* __GNUC__ && !__CC_ARM */ +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_HPDMA_INSTANCE(hdma->Instance) != 0U) || (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 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)); + + /* 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 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_HPDMA)) != 0U) + { + 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)); + } + + /* 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 or HPDMA 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_DWX | 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_HPDMA_INSTANCE(hdma->Instance) != 0U) || (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; + + + /* Add parameters related to DMA configuration */ + if ((pNodeConfig->NodeType & (DMA_CHANNEL_TYPE_GPDMA | DMA_CHANNEL_TYPE_HPDMA)) != 0U) + { + /* 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 OR HPDMA */ + if ((pNodeConfig->NodeType & (DMA_CHANNEL_TYPE_GPDMA | DMA_CHANNEL_TYPE_HPDMA)) != 0U) + { + 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 CLLR register value *************************************************************************************/ + /* Reset CLLR Register value : channel linked-list address register offset */ + pNode->LinkRegisters[NODE_CLLR_2D_DEFAULT_OFFSET] = 0U; + /********************************************************************************* CLLR register value is cleared */ + } + else + { + /* Update CLLR register value *************************************************************************************/ + /* Reset CLLR Register value : channel linked-list address register offset */ + pNode->LinkRegisters[NODE_CLLR_LINEAR_DEFAULT_OFFSET] = 0U; + /********************************************************************************* CLLR register value is cleared */ + } + + /* 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 | DMA_CTR1_DWX); + pNodeConfig->DataHandlingConfig.DataAlignment = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_PAM; + /*********************************************************************************** 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. + */ +#if defined ( __GNUC__ ) && !defined (__CC_ARM) +static __attribute__((noinline)) uint32_t DMA_List_CheckNodesBaseAddresses(DMA_NodeTypeDef const *const pNode1, \ + DMA_NodeTypeDef const *const pNode2, \ + DMA_NodeTypeDef const *const pNode3) +#else +static uint32_t DMA_List_CheckNodesBaseAddresses(DMA_NodeTypeDef const *const pNode1, + DMA_NodeTypeDef const *const pNode2, + DMA_NodeTypeDef const *const pNode3) +#endif /* __GNUC__ && !__CC_ARM */ +{ + 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; + const 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c new file mode 100644 index 0000000..d2eda62 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c @@ -0,0 +1,639 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### 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 different + interrupts 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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: Offset between MCU IMRx/EMRx registers */ +#define EXTI_CONFIG_OFFSET 0x08u /* 0x20: Offset between MCU Rising/Falling configuration 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,const 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 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) != 0x00u) + { + 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) != 0x00u) + { + 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) != 0x00u) + { + 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 = SBS->EXTICR[linepos >> 2u]; + regval &= ~(SBS_EXTICR1_PC_EXTI0 << (SBS_EXTICR1_PC_EXTI1_Pos * (linepos & 0x03u))); + regval |= (pExtiConfig->GPIOSel << (SBS_EXTICR1_PC_EXTI1_Pos * (linepos & 0x03u))); + SBS->EXTICR[linepos >> 2u] = 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) != 0x00u) + { + regval |= maskline; + } + else + { + regval &= ~maskline; + } + + /* Store interrupt mode */ + *regaddr = regval; + + /* The event mode cannot be configured if the line does not support it */ + assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT)); + + /* 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) != 0x00u) + { + 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 configuration 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) != 0x00u) + { + 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) != 0x00u) + { + pExtiConfig->Mode |= EXTI_MODE_EVENT; + } + + /* 2] Get trigger for configurable lines : rising */ + if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) + { + regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = *regaddr; + + /* Check if configuration of selected line is enable */ + if ((regval & maskline) != 0x00u) + { + pExtiConfig->Trigger = EXTI_TRIGGER_RISING; + } + else + { + pExtiConfig->Trigger = EXTI_TRIGGER_NONE; + } + + /* 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) != 0x00u) + { + 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 = SBS->EXTICR[linepos >> 2u]; + pExtiConfig->GPIOSel = (regval >> (SBS_EXTICR1_PC_EXTI1_Pos * (linepos & 0x03u))) & SBS_EXTICR1_PC_EXTI0; + } + else + { + pExtiConfig->GPIOSel = 0x00u; + } + } + else + { + pExtiConfig->Trigger = EXTI_TRIGGER_NONE; + pExtiConfig->GPIOSel = 0x00u; + } + + 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) != 0x00u) + { + 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 = SBS->EXTICR[linepos >> 2u]; + regval &= ~(SBS_EXTICR1_PC_EXTI0 << (SBS_EXTICR1_PC_EXTI1_Pos * (linepos & 0x03u))); + SBS->EXTICR[linepos >> 2u] = regval; + } + } + + return HAL_OK; +} + + +/** + * @brief Register callback for a dedicated 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->PendingCallback = 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 pending bit */ + regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset)); + regval = (*regaddr & maskline); + + if (regval != 0x00u) + { + /* Clear pending bit */ + *regaddr = maskline; + + /* Call callback */ + if (hexti->PendingCallback != NULL) + { + hexti->PendingCallback(); + } + } +} + + +/** + * @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_FALLING + * This parameter is kept for compatibility with other series. + * @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 parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(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); + + /* Get pending bit */ + regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_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_FALLING + * This parameter is kept for compatibility with other series. + * @retval None. + */ +void HAL_EXTI_ClearPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge) +{ + __IO uint32_t *regaddr; + uint32_t maskline; + uint32_t offset; + + /* Check parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(Edge); + + /* compute line register offset and line mask */ + offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); + + /* Get pending register address */ + regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_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 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; +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_EXTI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c new file mode 100644 index 0000000..3dc9a8f --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c @@ -0,0 +1,962 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 + * + @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 + (+) Error code correction (ECC) : Data in flash are 137-bits word + (9 bits added per quad-word) + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver provides functions and macros to configure and program the FLASH + memory of all STM32H7RSxx devices. + + (#) Flash Memory IO Programming functions: + (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and + HAL_FLASH_Lock() functions + (++) Program functions: bytes, half-words, words, double-words and quad-words + (++) There are 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_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_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 + + @endverbatim + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup FLASH FLASH + * @brief FLASH HAL module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/* 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, \ + .Sector = 0U, \ + .NbSectorsToErase = 0U + }; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASH_Private_Functions FLASH Private Functions + * @{ + */ +static void FLASH_Program_Byte(uint32_t Address, uint32_t DataAddress); +static void FLASH_Program_HalfWord(uint32_t Address, uint32_t DataAddress); +static void FLASH_Program_Word(uint32_t Address, uint32_t DataAddress); +static void FLASH_Program_DoubleWord(uint32_t Address, uint32_t DataAddress); +static void FLASH_Program_QuadWord(uint32_t Address, uint32_t DataAddress); +static void FLASH_Program_OTPHalfWord(uint32_t Address, uint32_t DataAddress); +static void FLASH_Program_OTPWord(uint32_t Address, 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 data 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 Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t DataAddress) +{ + HAL_StatusTypeDef status; + + /* 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) + { + switch (TypeProgram) + { + case FLASH_TYPEPROGRAM_BYTE: + /* Program a byte (8-bit) at a specified address */ + FLASH_Program_Byte(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_HALFWORD: + /* Program a half-word (16-bit) at a specified address */ + FLASH_Program_HalfWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_WORD: + /* Program a word (32-bit) at a specified address */ + FLASH_Program_Word(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_DOUBLEWORD: + /* Program a double-word (64-bit) at a specified address */ + FLASH_Program_DoubleWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_QUADWORD: + /* Program a quad-word (128-bit) at a specified address */ + FLASH_Program_QuadWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_OTP_HALFWORD: + /* Program a half-word (16-bit) at a OTP address */ + FLASH_Program_OTPHalfWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_OTP_WORD: + /* Program a word (32-bit) at a OTP address */ + FLASH_Program_OTPWord(Address, DataAddress); + break; + + default: + status = HAL_ERROR; + break; + } + + if (status != HAL_ERROR) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + /* If the program operation is completed, disable the PG (and FW Bit in non quad-word mode) */ + CLEAR_BIT(FLASH->CR, (TypeProgram & ~(FLASH_WORD_SIZE_MASK))); + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + /* return status */ + return status; +} + +/** + * @brief Program a data 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 Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t DataAddress) +{ + HAL_StatusTypeDef status; + + /* 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 = Address; + + /* Enable End of Operation and Error interrupts */ + SET_BIT(FLASH->IER, (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | FLASH_IT_STRBERR | FLASH_IT_INCERR)); + + switch (TypeProgram) + { + case FLASH_TYPEPROGRAM_BYTE: + /* Program a byte (8-bit) at a specified address */ + FLASH_Program_Byte(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_HALFWORD: + /* Program a half-word (16-bit) at a specified address */ + FLASH_Program_HalfWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_WORD: + /* Program a word (32-bit) at a specified address */ + FLASH_Program_Word(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_DOUBLEWORD: + /* Program a double-word (64-bit) at a specified address */ + FLASH_Program_DoubleWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_QUADWORD: + /* Program a quad-word (128-bit) at a specified address */ + FLASH_Program_QuadWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_OTP_HALFWORD: + /* Program a half-word (16-bit) at a OTP address */ + FLASH_Program_OTPHalfWord(Address, DataAddress); + break; + + case FLASH_TYPEPROGRAM_OTP_WORD: + /* Program a word (32-bit) at a OTP address */ + FLASH_Program_OTPWord(Address, DataAddress); + break; + + default: + status = HAL_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + break; + } + } + + return status; +} + +/** + * @brief Handle FLASH interrupt request. + * @retval None + */ +void HAL_FLASH_IRQHandler(void) +{ + uint32_t param = 0U; + uint32_t error; + + /* Save Flash errors */ + error = FLASH->ISR & FLASH_FLAG_ISR_ERRORS; + error |= (FLASH->OPTISR & FLASH_FLAG_OPTISR_ERRORS); + + /* Set parameter of the callback */ + if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_SECTORS) + { + param = pFlash.Sector; + } + else if ((pFlash.ProcedureOnGoing & FLASH_CR_PG) != 0U) + { + param = pFlash.Address; + } + else + { + /* Empty statement (to be compliant MISRA 15.7) */ + } + + /* Clear operation bit on the on-going procedure */ + CLEAR_BIT(FLASH->CR, (pFlash.ProcedureOnGoing & ~(FLASH_WORD_SIZE_MASK))); + + /* Check FLASH operation error flags */ + if (error != 0U) + { + /* Save the error code */ + pFlash.ErrorCode |= error; + + /* Clear error programming flags */ + FLASH->ICR = (error & FLASH_FLAG_ISR_ERRORS); + FLASH->OPTICR = (error & FLASH_FLAG_OPTISR_ERRORS); + + /* Stop the procedure ongoing */ + pFlash.ProcedureOnGoing = 0U; + + /* FLASH error interrupt user callback */ + HAL_FLASH_OperationErrorCallback(param); + } + + /* Check FLASH End of Operation flag */ + if ((FLASH->ISR & FLASH_FLAG_EOP) != 0U) + { + /* Clear FLASH End of Operation pending bit */ + FLASH->ICR = FLASH_FLAG_EOP; + + if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_SECTORS) + { + /* Nb of sectors to erase can be decreased */ + pFlash.NbSectorsToErase--; + + /* Check if there are still sectors to erase */ + if (pFlash.NbSectorsToErase != 0U) + { + /* Increment sector number */ + pFlash.Sector++; + FLASH_SectorErase(pFlash.Sector); + } + else + { + /* No more sectors to Erase */ + pFlash.ProcedureOnGoing = 0U; + param = 0xFFFFFFFFU; + } + } + else + { + /*Clear the procedure ongoing*/ + pFlash.ProcedureOnGoing = 0U; + } + + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(param); + } + + if (pFlash.ProcedureOnGoing == 0U) + { + /* Disable End of Operation and Error interrupts */ + CLEAR_BIT(FLASH->IER, (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | FLASH_IT_STRBERR | FLASH_IT_INCERR)); + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + + /* Check ECC Correction Error */ + if ((FLASH->IER & FLASH_IT_SNECCERR) != 0U) + { + if ((FLASH->ISR & FLASH_FLAG_SNECCERR) != 0U) + { + /* Call User callback */ + HAL_FLASHEx_EccCorrectionCallback(); + + /* Clear ECC correction flag in order to allow new ECC error record */ + FLASH->ICR = FLASH_FLAG_SNECCERR; + } + } + + /* Check ECC Detection Error */ + if ((FLASH->IER & FLASH_IT_DBECCERR) != 0U) + { + if ((FLASH->ISR & FLASH_FLAG_DBECCERR) != 0U) + { + /* Call User callback */ + HAL_FLASHEx_EccDetectionCallback(); + + /* Clear ECC detection flag in order to allow new ECC error record */ + FLASH->ICR = FLASH_FLAG_DBECCERR; + } + } +} + +/** + * @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 + * Sector 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 + * Sector 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 register access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Unlock(void) +{ + if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U) + { + /* Authorize the FLASH Registers access */ + WRITE_REG(FLASH->KEYR, FLASH_KEY1); + WRITE_REG(FLASH->KEYR, FLASH_KEY2); + + /* verify Flash is unlocked */ + if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Lock the FLASH control register access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Lock(void) +{ + /* Set the LOCK Bit to lock the FLASH Registers access */ + SET_BIT(FLASH->CR, FLASH_CR_LOCK); + + /* verify Flash is locked */ + if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U) + { + return HAL_OK; + } + + return HAL_ERROR; +} + +/** + * @brief Unlock the FLASH Option Bytes 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 register 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 Bytes 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; +} + +/** + * @} + */ + +/** @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 FLASH_ErrorCode The returned value can be: + * @arg HAL_FLASH_ERROR_NONE: No error set + * @arg HAL_FLASH_ERROR_WRP: FLASH Write protection error + * @arg HAL_FLASH_ERROR_PGS: FLASH Programming sequence error + * @arg HAL_FLASH_ERROR_STRB: FLASH Strobe error + * @arg HAL_FLASH_ERROR_INC: FLASH Inconsistency error + * @arg HAL_FLASH_ERROR_RDS: FLASH Read security error + * @arg HAL_FLASH_ERROR_SNECC: FLASH ECC single error + * @arg HAL_FLASH_ERROR_DBECC: FLASH ECC double error + * @arg HAL_FLASH_ERROR_CRC: FLASH CRC error + * @arg HAL_FLASH_ERROR_KDR: FLASH Key data register error + * @arg HAL_FLASH_ERROR_OBC: FLASH Options byte change 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 Status + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) +{ + /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. + Even if the FLASH operation fails, the BUSY flag will be reset and an error + flag will be set */ + + uint32_t tickstart = HAL_GetTick(); + uint32_t error; + + while ((FLASH->SR & FLASH_SR_QW) != 0U) + { + if (Timeout != HAL_MAX_DELAY) + { + if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + return HAL_TIMEOUT; + } + } + } + + /* Check FLASH operation error flags */ + error = (FLASH->ISR & FLASH_FLAG_ISR_ERRORS); + error |= (FLASH->OPTISR & FLASH_FLAG_OPTISR_ERRORS); + + if (error != 0U) + { + /*Save the error code*/ + pFlash.ErrorCode |= error; + + /* Clear error programming flags */ + FLASH->ICR = (error & FLASH_FLAG_ISR_ERRORS); + FLASH->OPTICR = (error & FLASH_FLAG_OPTISR_ERRORS); + + return HAL_ERROR; + } + + /* Check FLASH End of Operation flag */ + if ((FLASH->ISR & FLASH_FLAG_EOP) != 0U) + { + /* Clear FLASH End of Operation pending bit */ + FLASH->ICR = FLASH_FLAG_EOP; + } + + /* If there is no error flag set */ + return HAL_OK; +} + +/** + * @brief Program a byte (8-bit) at a specified address. + * @param Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_Byte(uint32_t Address, uint32_t DataAddress) +{ + uint8_t *dest_addr = (uint8_t *)Address; + uint8_t *src_addr = (uint8_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address)); + + /* Set PG bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the byte */ + *dest_addr = *src_addr; + + __ISB(); + __DSB(); + + /* Set FW bit */ + SET_BIT(FLASH->CR, FLASH_CR_FW); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @brief Program a half-word (16-bit) at a specified address. + * @param Address 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 Address, uint32_t DataAddress) +{ + uint16_t *dest_addr = (uint16_t *)Address; + uint16_t *src_addr = (uint16_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address)); + + /* Set PG bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the half-word */ + *dest_addr = *src_addr; + + __ISB(); + __DSB(); + + /* Set FW bit */ + SET_BIT(FLASH->CR, FLASH_CR_FW); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @brief Program a word (32-bit) at a specified address. + * @param Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_Word(uint32_t Address, uint32_t DataAddress) +{ + uint8_t index = 2; + uint16_t *dest_addr = (uint16_t *)Address; + uint16_t *src_addr = (uint16_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address)); + + /* Set PG bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the word */ + do + { + *dest_addr = *src_addr; + dest_addr++; + src_addr++; + index--; + } while (index != 0U); + + __ISB(); + __DSB(); + + /* Set FW bit */ + SET_BIT(FLASH->CR, FLASH_CR_FW); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @brief Program a double-word (64-bit) at a specified address. + * @param Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_DoubleWord(uint32_t Address, uint32_t DataAddress) +{ + uint8_t index = 4; + uint16_t *dest_addr = (uint16_t *)Address; + uint16_t *src_addr = (uint16_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address)); + + /* Set PG bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the double-word */ + do + { + *dest_addr = *src_addr; + dest_addr++; + src_addr++; + index--; + } while (index != 0U); + + __ISB(); + __DSB(); + + /* Set FW bit */ + SET_BIT(FLASH->CR, FLASH_CR_FW); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @brief Program a quad-word (128-bit) at a specified address. + * @param Address 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 Address, uint32_t DataAddress) +{ + uint8_t index = 8; + uint16_t *dest_addr = (uint16_t *)Address; + uint16_t *src_addr = (uint16_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address)); + + /* Set PG bit */ + SET_BIT(FLASH->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); + + __ISB(); + __DSB(); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @brief Program a half-word (16-bit) at a OTP address. + * @param Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_OTPHalfWord(uint32_t Address, uint32_t DataAddress) +{ + uint16_t *dest_addr = (uint16_t *)Address; + uint16_t *src_addr = (uint16_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_OTP_ADDRESS(Address)); + + /* Set PG_OTP bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG_OTP); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the half-word */ + *dest_addr = *src_addr; + + __ISB(); + __DSB(); + + /* Set FW bit */ + SET_BIT(FLASH->CR, FLASH_CR_FW); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @brief Program a word (32-bit) at a OTP address. + * @param Address specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_OTPWord(uint32_t Address, uint32_t DataAddress) +{ + uint8_t index = 2; + uint16_t *dest_addr = (uint16_t *)Address; + uint16_t *src_addr = (uint16_t *)DataAddress; + uint32_t primask_bit; + + /* Check the parameters */ + assert_param(IS_FLASH_OTP_ADDRESS(Address)); + + /* Set PG_OTP bit */ + SET_BIT(FLASH->CR, FLASH_CR_PG_OTP); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the word */ + do + { + *dest_addr = *src_addr; + dest_addr++; + src_addr++; + index--; + } while (index != 0U); + + __ISB(); + __DSB(); + + /* Set FW bit */ + SET_BIT(FLASH->CR, FLASH_CR_FW); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c new file mode 100644 index 0000000..483a4e4 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c @@ -0,0 +1,1322 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 extended peripheral: + * + Extended programming operations functions + * + @verbatim + ============================================================================== + ##### Flash Extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the FLASH interface for STM32H7RSxx + devices contains the following additional features + + (+) Non-volatile state, Root-Of-Trust and Epoch option bytes + (+) Option byte keys associated with hide protection level + (+) CRC hardware module to check integrity + (+) OTP blocks lock mechanism + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure and program the FLASH memory + of all STM32H7RSxx 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 and Mass Erase + (++) There are two modes of erase : + (+++) Polling Mode using HAL_FLASHEx_Erase() + (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT() + + (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to: + (++) Configure the write protection for each sector + (++) Program the user Option Bytes + (++) Configure the hide protection area + (++) Configure the non-volatile state + + (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to: + (++) Get the value of the sectors write protection + (++) Get the value of the user Option Bytes + (++) Get the configuration of the hide protection area + (++) Get the value of the non-volatile state + (++) Get the value of the Root-Of-Trust configuration + (++) Get the value of the Epoch + + (#) OTP lock configuration function: Use HAL_FLASHEx_OTPLockConfig() + (++) Activate the lock of an OTP block + + (#) Get the OTP lock configuration function: Use HAL_FLASHEx_GetOTPLock() + (++) Get the value of the OTP blocks lock configuration + + (#) Option Byte Keys configuration function: Use HAL_FLASHEx_KeyConfig() + (++) Program an option key for a specified hide protection level + + (#) Get an option byte key value: Use HAL_FLASHEx_GetKey() + (++) Get the value of an option byte key for a specified hide protection level + + (#) Perform a CRC computation function: Use HAL_FLASHEx_ComputeCRC() + (++) Perform CRC computation on a area defined either by sectors or by start/end + addresses and return computation result + + (#) ECC management functions: + (++) Handle ECC Detection flash interrupt by calling HAL_FLASHEx_ECCD_IRQHandler() + (++) Callback functions are called when the ECC detection or correction occurs : + HAL_FLASHEx_EccDetectionCallback() for ECC detection, otherwise + HAL_FLASHEx_EccCorrectionCallback() + (++) Get information about ECC error by calling HAL_FLASHEx_GetEccInfo() + (++) Enable/Disable the ECC correction and detection interrupts: + (+++) HAL_FLASHEx_EnableEccCorrectionInterrupt() to enable ECC correction interrupt + (+++) HAL_FLASHEx_DisableEccCorrectionInterrupt() to disable ECC correction interrupt + (+++) HAL_FLASHEx_EnableEccDetectionInterrupt() to enable ECC detection interrupt + (+++) HAL_FLASHEx_DisableEccDetectionInterrupt() to disable ECC detection interrupt + + @endverbatim + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup FLASHEx FLASHEx + * @brief FLASH Extended HAL module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define SYSTEM_FLASH_SIZE 0x00020000UL /*!< System Flash size : 128 KB */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions + * @{ + */ +static void FLASH_MassErase(void); + +static void FLASH_OB_WRPConfig(uint32_t WRPState, uint32_t WRPSector); +static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2); +static void FLASH_OB_HDPConfig(uint32_t HDPStartPage, uint32_t HDPEndPage); +static void FLASH_OB_NVConfig(uint32_t NVState); + +static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector); +static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2); +static void FLASH_OB_GetHDP(uint32_t *HDPStartPage, uint32_t *HDPEndPage); +static uint32_t FLASH_OB_GetNV(void); +static uint32_t FLASH_OB_GetRoT(void); +static uint32_t FLASH_OB_GetEpoch(void); + +static void FLASH_CRC_AddSector(uint32_t Sector); +static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr); +static HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +/* Exported functions -------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions + * @{ + */ + +/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions + * @brief 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(const FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) +{ + HAL_StatusTypeDef status; + uint32_t sector_index; + + /* 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) + { + if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /* Mass erase to be done */ + FLASH_MassErase(); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + else + { + /*Initialization of SectorError variable*/ + *SectorError = 0xFFFFFFFFU; + + for (sector_index = pEraseInit->Sector; sector_index < (pEraseInit->Sector + pEraseInit->NbSectors); + sector_index++) + { + FLASH_SectorErase(sector_index); + + /* 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(FLASH->CR, (pEraseInit->TypeErase | FLASH_CR_SSN)); + } + + /* 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(const FLASH_EraseInitTypeDef *pEraseInit) +{ + HAL_StatusTypeDef status; + + /* 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; + + /* Enable End of Operation and Error interrupts */ + SET_BIT(FLASH->IER, (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | FLASH_IT_STRBERR | FLASH_IT_INCERR)); + + if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /* Mass erase to be done */ + FLASH_MassErase(); + } + else + { + /* Erase by sector to be done */ + pFlash.NbSectorsToErase = pEraseInit->NbSectors; + pFlash.Sector = pEraseInit->Sector; + + /* Erase first sector and wait for IT */ + FLASH_SectorErase(pEraseInit->Sector); + } + } + + 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 reset (BOR reset or exit from Standby/Shutdown modes) + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(const 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; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if ((status == HAL_OK) && (pOBInit->OptionType != 0U)) + { + /* Set PG_OPT Bit */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + + /* Write protection configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U) + { + /* Configure of Write protection on the selected area */ + FLASH_OB_WRPConfig(pOBInit->WRPState, pOBInit->WRPSector); + } + + /* User Configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U) + { + /* Configure the user option bytes */ + FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig1, pOBInit->USERConfig2); + } + + /* HDP configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_HDP) != 0U) + { + /* Configure the HDP Protection */ + FLASH_OB_HDPConfig(pOBInit->HDPStartPage, pOBInit->HDPEndPage); + } + + /* Non-volatile state configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_NV) != 0U) + { + /* Configure the non-volatile state */ + FLASH_OB_NVConfig(pOBInit->NVState); + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + /* Clear PG_OPT Bit */ + CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Get the Option bytes configuration. + * @param pOBInit pointer to an FLASH_OBInitStruct structure that contains the + * configuration information. + * @note The fields pOBInit->WRPArea, pOBInit->WMSecConfig and pOBInit->BootAddrConfig + * should indicate which area/address is requested for the WRP, WM Security or + * Boot Address, else no information will be returned + * + * @retval None + */ +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) +{ + /* Get write protection on the selected area */ + FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector)); + + /* Get the user option bytes */ + FLASH_OB_GetUser(&(pOBInit->USERConfig1), &(pOBInit->USERConfig2)); + + /* Get the HDP Protection */ + FLASH_OB_GetHDP(&(pOBInit->HDPStartPage), &(pOBInit->HDPEndPage)); + + /* Get the non-volatile state */ + pOBInit->NVState = FLASH_OB_GetNV(); + + /* Get the Root-Of-Trust configuration */ + pOBInit->ROTConfig = FLASH_OB_GetRoT(); + + /* Get the epoch */ + pOBInit->EPOCH = FLASH_OB_GetEpoch(); +} + +/** + * @} + */ + +/** @defgroup FLASHEx_Exported_Functions_Group2 Extended protection operation functions + * @brief Extended protection operation functions + * +@verbatim + =============================================================================== + ##### Extended protection operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the Extended FLASH + CRC operations, OTP lock mechanism and option byte keys management. + +@endverbatim + * @{ + */ +/** + * @brief Configure the OTP Lock. + * + * @note To configure the OTP Lock options, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @param OTPLBlock Specifies the block(s) to be OTP locked (used for OPTIONBYTE_OTPL). + * The value of this parameter depend on device used within the same series + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OTPLockConfig(uint32_t OTPLBlock) +{ + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_OB_OTP_BLOCK(OTPLBlock)); + + /* 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 the bit for the OTP programmation */ + SET_BIT(FLASH->CR, FLASH_CR_PG_OTP); + + /* Set PG_OPT Bit */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + + /* Configure the write protected area */ + MODIFY_REG(FLASH->OTPLSRP, FLASH_OTPLSRP_OTPL, (OTPLBlock & FLASH_OTPLSRP_OTPL)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + /* Clear PG_OPT Bit */ + CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + + /* Clear the bit for the OTP programmation */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PG_OTP); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Return the FLASH OTP Lock Option Bytes value. + * + * @retval Status of the OTP Lock + */ +uint32_t HAL_FLASHEx_GetOTPLock(void) +{ + return (FLASH->OTPLSR & FLASH_OTPLSR_OTPL); +} + +/** + * @brief Configure the Keys. + * + * @note To configure the Keys options, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @param pKeyConfig Key(s) to be configured. + * + * @param pKey Address of the key + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_KeyConfig(const FLASH_KeyConfigTypeDef *pKeyConfig, const uint32_t *pKey) +{ + uint32_t index; + uint32_t index_max; + const uint32_t *pdata; + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_KEY_INDEX(pKeyConfig->Index)); + assert_param(IS_KEY_SIZE(pKeyConfig->Size)); + assert_param(IS_KEY_HDPL_LEVEL(pKeyConfig->HDPLLevel)); + + /* 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 PG_OPT Bit */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + + switch (pKeyConfig->Size) + { + case FLASH_KEY_32_BITS : + index_max = 1U; + break; + + case FLASH_KEY_64_BITS : + index_max = 2U; + break; + + case FLASH_KEY_128_BITS : + index_max = 4U; + break; + + case FLASH_KEY_256_BITS : + index_max = 8U; + break; + + default: + /* This case should not occur */ + index_max = 0U; + break; + } + + pdata = pKey; + for (index = 0U; index < index_max; index++) + { + FLASH->OBKDR[index] = pdata[index]; + } + + MODIFY_REG(FLASH->OBKCR, (FLASH_OBKCR_OBKINDEX | FLASH_OBKCR_NEXTKL | FLASH_OBKCR_OBKSIZE), + (pKeyConfig->Index | pKeyConfig->HDPLLevel | pKeyConfig->Size)); + + SET_BIT(FLASH->OBKCR, (FLASH_OBKCR_KEYSTART | FLASH_OBKCR_KEYPROG)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + CLEAR_BIT(FLASH->OBKCR, FLASH_OBKCR_KEYPROG); + + /* Clear PG_OPT Bit */ + CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Load and optionally return the FLASH Option Bytes Key value. + * + * @param pKeyConfig Configuration of the key to be loaded and optionally returned + * + * @param pKey Address to return the FLASH Option Bytes Key value if not NULL. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_GetKey(const FLASH_KeyConfigTypeDef *pKeyConfig, uint32_t *pKey) +{ + uint32_t index; + uint32_t index_max; + uint32_t *pdata; + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_KEY_INDEX(pKeyConfig->Index)); + assert_param(IS_KEY_SIZE(pKeyConfig->Size)); + assert_param(IS_KEY_HDPL_LEVEL(pKeyConfig->HDPLLevel)); + + /* 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 PG_OPT Bit */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + + /* Configure index and HDPL level */ + MODIFY_REG(FLASH->OBKCR, (FLASH_OBKCR_OBKINDEX | FLASH_OBKCR_NEXTKL | FLASH_OBKCR_OBKSIZE | FLASH_OBKCR_KEYPROG), + (pKeyConfig->Index | pKeyConfig->HDPLLevel | pKeyConfig->Size)); + + /* Set the start bit to get the key value */ + SET_BIT(FLASH->OBKCR, FLASH_OBKCR_KEYSTART); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if ((status == HAL_OK) && (pKey != NULL)) + { + switch (pKeyConfig->Size) + { + case FLASH_KEY_32_BITS : + index_max = 1U; + break; + + case FLASH_KEY_64_BITS : + index_max = 2U; + break; + + case FLASH_KEY_128_BITS : + index_max = 4U; + break; + + case FLASH_KEY_256_BITS : + index_max = 8U; + break; + + default: + /* This case should not occur */ + index_max = 0U; + break; + } + + pdata = pKey; + for (index = 0U; index < index_max; index++) + { + *pdata = FLASH->OBKDR[index]; + pdata++; + } + } + + /* Clear PG_OPT Bit */ + CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Perform a CRC computation on the specified FLASH memory area + * @param pCRCInit pointer to an FLASH_CRCInitTypeDef structure that + * contains the configuration information for the CRC computation. + * @param CRC_Result pointer to CRC result + * @note CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7 + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(const FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result) +{ + HAL_StatusTypeDef status; + uint32_t sector_index; + + /* Check the parameters */ + assert_param(IS_FLASH_TYPE_CRC(pCRCInit->TypeCRC)); + assert_param(IS_FLASH_BURST_SIZE_CRC(pCRCInit->BurstSize)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Enable CRC feature */ + SET_BIT(FLASH->CR, FLASH_CR_CRC_EN); + + /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */ + FLASH->ICR = (FLASH_ICR_CRCRDERRF | FLASH_ICR_CRCENDF); + + /* Clear current CRC result and program burst size */ + MODIFY_REG(FLASH->CRCCR, (FLASH_CRCCR_CLEAN_CRC | FLASH_CRCCR_CRC_BURST), + (FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize)); + + if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS) + { + /* Select CRC by sector and clear sectors list */ + SET_BIT(FLASH->CRCCR, (FLASH_CRCCR_CRC_BY_SECT | FLASH_CRCCR_CLEAN_SECT)); + + /* Select CRC sectors */ + for (sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++) + { + FLASH_CRC_AddSector(sector_index); + } + } + else if (pCRCInit->TypeCRC == FLASH_CRC_BANK) + { + /* Select CRC by sector and all sectors */ + SET_BIT(FLASH->CRCCR, (FLASH_CRCCR_CRC_BY_SECT | FLASH_CRCCR_ALL_SECT)); + } + else + { + /* Select CRC by address */ + CLEAR_BIT(FLASH->CRCCR, FLASH_CRCCR_CRC_BY_SECT); + + /* Select CRC start and end addresses */ + FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr); + } + + /* Start the CRC calculation */ + SET_BIT(FLASH->CRCCR, FLASH_CRCCR_START_CRC); + + /* Wait on CRC busy flag */ + status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* Return CRC result */ + (*CRC_Result) = FLASH->CRCDATAR; + + /* Disable CRC feature */ + CLEAR_BIT(FLASH->CR, FLASH_CR_CRC_EN); + + /* Clear CRC flags */ + FLASH->ICR = (FLASH_ICR_CRCRDERRF | FLASH_ICR_CRCENDF); + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + + return status; +} + +/** + * @} + */ + +/** @defgroup FLASHEx_Exported_Functions_Group3 Extended ECC operation functions + * @brief Extended ECC operation functions + * +@verbatim + =============================================================================== + ##### Extended ECC operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the Extended FLASH + ECC Operations. + +@endverbatim + * @{ + */ +/** + * @brief Enable ECC correction interrupt + * @retval None + */ +void HAL_FLASHEx_EnableEccCorrectionInterrupt(void) +{ + __HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR); +} + +/** + * @brief Disable ECC correction interrupt + * @retval None + */ +void HAL_FLASHEx_DisableEccCorrectionInterrupt(void) +{ + __HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR); +} + +/** + * @brief Enable ECC detection interrupt + * @retval None + */ +void HAL_FLASHEx_EnableEccDetectionInterrupt(void) +{ + __HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR); +} + +/** + * @brief Disable ECC detection interrupt + * @retval None + */ +void HAL_FLASHEx_DisableEccDetectionInterrupt(void) +{ + __HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR); +} + +/** + * @brief Get the ECC error information. + * @param pData Pointer to an FLASH_EccInfoTypeDef structure that contains the + * ECC error information. + * @note This function should be called before ECC bit is cleared + * (in callback function) + * @retval None + */ +void HAL_FLASHEx_GetEccInfo(FLASH_EccInfoTypeDef *pData) +{ + /* Check Null pointer */ + assert_param(pData != NULL); + + /* Set address which generate ECC error */ + if ((FLASH->ISR & FLASH_FLAG_SNECCERR) != 0U) + { + pData->Address = FLASH->ECCSFADDR; + } + else + { + pData->Address = FLASH->ECCDFADDR; + } + + /* Set area according address */ + if (IS_FLASH_MAIN_MEM_ADDRESS(pData->Address)) + { + pData->Area = FLASH_ECC_AREA_USER_BANK1; + } + else if (IS_FLASH_OTP_ADDRESS(pData->Address)) + { + pData->Area = FLASH_ECC_AREA_OTP; + } + else if ((pData->Address >= SYSTEM_FLASH_BASE) && + (pData->Address < (SYSTEM_FLASH_BASE + SYSTEM_FLASH_SIZE))) + { + pData->Area = FLASH_ECC_AREA_SYSTEM; + } + else + { + pData->Area = FLASH_ECC_AREA_READ_ONLY; + } + + /* Set Master which initiates transaction. On H7RS, it's necessary CPU1 */ + pData->MasterID = FLASH_ECC_MASTER_CPU1; +} + +/** + * @brief Handle Flash ECC Detection interrupt request. + * @note On STM32H7RS, this Irq Handler should be called in Bus Fault + * interrupt subroutine. + * @retval None + */ +void HAL_FLASHEx_ECCD_IRQHandler(void) +{ + /* Check ECC Detection Error */ + if ((FLASH->ISR & FLASH_FLAG_DBECCERR) != 0U) + { + /* Call User callback */ + HAL_FLASHEx_EccDetectionCallback(); + + /* Clear ECC detection flag in order to allow new ECC error record */ + FLASH->ICR = FLASH_FLAG_DBECCERR; + } +} + +/** + * @brief FLASH ECC Correction interrupt callback. + * @retval None + */ +__weak void HAL_FLASHEx_EccCorrectionCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_FLASHEx_EccCorrectionCallback could be implemented in the user file + */ +} + +/** + * @brief FLASH ECC Detection interrupt callback. + * @retval None + */ +__weak void HAL_FLASHEx_EccDetectionCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_FLASHEx_EccDetectionCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @addtogroup FLASHEx_Private_Functions + * @{ + */ +/** + * @brief Mass erase of FLASH memory. + * @retval None + */ +static void FLASH_MassErase(void) +{ + /* Set the Mass Erase Bit and proceed to erase */ + SET_BIT(FLASH->CR, (FLASH_CR_BER | FLASH_CR_START)); +} + +/** + * @brief Erase the specified FLASH memory sector. + * @param Sector FLASH sector to erase + * This parameter must be a value between 0 and (max number of sectors in the bank - 1) + * @retval None + */ +void FLASH_SectorErase(uint32_t Sector) +{ + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(Sector)); + + /* Proceed to erase the page */ + MODIFY_REG(FLASH->CR, (FLASH_CR_SSN | FLASH_CR_SER | FLASH_CR_START), \ + ((Sector << FLASH_CR_SSN_Pos) | FLASH_CR_SER | FLASH_CR_START)); +} + +/** + * @brief Configure the write protection of the desired sectors. + * + * @note To configure the WRP options, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @param WRPState + * + * @param WRPSector + * + * @retval None + */ +static void FLASH_OB_WRPConfig(uint32_t WRPState, uint32_t WRPSector) +{ + /* Check the parameters */ + assert_param(IS_OB_WRPSTATE(WRPState)); + + /* Configure the write protected area */ + if (WRPState == OB_WRPSTATE_DISABLE) + { + FLASH->WRPSRP |= (WRPSector & FLASH_WRPSRP_WRPS); + } + else if (WRPState == OB_WRPSTATE_ENABLE) + { + FLASH->WRPSRP &= (~(WRPSector & FLASH_WRPSRP_WRPS)); + } + else + { + /* Empty statement (to be compliant MISRA 15.7) */ + } +} + +/** + * @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. + * @param UserType: The FLASH User Option Bytes to be modified. + * This parameter can be a combination of @ref FLASH_OB_USER_TYPE + * @param UserConfig1 The selected User Option Bytes values + * @param UserConfig2 The selected User Option Bytes values + * @retval None + */ +static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2) +{ + uint32_t optr_reg_val = 0; + uint32_t optr_reg_mask = 0; + + /* 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_OBW1SR_BOR_LEVEL)); + + /* Set value and mask for BOR level option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_BOR_LEVEL); + optr_reg_mask |= FLASH_OBW1SR_BOR_LEVEL; + } + + if ((UserType & OB_USER_IWDG_SW) != 0U) + { + /* IWDG1_HW option byte should be modified */ + assert_param(IS_OB_USER_IWDG(UserConfig1 & FLASH_OBW1SR_IWDG_HW)); + + /* Set value and mask for IWDG1_HW option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_HW); + optr_reg_mask |= FLASH_OBW1SR_IWDG_HW; + } + + if ((UserType & OB_USER_NRST_STOP) != 0U) + { + /* NRST_STOP_D1 option byte should be modified */ + assert_param(IS_OB_USER_STOP(UserConfig1 & FLASH_OBW1SR_NRST_STOP)); + + /* Set value and mask for NRST_STOP_D1 option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_NRST_STOP); + optr_reg_mask |= FLASH_OBW1SR_NRST_STOP; + } + + if ((UserType & OB_USER_NRST_STDBY) != 0U) + { + /* NRST_STBY_D1 option byte should be modified */ + assert_param(IS_OB_USER_STANDBY(UserConfig1 & FLASH_OBW1SR_NRST_STBY)); + + /* Set value and mask for NRST_STBY_D1 option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_NRST_STBY); + optr_reg_mask |= FLASH_OBW1SR_NRST_STBY; + } + + if ((UserType & OB_USER_XSPI1_HSLV) != 0U) + { + /* XSPI1_HSLV option byte should be modified */ + assert_param(IS_OB_USER_XSPI1_HSLV(UserConfig1 & FLASH_OBW1SR_XSPI1_HSLV)); + + /* Set value and mask for XSPI1_HSLV option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_XSPI1_HSLV); + optr_reg_mask |= FLASH_OBW1SR_XSPI1_HSLV; + } + + if ((UserType & OB_USER_XSPI2_HSLV) != 0U) + { + /* XSPI2_HSLV option byte should be modified */ + assert_param(IS_OB_USER_XSPI2_HSLV(UserConfig1 & FLASH_OBW1SR_XSPI2_HSLV)); + + /* Set value and mask for XSPI2_HSLV option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_XSPI2_HSLV); + optr_reg_mask |= FLASH_OBW1SR_XSPI2_HSLV; + } + + if ((UserType & OB_USER_IWDG_STOP) != 0U) + { + /* IWDG_FZ_STOP option byte should be modified */ + assert_param(IS_OB_USER_IWDG_STOP(UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STOP)); + + /* Set value and mask for IWDG_FZ_STOP option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STOP); + optr_reg_mask |= FLASH_OBW1SR_IWDG_FZ_STOP; + } + + if ((UserType & OB_USER_IWDG_STDBY) != 0U) + { + /* IWDG_FZ_SDBY option byte should be modified */ + assert_param(IS_OB_USER_IWDG_STDBY(UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STBY)); + + /* Set value and mask for IWDG_FZ_SDBY option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STBY); + optr_reg_mask |= FLASH_OBW1SR_IWDG_FZ_STBY; + } + + if ((UserType & OB_USER_VDDIO_HSLV) != 0U) + { + /* VDDIO_HSLV option byte should be modified */ + assert_param(IS_OB_USER_VDDIO_HSLV(UserConfig1 & FLASH_OBW1SR_VDDIO_HSLV)); + + /* Set value and mask for VDDIO_HSLV option byte */ + optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_VDDIO_HSLV); + optr_reg_mask |= FLASH_OBW1SR_VDDIO_HSLV; + } + + /* Configure the option bytes register 1 if necessary */ + if (optr_reg_mask != 0U) + { + MODIFY_REG(FLASH->OBW1SRP, optr_reg_mask, optr_reg_val); + } + + optr_reg_val = 0; + optr_reg_mask = 0; + + if ((UserType & OB_USER_ITCM_AXI_SHARE) != 0U) + { + /* ITCM_AXI_SHARE option byte should be modified */ + assert_param(IS_OB_USER_ITCM_AXI_SHARE(UserConfig2 & FLASH_OBW2SR_ITCM_AXI_SHARE)); + + /* Set value and mask for ITCM_AXI_SHARE option byte */ + optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_ITCM_AXI_SHARE); + optr_reg_mask |= FLASH_OBW2SR_ITCM_AXI_SHARE; + } + + if ((UserType & OB_USER_DTCM_AXI_SHARE) != 0U) + { + /* DTCM_AXI_SHARE option byte should be modified */ + assert_param(IS_OB_USER_DTCM_AXI_SHARE(UserConfig2 & FLASH_OBW2SR_DTCM_AXI_SHARE)); + + /* Set value and mask for DTCM_AXI_SHARE option byte */ + optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_DTCM_AXI_SHARE); + optr_reg_mask |= FLASH_OBW2SR_DTCM_AXI_SHARE; + } + + if ((UserType & OB_USER_SRAM_ECC) != 0U) + { + /* SRAM_ECC option byte should be modified */ + assert_param(IS_OB_USER_AXISRAM_ECC(UserConfig2 & FLASH_OBW2SR_ECC_ON_SRAM)); + + /* Set value and mask for SRAM_ECC option byte */ + optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_ECC_ON_SRAM); + optr_reg_mask |= FLASH_OBW2SR_ECC_ON_SRAM; + } + + if ((UserType & OB_USER_I2C_NI3C) != 0U) + { + /* I2C_NI3C option byte should be modified */ + assert_param(IS_OB_USER_I2C_NI3C(UserConfig2 & FLASH_OBW2SR_I2C_NI3C)); + + /* Set value and mask for I2C_NI3C option byte */ + optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_I2C_NI3C); + optr_reg_mask |= FLASH_OBW2SR_I2C_NI3C; + } + + /* Configure the option bytes register 2 if necessary */ + if (optr_reg_mask != 0U) + { + MODIFY_REG(FLASH->OBW2SRP, optr_reg_mask, optr_reg_val); + } +} + +/** + * @brief Configure the Hide Protection. + * + * @note To configure the HDP options, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @param HDPStartPage + * + * @param HDPEndPage + * + * @retval None + */ +static void FLASH_OB_HDPConfig(uint32_t HDPStartPage, uint32_t HDPEndPage) +{ + /* Check the parameters */ + assert_param(IS_OB_HDP_PAGE(HDPStartPage)); + assert_param(IS_OB_HDP_PAGE(HDPEndPage)); + + MODIFY_REG(FLASH->HDPSRP, (FLASH_HDPSRP_HDP_AREA_START | FLASH_HDPSRP_HDP_AREA_END), \ + (HDPStartPage | (HDPEndPage << FLASH_HDPSRP_HDP_AREA_END_Pos))); +} + +/** + * @brief Configure the Non-Volatile state. + * + * @note To configure the Non-volatile options, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * + * @param NVState + * + * @retval None + */ +static void FLASH_OB_NVConfig(uint32_t NVState) +{ + /* Check the parameter */ + assert_param(IS_OB_NVSTATE(NVState)); + + MODIFY_REG(FLASH->NVSRP, FLASH_NVSRP_NVSTATE, NVState); +} + +/** + * @brief Return the FLASH Write Protection Option Bytes value. + * + * @param WRPState + * + * @param WRPSector + * + * @retval None + */ +static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector) +{ + if ((FLASH->WRPSR & FLASH_WRPSR_WRPS) == FLASH_WRPSR_WRPS) + { + /* All sectors aren't write protected */ + *WRPState = OB_WRPSTATE_DISABLE; + } + else + { + /* Some sectors are write protected */ + *WRPState = OB_WRPSTATE_ENABLE; + *WRPSector = ((~(FLASH->WRPSR)) & FLASH_WRPSR_WRPS); + } +} + +/** + * @brief Return the FLASH User Option Byte value. + * + * @param UserConfig1 Address to return the FLASH User Option Bytes values configuration 1. + * The return value can be a combination of + * @param UserConfig2 Address to return the FLASH User Option Bytes values configuration 2. + * The return value can be a combination of + * + * @retval None + */ +static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2) +{ + *UserConfig1 = FLASH->OBW1SR; + *UserConfig2 = FLASH->OBW2SR; +} + +/** + * @brief Return the FLASH Hide Protection Option Bytes value. + * + * @param HDPStartPage Address to return the FLASH HDP Option Bytes Start Sector. + * The return value can be a combination of + * @param HDPEndPage Address to return the FLASH HDP Option Bytes End Sector. + * The return value can be a combination of + * + * @retval None + */ +static void FLASH_OB_GetHDP(uint32_t *HDPStartPage, uint32_t *HDPEndPage) +{ + *HDPStartPage = (FLASH->HDPSR & FLASH_HDPSR_HDP_AREA_START); + *HDPEndPage = ((FLASH->HDPSR & FLASH_HDPSR_HDP_AREA_END) >> FLASH_HDPSR_HDP_AREA_END_Pos); +} + +/** + * @brief Return the FLASH Non-volatile state Option Bytes value. + * + * @retval Value of Non-volatile state + */ +static uint32_t FLASH_OB_GetNV(void) +{ + return (FLASH->NVSR & FLASH_NVSR_NVSTATE); +} + +/** + * @brief Return the FLASH RoT Option Bytes value. + * + * @retval Value of the RoT + */ +static uint32_t FLASH_OB_GetRoT(void) +{ + return (FLASH->ROTSR & (FLASH_ROTSR_OEM_PROVD | FLASH_ROTSR_DBG_AUTH | FLASH_ROTSR_IROT_SELECT)); +} + +/** + * @brief Return the FLASH Epoch Option Bytes value. + * + * @retval Value of the Epoch + */ +static uint32_t FLASH_OB_GetEpoch(void) +{ + return (FLASH->EPOCHSR & FLASH_EPOCHSR_EPOCH); +} + +/** + * @brief Add a CRC sector to the list of sectors on which the CRC will be calculated + * @param Sector Specifies the CRC sector number + * @retval None + */ +static void FLASH_CRC_AddSector(uint32_t Sector) +{ + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(Sector)); + + /* Clear CRC sector */ + MODIFY_REG(FLASH->CRCCR, FLASH_CRCCR_CRC_SECT, Sector); + + /* Activate ADD_SECT bit */ + SET_BIT(FLASH->CRCCR, FLASH_CRCCR_ADD_SECT); +} + +/** + * @brief Select CRC start and end memory addresses on which the CRC will be calculated + * @param CRCStartAddr Specifies the CRC start address + * @param CRCEndAddr Specifies the CRC end address + * @retval None + */ +static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr) +{ + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(CRCStartAddr)); + assert_param(IS_FLASH_MAIN_MEM_ADDRESS(CRCEndAddr)); + + /* Write CRC Start and End addresses */ + FLASH->CRCSADDR = (CRCStartAddr - FLASH_BASE); + FLASH->CRCEADDR = (CRCEndAddr - FLASH_BASE); +} + +/** + * @brief Wait for a FLASH CRC computation to complete. + * @param Timeout maximum flash operation timeout + * @retval HAL_StatusTypeDef HAL Status + */ +static HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */ + while ((FLASH->SR & FLASH_SR_CRC_BUSY) != 0U) + { + if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + return HAL_TIMEOUT; + } + } + + /* Check FLASH CRC calculation error flag */ + if ((FLASH->ISR & FLASH_FLAG_CRCERR) != 0U) + { + /*Save the error code*/ + pFlash.ErrorCode |= HAL_FLASH_ERROR_CRC; + + /* Clear CRC error flag */ + FLASH->ICR = FLASH_FLAG_CRCERR; + + return HAL_ERROR; + } + + /* Check FLASH CRC End of Calculation flag */ + if ((FLASH->ISR & FLASH_FLAG_CRCEND) != 0U) + { + /* Clear FLASH End of Calculation pending bit */ + FLASH->ICR = FLASH_FLAG_CRCEND; + } + + /* If there is no error flag set */ + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c new file mode 100644 index 0000000..15a6f94 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c @@ -0,0 +1,556 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### 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 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ +/** MISRA C:2012 deviation rule has been granted for following rules: + * Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of + * range of the shift operator in following API : + * HAL_GPIO_Init + * HAL_GPIO_DeInit + */ + +#ifdef HAL_GPIO_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines ------------------------------------------------------------*/ +/** @addtogroup GPIO_Private_Constants + * @{ + */ +#define GPIO_NUMBER (16U) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup GPIO_Exported_Functions + * @{ + */ + +/** @addtogroup GPIO_Exported_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the GPIOx peripheral according to the specified parameters in the GPIO_Init. + * @param GPIOx where x can be (A..H and M..P) to select the GPIO peripheral for STM32H7RSxx family + * @param GPIO_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 *GPIO_Init) +{ + uint32_t position = 0x00U; + uint32_t iocurrent; + uint32_t temp; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + + /* Configure the port pins */ + while (((GPIO_Init->Pin) >> position) != 0x00U) + { + /* Get current io position */ + iocurrent = (GPIO_Init->Pin) & (1UL << position); + + if (iocurrent != 0x00U) + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Output or Alternate function mode selection */ + if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)) + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * GPIO_OSPEEDR_OSPEED1_Pos)); + temp |= (GPIO_Init->Speed << (position * GPIO_OSPEEDR_OSPEED1_Pos)); + GPIOx->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + temp &= ~(GPIO_OTYPER_OT0 << position) ; + temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position); + GPIOx->OTYPER = temp; + } + + if (((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG) || + (((GPIO_Init->Mode & GPIO_MODE) == MODE_ANALOG) && (GPIO_Init->Pull != GPIO_PULLUP))) + { + /* Check the Pull parameter */ + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + temp &= ~(GPIO_PUPDR_PUPD0 << (position * GPIO_PUPDR_PUPD1_Pos)); + temp |= ((GPIO_Init->Pull) << (position * GPIO_PUPDR_PUPD1_Pos)); + GPIOx->PUPDR = temp; + } + + /* In case of Alternate function mode selection */ + if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF) + { + /* Check the Alternate function parameters */ + assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3U]; + temp &= ~(0xFuL << ((position & 0x07U) * GPIO_AFRL_AFSEL1_Pos)); + temp |= ((GPIO_Init->Alternate) << ((position & 0x07U) * GPIO_AFRL_AFSEL1_Pos)); + GPIOx->AFR[position >> 3U] = temp; + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + temp &= ~(GPIO_MODER_MODE0 << (position * GPIO_MODER_MODE1_Pos)); + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * GPIO_MODER_MODE1_Pos)); + GPIOx->MODER = temp; + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if ((GPIO_Init->Mode & EXTI_MODE) != 0x00U) + { + temp = SBS->EXTICR[position >> 2U]; + temp &= ~(0x0FuL << ((position & 0x03U) * SBS_EXTICR1_PC_EXTI1_Pos)); + temp |= (GPIO_GET_INDEX(GPIOx) << ((position & 0x03U) * SBS_EXTICR1_PC_EXTI1_Pos)); + SBS->EXTICR[position >> 2U] = temp; + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR1; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00U) + { + temp |= iocurrent; + } + EXTI->RTSR1 = temp; + + temp = EXTI->FTSR1; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00U) + { + temp |= iocurrent; + } + EXTI->FTSR1 = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->EMR1; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & EXTI_EVT) != 0x00U) + { + temp |= iocurrent; + } + EXTI->EMR1 = temp; + + temp = EXTI->IMR1; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & EXTI_IT) != 0x00U) + { + temp |= iocurrent; + } + EXTI->IMR1 = temp; + } + } + + position++; + } +} + +/** + * @brief Reset the configuration of a pin or a set of pins for a GPIO port to the default one. + * @param GPIOx where x can be (A..H and M..P) to select the GPIO peripheral for STM32H7RSxx 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_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + uint32_t position = 0x00U; + uint32_t iocurrent; + uint32_t tmp; + + /* 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) != 0x00U) + { + /* Get current io position */ + iocurrent = (GPIO_Pin) & (1UL << position); + + if (iocurrent != 0x00U) + { + /*------------------------- EXTI Mode Configuration --------------------*/ + /* Clear the External Interrupt or Event for the current IO */ + + tmp = SBS->EXTICR[position >> 2U]; + tmp &= (0x0FuL << ((position & 0x03U) * SBS_EXTICR1_PC_EXTI1_Pos)); + if (tmp == (GPIO_GET_INDEX(GPIOx) << ((position & 0x03U) * SBS_EXTICR1_PC_EXTI1_Pos))) + { + /* Clear EXTI line configuration */ + EXTI->IMR1 &= ~(iocurrent); + EXTI->EMR1 &= ~(iocurrent); + + /* Clear Rising Falling edge configuration */ + EXTI->FTSR1 &= ~(iocurrent); + EXTI->RTSR1 &= ~(iocurrent); + + /* Clear EXTICR configuration */ + tmp = 0x0FuL << ((position & 0x03U) * SBS_EXTICR1_PC_EXTI1_Pos); + SBS->EXTICR[position >> 2U] &= ~tmp; + } + + /*------------------------- GPIO Mode Configuration --------------------*/ + /* Configure IO in Analog Mode */ + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * GPIO_MODER_MODE1_Pos)); + + /* Configure the default Alternate Function in current IO */ + GPIOx->AFR[position >> 3U] &= ~(0xFuL << ((position & 0x07U) * GPIO_AFRL_AFSEL1_Pos)) ; + + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * GPIO_OSPEEDR_OSPEED1_Pos)); + + /* 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 * GPIO_PUPDR_PUPD1_Pos)); + } + + position++; + } +} + +/** + * @} + */ + +/** @addtogroup GPIO_Exported_Functions_Group2 + * @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..H and M..P) to select the GPIO peripheral for STM32H7RSxx family + * @param GPIO_Pin specifies the port bit to read. + * This parameter can be any combination of 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) != 0x00U) + { + 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..H and M..P) to select the GPIO peripheral for STM32H7RSxx 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). + * @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. + * @param GPIOx where x can be (A..H and M..P) to select the GPIO peripheral for STM32H7RSxx 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..H and M..P) to select the GPIO peripheral for STM32H7RSxx family + * @param GPIO_Pin specifies the pin to be toggled. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @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..H and M..P) to select the GPIO peripheral for STM32H7RSxx 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 register. This read is mandatory to complete key lock sequence */ + tmp = GPIOx->LCKR; + + /* read again in order to confirm lock is active */ + if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00U) + { + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @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_IT(GPIO_Pin) != 0U) + { + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + HAL_GPIO_EXTI_Callback(GPIO_Pin); + } +} + +/** + * @brief EXTI line detection callback. + * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +__weak void HAL_GPIO_EXTI_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_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* HAL_GPIO_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c new file mode 100644 index 0000000..a2eb7a8 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c @@ -0,0 +1,750 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_gpu2d.c + * @author MCD Application Team + * @brief GPU2D HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the GPU2D peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors 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 + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Peripheral control is exclusively done by the accompanying middleware library. + + *** Interrupt mode IO operation *** + =================================== + [..] + (#) Configure the GPU2D hardware to perform graphics operation using the Third Party MW + Library APIs. + (#) Submit command List to the hardware. + (#) Wait indefinitely for the completion of submitted Command List by GPU2D hardware. + (#) Use HAL_GPU2D_IRQHandler() called under GPU2D_IRQHandler() interrupt subroutine. + (#) At the end of Command List execution HAL_GPU2D_IRQHandler() function is executed + and user can add his own function by customization of function pointer + (#) CommandListCpltCallback (member of GPU2D handle structure) to notify the upper level + about the completion of Command List execution. + + (#) Callback HAL_GPU2D_CommandListCpltCallback is invoked when the GPU2D hardware executes + the programmed command list (Command List execution completion). + + (++) This callback is called when the compilation defines USE_HAL_GPU2D_REGISTER_CALLBACKS + is set to 0 or not defined. + + (++) This callback should be implemented in the application side. It should notify + the upper level that the programmed command list is completed. + + (#) To control the GPU2D state, use the following function: HAL_GPU2D_GetState(). + + (#) To read the GPU2D error code, use the following function: HAL_GPU2D_GetError(). + + *** GPU2D HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in GPU2D HAL driver : + + (+) __HAL_GPU2D_RESET_HANDLE_STATE: Reset GPU2D handle state. + (+) __HAL_GPU2D_GET_FLAG: Get the GPU2D pending flags. + (+) __HAL_GPU2D_CLEAR_FLAG: Clear the GPU2D pending flags. + (+) __HAL_GPU2D_GET_IT_SOURCE: Check whether the specified GPU2D interrupt is enabled or not. + + *** Callback registration *** + =================================== + [..] + (#) The compilation define USE_HAL_GPU2D_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use function @ref HAL_GPU2D_RegisterCallback() to register a user callback. + + (#) Function @ref HAL_GPU2D_RegisterCallback() allows to register following callbacks: + (+) CommandListCpltCallback : callback for Command List completion. + (+) MspInitCallback : GPU2D MspInit. + (+) MspDeInitCallback : GPU2D 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_GPU2D_UnRegisterCallback() to reset a callback to the default + weak (surcharged) function. + @ref HAL_GPU2D_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) CommandListCpltCallback : callback for Command List completion. + (+) MspInitCallback : GPU2D MspInit. + (+) MspDeInitCallback : GPU2D MspDeInit. + + 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 @ref HAL_GPU2D_RegisterCallback before calling @ref HAL_GPU2D_DeInit + or @ref HAL_GPU2D_Init function. + + When The compilation define USE_HAL_GPU2D_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + [..] + (@) You can refer to the GPU2D HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +#ifdef HAL_GPU2D_MODULE_ENABLED +#if defined (GPU2D) + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup GPU2D GPU2D + * @brief GPU2D HAL module driver + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup GPU2D_Private_Macros GPU2D Private Macros + * @{ + */ + +/** @defgroup GPU2D_Write_Read Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in GPU2D register + * @param __INSTANCE__ GPU2D Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define GPU2D_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(*(__IO uint32_t *)(__INSTANCE__\ + + __REG__), __VALUE__) + +/** + * @brief Read a value in GPU2D register + * @param __INSTANCE__ GPU2D Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define GPU2D_ReadReg(__INSTANCE__, __REG__) READ_REG(*(__IO uint32_t *)(__INSTANCE__ + __REG__)) +/** + * @} + */ + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPU2D_Exported_Functions GPU2D Exported Functions + * @{ + */ + +/** @defgroup GPU2D_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the GPU2D + (+) De-initialize the GPU2D + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the GPU2D according to the specified + * parameters in the GPU2D_InitTypeDef and create the associated handle. + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_GPU2D_Init(GPU2D_HandleTypeDef *hgpu2d) +{ + /* Check the GPU2D handle validity */ + if (hgpu2d == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_GPU2D_ALL_INSTANCE(hgpu2d->Instance)); + + if (hgpu2d->State == HAL_GPU2D_STATE_RESET) + { +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + /* Reset Callback pointers in HAL_GPU2D_STATE_RESET only */ + hgpu2d->CommandListCpltCallback = HAL_GPU2D_CommandListCpltCallback; + if (hgpu2d->MspInitCallback == NULL) + { + hgpu2d->MspInitCallback = HAL_GPU2D_MspInit; + } + + /* Init the low level hardware */ + hgpu2d->MspInitCallback(hgpu2d); +#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */ + /* Init the low level hardware */ + HAL_GPU2D_MspInit(hgpu2d); +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + + /* Allocate lock resource and initialize it */ + hgpu2d->Lock = HAL_UNLOCKED; + } + + /* Process locked */ + __HAL_LOCK(hgpu2d); + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + /* Reset the CommandListCpltCallback handler */ + hgpu2d->CommandListCpltCallback = NULL; +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + + /* Update error code */ + hgpu2d->ErrorCode = HAL_GPU2D_ERROR_NONE; + + /* Initialize the GPU2D state*/ + hgpu2d->State = HAL_GPU2D_STATE_READY; + + /* Release Lock */ + __HAL_UNLOCK(hgpu2d); + + return HAL_OK; +} + +/** + * @brief Deinitializes the GPU2D peripheral registers to their default reset + * values. + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval None + */ +HAL_StatusTypeDef HAL_GPU2D_DeInit(GPU2D_HandleTypeDef *hgpu2d) +{ + /* Check the GPU2D handle validity */ + if (hgpu2d == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_GPU2D_ALL_INSTANCE(hgpu2d->Instance)); + + /* Process locked */ + __HAL_LOCK(hgpu2d); + + if (hgpu2d->State == HAL_GPU2D_STATE_READY) + { +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + if (hgpu2d->MspDeInitCallback == NULL) + { + hgpu2d->MspDeInitCallback = HAL_GPU2D_MspDeInit; + } + + /* DeInit the low level hardware */ + hgpu2d->MspDeInitCallback(hgpu2d); +#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */ + /* Carry on with de-initialization of low level hardware */ + HAL_GPU2D_MspDeInit(hgpu2d); +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + } + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + /* Reset the CommandListCpltCallback handler */ + hgpu2d->CommandListCpltCallback = NULL; +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + + /* Update error code */ + hgpu2d->ErrorCode = HAL_GPU2D_ERROR_NONE; + + /* Reset the GPU2D state*/ + hgpu2d->State = HAL_GPU2D_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hgpu2d); + + return HAL_OK; +} + +/** + * @brief Initializes the GPU2D MSP. + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval None + */ +__weak void HAL_GPU2D_MspInit(GPU2D_HandleTypeDef *hgpu2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hgpu2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_GPU2D_MspInit can be implemented in the user file. + */ +} + +/** + * @brief DeInitializes the GPU2D MSP. + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval None + */ +__weak void HAL_GPU2D_MspDeInit(GPU2D_HandleTypeDef *hgpu2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hgpu2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_GPU2D_MspDeInit can be implemented in the user file. + */ +} + +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User GPU2D callback + * To be used instead of the weak (surcharged) predefined callback + * @param hgpu2d GPU2D handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_GPU2D_MSPINIT_CB_ID GPU2D MspInit callback ID + * @arg @ref HAL_GPU2D_MSPDEINIT_CB_ID GPU2D MspDeInit callback ID + * @param pCallback pointer to the callback function + * @note Weak predefined callback is defined for HAL_GPU2D_MSPINIT_CB_ID and HAL_GPU2D_MSPDEINIT_CB_ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_GPU2D_RegisterCallback(GPU2D_HandleTypeDef *hgpu2d, HAL_GPU2D_CallbackIDTypeDef CallbackID, + pGPU2D_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the GPU2D handle validity */ + if (hgpu2d == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hgpu2d); + + /* Check the pCallback parameter is valid or not */ + if (pCallback == NULL) + { + /* Update the error code */ + hgpu2d->ErrorCode |= HAL_GPU2D_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + else + { + if ((hgpu2d->State == HAL_GPU2D_STATE_READY) + || (hgpu2d->State == HAL_GPU2D_STATE_RESET)) + { + switch (CallbackID) + { + case HAL_GPU2D_MSPINIT_CB_ID: + hgpu2d->MspInitCallback = pCallback; + break; + + case HAL_GPU2D_MSPDEINIT_CB_ID: + hgpu2d->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hgpu2d->ErrorCode |= HAL_GPU2D_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + status = HAL_ERROR; + } + } + + /* Release lock */ + __HAL_UNLOCK(hgpu2d); + + return status; +} + +/** + * @brief Unregister a GPU2D callback + * GPU2D Callback is redirected to the weak (surcharged) predefined callback + * @param hgpu2d GPU2D handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_GPU2D_MSPINIT_CB_ID GPU2D MspInit callback ID + * @arg @ref HAL_GPU2D_MSPDEINIT_CB_ID GPU2D MspDeInit callback ID + * @note Callback pointers will be set to legacy weak predefined callbacks for HAL_GPU2D_MSPINIT_CB_ID and + * HAL_GPU2D_MSPDEINIT_CB_ID + * @retval status + */ +HAL_StatusTypeDef HAL_GPU2D_UnRegisterCallback(GPU2D_HandleTypeDef *hgpu2d, HAL_GPU2D_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the GPU2D handle validity */ + if (hgpu2d == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hgpu2d); + + if ((HAL_GPU2D_STATE_READY == hgpu2d->State) + || (HAL_GPU2D_STATE_RESET == hgpu2d->State)) + { + switch (CallbackID) + { + case HAL_GPU2D_MSPINIT_CB_ID: + hgpu2d->MspInitCallback = HAL_GPU2D_MspInit; /* Legacy weak Msp Init */ + break; + + case HAL_GPU2D_MSPDEINIT_CB_ID: + hgpu2d->MspDeInitCallback = HAL_GPU2D_MspDeInit; /* Legacy weak Msp DeInit */ + break; + + default : + /* Update the error code */ + hgpu2d->ErrorCode |= HAL_GPU2D_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + status = HAL_ERROR; + } + + /* Release lock */ + __HAL_UNLOCK(hgpu2d); + + return status; +} + +/** + * @brief Register GPU2D Command List Complete Callback + * To be used instead of the weak (surcharged) predefined callback + * @param hgpu2d GPU2D handle + * @param pCallback pointer to the Command List Complete Callback function + * @note Weak predefined callback is defined for Command List Complete + * @retval status + */ +HAL_StatusTypeDef HAL_GPU2D_RegisterCommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d, + pGPU2D_CommandListCpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the GPU2D handle validity */ + if (hgpu2d == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hgpu2d); + + /* Check the CallbackID is valid or not */ + if (pCallback == NULL) + { + /* Update the error code */ + hgpu2d->ErrorCode |= HAL_GPU2D_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + else + { + if ((HAL_GPU2D_STATE_READY == hgpu2d->State) + || (HAL_GPU2D_STATE_RESET == hgpu2d->State)) + { + hgpu2d->CommandListCpltCallback = pCallback; + } + else + { + status = HAL_ERROR; + } + } + + /* Release lock */ + __HAL_UNLOCK(hgpu2d); + + return status; +} + +/** + * @brief Unregister a GPU2D Command List Complete Callback + * GPU2D Command List Complete Callback is redirected to the weak (surcharged) predefined callback + * @param hgpu2d GPU2D handle + * @note Callback pointer will be invalidate (NULL value) + * @retval status + */ +HAL_StatusTypeDef HAL_GPU2D_UnRegisterCommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the GPU2D handle validity */ + if (hgpu2d == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hgpu2d); + + if ((hgpu2d->State == HAL_GPU2D_STATE_READY) + || (hgpu2d->State == HAL_GPU2D_STATE_RESET)) + { + hgpu2d->CommandListCpltCallback = NULL; /* Invalidate the Callback pointer */ + } + else + { + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hgpu2d); + + return status; +} +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + +/** + * @} + */ + + +/** @defgroup GPU2D_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Read GPU2D Register value. + (+) Write a value to GPU2D Register. + (+) handle GPU2D interrupt request. + (+) Command List Complete Transfer Complete callback. + + +@endverbatim + * @{ + */ + +/** + * @brief Read GPU2D Register. Helper function for the higher-level library. + * @param hgpu2d Pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @param offset The register offset from GPU2D base address to read. + * @retval Register value + */ +uint32_t HAL_GPU2D_ReadRegister(const GPU2D_HandleTypeDef *hgpu2d, uint32_t offset) +{ + uint32_t value; + + /* Check the GPU2D handle validity */ + assert_param(hgpu2d != NULL); + + /* Check the parameters */ + assert_param(IS_GPU2D_ALL_INSTANCE(hgpu2d->Instance)); + assert_param(IS_GPU2D_OFFSET(offset)); + + /* No locking is required since reading a register is an atomic operation + * and doesn't incur a state change in hal_gpu2d. */ + value = GPU2D_ReadReg(hgpu2d->Instance, offset); + + return value; +} + +/** + * @brief Write a value to GPU2D Register. Helper function for the higher-level library. + * @param hgpu2d Pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @param offset The register offset from GPU2D base address to write. + * @param value The value to be written to provided register. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_GPU2D_WriteRegister(GPU2D_HandleTypeDef *hgpu2d, uint32_t offset, uint32_t value) +{ + /* Check the GPU2D handle validity */ + assert_param(hgpu2d != NULL); + + /* Check the parameters */ + assert_param(IS_GPU2D_ALL_INSTANCE(hgpu2d->Instance)); + assert_param(IS_GPU2D_OFFSET(offset)); + + /* No locking is required since writing a register is an atomic operation + * and doesn't incur a state change in hal_gpu2d. */ + GPU2D_WriteReg(hgpu2d->Instance, offset, value); + + return HAL_OK; +} + +/** + * @brief Handle GPU2D interrupt request. + * @param hgpu2d Pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval None + */ +void HAL_GPU2D_IRQHandler(GPU2D_HandleTypeDef *hgpu2d) +{ + uint32_t isr_flags = GPU2D_ReadReg(hgpu2d->Instance, GPU2D_ITCTRL); + + /* Command List Complete Interrupt management */ + if ((isr_flags & GPU2D_FLAG_CLC) != 0U) + { + uint32_t last_cl_id; + + /* Clear the completion flag */ + __HAL_GPU2D_CLEAR_FLAG(hgpu2d, GPU2D_FLAG_CLC); + + last_cl_id = GPU2D_ReadReg(hgpu2d->Instance, GPU2D_CLID); + + /* Command List Complete Callback */ +#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1) + if (hgpu2d->CommandListCpltCallback != NULL) + { + hgpu2d->CommandListCpltCallback(hgpu2d, last_cl_id); + } +#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */ + HAL_GPU2D_CommandListCpltCallback(hgpu2d, last_cl_id); +#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */ + } +} + +/** + * @brief Handle GPU2D Error interrupt request. + * @param hgpu2d Pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval None + */ +void HAL_GPU2D_ER_IRQHandler(GPU2D_HandleTypeDef *hgpu2d) +{ + HAL_GPU2D_ErrorCallback(hgpu2d); +} + +/** + * @brief Command List Complete callback. + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @param CmdListID Command list ID that got completed. + * @retval None + */ +__weak void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef *hgpu2d, uint32_t CmdListID) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hgpu2d); + UNUSED(CmdListID); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_GPU2D_CommandListCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Error handler callback. + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval None + */ +__weak void HAL_GPU2D_ErrorCallback(GPU2D_HandleTypeDef *hgpu2d) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hgpu2d); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_GPU2D_ErrorCallback can be implemented in the user file. + The default implementation stops the execution as an error is considered + fatal and non recoverable. + */ + + /* Infinite loop */ + for (;;) {}; +} + +/** + * @} + */ + + +/** @defgroup GPU2D_Exported_Functions_Group3 Peripheral State and Error functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to: + (+) Get the GPU2D state + (+) Get the GPU2D error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the GPU2D state + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for the GPU2D. + * @retval GPU2D state + */ +HAL_GPU2D_StateTypeDef HAL_GPU2D_GetState(GPU2D_HandleTypeDef const *const hgpu2d) +{ + return hgpu2d->State; +} + +/** + * @brief Return the GPU2D error code + * @param hgpu2d pointer to a GPU2D_HandleTypeDef structure that contains + * the configuration information for GPU2D. + * @retval GPU2D Error Code + */ +uint32_t HAL_GPU2D_GetError(GPU2D_HandleTypeDef const *const hgpu2d) +{ + return hgpu2d->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* GPU2D */ +#endif /* HAL_GPU2D_MODULE_ENABLED */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c new file mode 100644 index 0000000..9a29872 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c @@ -0,0 +1,7824 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + ============================================================================== + [..] + 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 or memory 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 or memory 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 or memory 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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; + uint16_t tmpXferCount; + HAL_StatusTypeDef error; + + 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; + + /* 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--; + } + + /* 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; + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + return HAL_ERROR; + } + + /* 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; + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + 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; + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + 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 */ + error = I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart); + + if (error != HAL_OK) + { + /* Check that I2C transfer finished */ + /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ + /* Mean XferCount == 0 */ + + tmpXferCount = hi2c->XferCount; + if ((hi2c->ErrorCode == HAL_I2C_ERROR_AF) && (tmpXferCount == 0U)) + { + /* Reset ErrorCode to NONE */ + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + } + else + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + } + else + { + /* 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) + { + /* A non acknowledge appear during STOP Flag waiting process, a new trial must be performed */ + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Reset the error code for next trial */ + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + } + } + else + { + /* A acknowledge appear during STOP Flag waiting process, this mean that device respond to its address */ + + /* 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 + { + /* A non acknowledge is detected, this mean that device not respond to its address, + a new trial must be performed */ + + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) == HAL_OK) + { + /* 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 or memory 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) +{ + HAL_I2C_ModeTypeDef tmp_mode = hi2c->Mode; + + if ((tmp_mode == HAL_I2C_MODE_MASTER) || (tmp_mode == HAL_I2C_MODE_MEM)) + { + /* 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); + } + else 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); + } + else 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; + uint32_t tmpoptions = hi2c->XferOptions; + 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; + } + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(tmpcr1value, 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); + } + } + } + + 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 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, 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) +{ + HAL_StatusTypeDef status = HAL_OK; + + while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) && (status == HAL_OK)) + { + /* Check if an error is detected */ + if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK) + { + status = HAL_ERROR; + } + + /* Check if a STOPF is detected */ + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) && (status == HAL_OK)) + { + /* 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 */ + status = HAL_OK; + } + + /* Check a no-acknowledge have been detected */ + 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); + + /* 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); + + status = HAL_ERROR; + } + else + { + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + } + } + + /* Check for the Timeout */ + if ((((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) && (status == HAL_OK)) + { + 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); + + status = HAL_ERROR; + } + } + } + return status; +} + +/** + * @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) +{ + uint32_t tmp; + + /* 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 */ + 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c new file mode 100644 index 0000000..71dcd76 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c @@ -0,0 +1,359 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### I2C peripheral Extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the I2C interface for STM32H7RSxx + 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c new file mode 100644 index 0000000..cd6c2fa --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c @@ -0,0 +1,2806 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + =============================================================================== + [..] + 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 stm32h7rsxx_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 callbacks are used. + + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +#ifdef HAL_I2S_MODULE_ENABLED + +/** @addtogroup STM32H7RSxx_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) || (hi2s->Instance == SPI3)) + { + i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI23); + } + else /* SPI6 source clock */ + { + i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6); + } + + /* 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 + * @note The HAL_I2S_RegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET + * to register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID + * @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; + } + + 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; + } + + 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 + * @note The HAL_I2S_UnRegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET + * to un-register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + 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; + } + + 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 Enable the SDO/SDI alternate functions inversion feature for the dedicated I2Sx. + * Original SDI pin becomes SDO and original SDO pin becomes SDI (Also applicable + * on half-duplex mode in case of single data line). + * @param hi2s Pointer to a @ref I2S_HandleTypeDef structure that contains + * the configuration information for I2S module. + * @retval HAL_ERROR When IO is locked, handle is NULL or wrong state. + * @retval HAL_OK IO Swap feature enabled successfully. + */ +HAL_StatusTypeDef HAL_I2S_EnableIOSwap(I2S_HandleTypeDef *hi2s) +{ + /* Check the I2S handle allocation */ + if (hi2s == NULL) + { + return HAL_ERROR; + } + + /* Check the global state */ + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_ERROR; + } + + /* Check for IOLock */ + if (READ_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK) == (SPI_CR1_IOLOCK)) + { + return HAL_ERROR; + } + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE) + { + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + } + + /* Enable IO Swap feature */ + SET_BIT(hi2s->Instance->CFG2, SPI_CFG2_IOSWP); + + return HAL_OK; +} + +/** + * @brief Disable the SDO/SDI alternate functions inversion feature for the dedicated I2Sx. + * Original SDI pin becomes SDI and original SDO pin becomes SDO (Also applicable + * on half-duplex mode in case of single data line). + * @param hi2s Pointer to a @ref I2S_HandleTypeDef structure that contains + * the configuration information for I2S module. + * @retval HAL_ERROR When IO is locked, handle is NULL or wrong state. + * @retval HAL_OK IO Swap feature disabled successfully. + */ +HAL_StatusTypeDef HAL_I2S_DisableIOSwap(I2S_HandleTypeDef *hi2s) +{ + /* Check the I2S handle allocation */ + if (hi2s == NULL) + { + return HAL_ERROR; + } + + /* Check the global state */ + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_ERROR; + } + + /* Check for IOLock */ + if (READ_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK) == (SPI_CR1_IOLOCK)) + { + return HAL_ERROR; + } + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE) + { + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + } + + /* Disable the IO Swap feature */ + CLEAR_BIT(hi2s->Instance->CFG2, SPI_CFG2_IOSWP); + + return HAL_OK; +} + +/** + * @brief Retrieve the SDO/SDI alternate functions inversion feature status for the dedicated I2Sx. + * @param hi2s Pointer to a @ref I2S_HandleTypeDef structure that contains + * the configuration information for I2S module. + * @retval 1 when I2S IO swap feature is enabled, 0 otherwise, or when hi2s pointer is null. + */ +uint32_t HAL_I2S_IsEnabledIOSwap(const I2S_HandleTypeDef *hi2s) +{ + /* Check the I2S handle allocation */ + if (hi2s == NULL) + { + return 0; + } + + return ((READ_BIT(hi2s->Instance->CFG2, SPI_CFG2_IOSWP) == (SPI_CFG2_IOSWP)) ? 1UL : 0UL); +} + +/** + * @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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c new file mode 100644 index 0000000..e46b8a0 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c @@ -0,0 +1,512 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### ICACHE main features ##### + ============================================================================== + [..] + The Texture Cache (ICACHE) is introduced on AXI read-only texture port of + the GPU2D to improve performance when reading texture data from internal and + external memories. + + =============================================================================== + ##### 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. + To ensure a deterministic cache behavior after power on, system reset or after + a call to @ref HAL_ICACHE_Disable(), the application must call + @ref HAL_ICACHE_WaitForInvalidateComplete(). Indeed on power on, system reset + or cache disable, an automatic cache invalidation procedure is launched and the + cache is bypassed until the operation completes. + + (#) 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() + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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_4WAYS)) + +#define IS_ICACHE_MONITOR_TYPE(__TYPE__) (((__TYPE__) == ICACHE_MONITOR_HIT_MISS) || \ + ((__TYPE__) == ICACHE_MONITOR_HIT) || \ + ((__TYPE__) == ICACHE_MONITOR_MISS)) + +/** + * @} + */ + +/* 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_4WAYS 4-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_StatusTypeDef HAL_ICACHE_DeInit(void) +{ + /* Reset interrupt enable value */ + WRITE_REG(ICACHE->IER, 0U); + + /* Clear any pending flags */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF | ICACHE_FCR_CERRF); + + /* Disable cache then set default associative mode value */ + CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN); + WRITE_REG(ICACHE->CR, ICACHE_CR_WAYSEL); + + /* Stop monitor and reset monitor values */ + CLEAR_BIT(ICACHE->CR, ICACHE_MONITOR_HIT_MISS); + SET_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U)); + CLEAR_BIT(ICACHE->CR, (ICACHE_MONITOR_HIT_MISS << 2U)); + + + return HAL_OK; +} + +/** + * @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 if no ongoing operation */ + if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) == 0U) + { + /* 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 + */ +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c new file mode 100644 index 0000000..4ebe940 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c @@ -0,0 +1,4285 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_jpeg.c + * @author MCD Application Team + * @brief JPEG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the JPEG encoder/decoder peripheral: + * + Initialization and de-initialization functions + * + JPEG processing functions encoding and decoding + * + JPEG decoding Getting Info and encoding configuration setting + * + JPEG enable/disable header parsing functions (for decoding) + * + JPEG Input/Output Buffer configuration. + * + JPEG callback functions + * + JPEG Abort/Pause/Resume functions + * + JPEG custom quantization tables setting functions + * + IRQ handler management + * + Peripheral State and Error 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 + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the JPEG peripheral using HAL_JPEG_Init : No initialization parameters are required. + Only the call to HAL_JPEG_Init is necessary to initialize the JPEG peripheral. + + (#) If operation is JPEG encoding use function HAL_JPEG_ConfigEncoding to set + the encoding parameters (mandatory before calling the encoding function). + the application can change the encoding parameter ImageQuality from + 1 to 100 to obtain a more or less quality (visual quality vs the original row image), + and inversely more or less jpg file size. + + (#) Note that for decoding operation the JPEG peripheral output data are organized in + YCbCr blocks called MCU (Minimum Coded Unit) as defioned in the JPEG specification + ISO/IEC 10918-1 standard. + It is up to the application to transform these YCbCr blocks to RGB data that can be display. + + Respectively, for Encoding operation the JPEG peripheral input should be organized + in YCbCr MCU blocks. It is up to the application to perform the necessary RGB to YCbCr + MCU blocks transformation before feeding the JPEG peripheral with data. + + (#) Use functions HAL_JPEG_Encode and HAL_JPEG_Decode to start respectively + a JPEG encoding/decoding operation in polling method (blocking). + + (#) Use functions HAL_JPEG_Encode_IT and HAL_JPEG_Decode_IT to start respectively + a JPEG encoding/decoding operation with Interrupt method (not blocking). + + (#) Use functions HAL_JPEG_Encode_DMA and HAL_JPEG_Decode_DMA to start respectively + a JPEG encoding/decoding operation with DMA method (not blocking). + + (#) Callback HAL_JPEG_InfoReadyCallback is asserted if the current operation + is a JPEG decoding to provide the application with JPEG image parameters. + This callback is asserted when the JPEG peripheral successfully parse the + JPEG header. + + (#) Callback HAL_JPEG_GetDataCallback is asserted for both encoding and decoding + operations to inform the application that the input buffer has been + consumed by the peripheral and to ask for a new data chunk if the operation + (encoding/decoding) has not been complete yet. + + (++) This CallBack should be implemented in the application side. It should + call the function HAL_JPEG_ConfigInputBuffer if new input data are available, + or call HAL_JPEG_Pause with parameter XferSelection set to JPEG_PAUSE_RESUME_INPUT + to inform the JPEG HAL driver that the ongoing operation shall pause waiting for the + application to provide a new input data chunk. + Once the application succeed getting new data and if the input has been paused, + the application can call the function HAL_JPEG_ConfigInputBuffer to set the new + input buffer and size, then resume the JPEG HAL input by calling new function HAL_JPEG_Resume. + If the application has ended feeding the HAL JPEG with input data (no more input data), the application + Should call the function HAL_JPEG_ConfigInputBuffer (within the callback HAL_JPEG_GetDataCallback) + with the parameter InDataLength set to zero. + + (++) The mechanism of HAL_JPEG_ConfigInputBuffer/HAL_JPEG_Pause/HAL_JPEG_Resume allows + to the application to provide the input data (for encoding or decoding) by chunks. + If the new input data chunk is not available (because data should be read from an input file + for example) the application can pause the JPEG input (using function HAL_JPEG_Pause) + Once the new input data chunk is available ( read from a file for example), the application + can call the function HAL_JPEG_ConfigInputBuffer to provide the HAL with the new chunk + then resume the JPEG HAL input by calling function HAL_JPEG_Resume. + + (++) The application can call functions HAL_JPEG_ConfigInputBuffer then HAL_JPEG_Resume. + any time (outside the HAL_JPEG_GetDataCallback) Once the new input chunk data available. + However, to keep data coherency, the function HAL_JPEG_Pause must be imperatively called + (if necessary) within the callback HAL_JPEG_GetDataCallback, i.e when the HAL JPEG has ended + Transferring the previous chunk buffer to the JPEG peripheral. + + (#) Callback HAL_JPEG_DataReadyCallback is asserted when the HAL JPEG driver + has filled the given output buffer with the given size. + + (++) This CallBack should be implemented in the application side. It should + call the function HAL_JPEG_ConfigOutputBuffer to provide the HAL JPEG driver + with the new output buffer location and size to be used to store next data chunk. + if the application is not ready to provide the output chunk location then it can + call the function HAL_JPEG_Pause with parameter XferSelection set to JPEG_PAUSE_RESUME_OUTPUT + to inform the JPEG HAL driver that it shall pause output data. Once the application + is ready to receive the new data chunk (output buffer location free or available) it should call + the function HAL_JPEG_ConfigOutputBuffer to provide the HAL JPEG driver + with the new output chunk buffer location and size, then call HAL_JPEG_Resume + to inform the HAL that it shall resume outputting data in the given output buffer. + + (++) The mechanism of HAL_JPEG_ConfigOutputBuffer/HAL_JPEG_Pause/HAL_JPEG_Resume allows + the application to receive data from the JPEG peripheral by chunks. when a chunk + is received, the application can pause the HAL JPEG output data to be able to process + these received data (YCbCr to RGB conversion in case of decoding or data storage in case + of encoding). + + (++) The application can call functions HAL_JPEG_ ConfigOutputBuffer then HAL_JPEG_Resume. + any time (outside the HAL_JPEG_DataReadyCallback) Once the output data buffer is free to use. + However, to keep data coherency, the function HAL_JPEG_Pause must be imperatively called + (if necessary) within the callback HAL_JPEG_ DataReadyCallback, i.e when the HAL JPEG has ended + Transferring the previous chunk buffer from the JPEG peripheral to the application. + + (#) Callback HAL_JPEG_EncodeCpltCallback is asserted when the HAL JPEG driver has + ended the current JPEG encoding operation, and all output data has been transmitted + to the application. + + (#) Callback HAL_JPEG_DecodeCpltCallback is asserted when the HAL JPEG driver has + ended the current JPEG decoding operation. and all output data has been transmitted + to the application. + + (#) Callback HAL_JPEG_ErrorCallback is asserted when an error occurred during + the current operation. the application can call the function HAL_JPEG_GetError() + to retrieve the error codes. + + (#) By default the HAL JPEG driver uses the default quantization tables + as provide in the JPEG specification (ISO/IEC 10918-1 standard) for encoding. + User can change these default tables if necessary using the function HAL_JPEG_SetUserQuantTables + Note that for decoding the quantization tables are automatically extracted from + the JPEG header. + + (#) To control JPEG state you can use the following function: HAL_JPEG_GetState() + + *** JPEG HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in JPEG HAL driver. + + (+) __HAL_JPEG_RESET_HANDLE_STATE : Reset JPEG handle state. + (+) __HAL_JPEG_ENABLE : Enable the JPEG peripheral. + (+) __HAL_JPEG_DISABLE : Disable the JPEG peripheral. + (+) __HAL_JPEG_GET_FLAG : Check the specified JPEG status flag. + (+) __HAL_JPEG_CLEAR_FLAG : Clear the specified JPEG status flag. + (+) __HAL_JPEG_ENABLE_IT : Enable the specified JPEG Interrupt. + (+) __HAL_JPEG_DISABLE_IT : Disable the specified JPEG Interrupt. + (+) __HAL_JPEG_GET_IT_SOURCE : returns the state of the specified JPEG Interrupt (Enabled or disabled). + + *** Callback registration *** + ============================================= + + The compilation define USE_HAL_JPEG_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_JPEG_RegisterCallback() or HAL_JPEG_RegisterXXXCallback() + to register an interrupt callback. + + Function HAL_JPEG_RegisterCallback() allows to register following callbacks: + (+) EncodeCpltCallback : callback for end of encoding operation. + (+) DecodeCpltCallback : callback for end of decoding operation. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : JPEG MspInit. + (+) MspDeInitCallback : JPEG MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + For specific callbacks InfoReadyCallback, GetDataCallback and DataReadyCallback use dedicated + register callbacks : respectively HAL_JPEG_RegisterInfoReadyCallback(), + HAL_JPEG_RegisterGetDataCallback() and HAL_JPEG_RegisterDataReadyCallback(). + + Use function HAL_JPEG_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_JPEG_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) EncodeCpltCallback : callback for end of encoding operation. + (+) DecodeCpltCallback : callback for end of decoding operation. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : JPEG MspInit. + (+) MspDeInitCallback : JPEG MspDeInit. + + For callbacks InfoReadyCallback, GetDataCallback and DataReadyCallback use dedicated + unregister callbacks : respectively HAL_JPEG_UnRegisterInfoReadyCallback(), + HAL_JPEG_UnRegisterGetDataCallback() and HAL_JPEG_UnRegisterDataReadyCallback(). + + By default, after the HAL_JPEG_Init() and when the state is HAL_JPEG_STATE_RESET + all callbacks are set to the corresponding weak functions : + examples HAL_JPEG_DecodeCpltCallback() , HAL_JPEG_GetDataCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak function in the HAL_JPEG_Init()/ HAL_JPEG_DeInit() only when + these callbacks are null (not registered beforehand). + if not, MspInit or MspDeInit are not null, the HAL_JPEG_Init() / HAL_JPEG_DeInit() + keep and use the user MspInit/MspDeInit functions (registered beforehand) + + Callbacks can be registered/unregistered in HAL_JPEG_STATE_READY state only. + Exception done MspInit/MspDeInit callbacks that can be registered/unregistered + in HAL_JPEG_STATE_READY or HAL_JPEG_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_JPEG_RegisterCallback() before calling HAL_JPEG_DeInit() + or HAL_JPEG_Init() function. + + When The compilation define USE_HAL_JPEG_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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +#ifdef HAL_JPEG_MODULE_ENABLED + +#if defined (JPEG) + +/** @defgroup JPEG JPEG + * @brief JPEG HAL module driver. + * @{ + */ + +/* Private define ------------------------------------------------------------*/ +/** @addtogroup JPEG_Private_Constants + * @{ + */ +#define JPEG_TIMEOUT_VALUE ((uint32_t)1000) /* 1s */ +#define JPEG_AC_HUFF_TABLE_SIZE ((uint32_t)162) /* Huffman AC table size : 162 codes*/ +#define JPEG_DC_HUFF_TABLE_SIZE ((uint32_t)12) /* Huffman DC table size : 12 codes*/ + +#define JPEG_QUANTVAL_MAX ((uint32_t)255) /* Quantization values are 8-bit numbers*/ +#define JPEG_LOW_QUALITY_REFERENCE ((uint32_t)5000) /*Reference value to generate scaling factor + for low quality factors (<50) */ +#define JPEG_HIGH_QUALITY_REFERENCE ((uint32_t)200) /*Reference value to generate scaling factor + for high quality factors (>=50)*/ + +#define JPEG_FIFO_SIZE ((uint32_t)16U) /* JPEG Input/Output HW FIFO size in words*/ + +#define JPEG_FIFO_TH_SIZE ((uint32_t)4U) /* JPEG Input/Output HW FIFO Threshold in words*/ + +#define JPEG_DMA_MASK ((uint32_t)0x00001800) /* JPEG DMA request Mask*/ +#define JPEG_DMA_IDMA ((uint32_t)JPEG_CR_IDMAEN) /* DMA request for the input FIFO */ +#define JPEG_DMA_ODMA ((uint32_t)JPEG_CR_ODMAEN) /* DMA request for the output FIFO */ + +#define JPEG_INTERRUPT_MASK ((uint32_t)0x0000007EU) /* JPEG Interrupt Mask*/ + +#define JPEG_CONTEXT_ENCODE ((uint32_t)0x00000001) /* JPEG context : operation is encoding*/ +#define JPEG_CONTEXT_DECODE ((uint32_t)0x00000002) /* JPEG context : operation is decoding*/ +#define JPEG_CONTEXT_OPERATION_MASK ((uint32_t)0x00000003) /* JPEG context : operation Mask */ + +#define JPEG_CONTEXT_POLLING ((uint32_t)0x00000004) /* JPEG context : Transfer use Polling */ +#define JPEG_CONTEXT_IT ((uint32_t)0x00000008) /* JPEG context : Transfer use Interrupt */ +#define JPEG_CONTEXT_DMA ((uint32_t)0x0000000C) /* JPEG context : Transfer use DMA */ +#define JPEG_CONTEXT_METHOD_MASK ((uint32_t)0x0000000C) /* JPEG context : Transfer Mask */ + + +#define JPEG_CONTEXT_CONF_ENCODING ((uint32_t)0x00000100) /* JPEG context : encoding config done */ + +#define JPEG_CONTEXT_PAUSE_INPUT ((uint32_t)0x00001000) /* JPEG context : Pause Input */ +#define JPEG_CONTEXT_PAUSE_OUTPUT ((uint32_t)0x00002000) /* JPEG context : Pause Output */ + +#define JPEG_CONTEXT_CUSTOM_TABLES ((uint32_t)0x00004000) /* JPEG context : Use custom quantization tables */ + +#define JPEG_CONTEXT_ENDING_DMA ((uint32_t)0x00008000) /* JPEG context : ending with DMA in progress */ + +#define JPEG_PROCESS_ONGOING ((uint32_t)0x00000000) /* Process is on going */ +#define JPEG_PROCESS_DONE ((uint32_t)0x00000001) /* Process is done (ends) */ +#define JPEG_GET_DMA_REMAIN_DATA(__HANDLE__) (__HAL_DMA_GET_COUNTER(__HANDLE__)\ + + HAL_DMAEx_GetFifoLevel(__HANDLE__)) +/** + * @} + */ + +/* Private typedef -----------------------------------------------------------*/ +/** @addtogroup JPEG_Private_Types + * @{ + */ + +/* + JPEG Huffman Table Structure definition : + This implementation of Huffman table structure is compliant with ISO/IEC 10918-1 standard, + Annex C Huffman Table specification + */ +typedef struct +{ + /* These two fields directly represent the contents of a JPEG DHT marker */ + uint8_t Bits[16]; /*!< bits[k] = # of symbols with codes of length k bits, + this parameter corresponds to BITS list in the Annex C */ + + uint8_t HuffVal[162]; /*!< The symbols, in order of incremented code length, + this parameter corresponds to HUFFVAL list in the Annex C */ + + +} JPEG_ACHuffTableTypeDef; + +typedef struct +{ + /* These two fields directly represent the contents of a JPEG DHT marker */ + uint8_t Bits[16]; /*!< bits[k] = # of symbols with codes of length k bits, + this parameter corresponds to BITS list in the Annex C */ + + uint8_t HuffVal[12]; /*!< The symbols, in order of incremented code length, + this parameter corresponds to HUFFVAL list in the Annex C */ + + +} JPEG_DCHuffTableTypeDef; + +typedef struct +{ + uint8_t CodeLength[JPEG_AC_HUFF_TABLE_SIZE]; /*!< Code length */ + + uint32_t HuffmanCode[JPEG_AC_HUFF_TABLE_SIZE]; /*!< HuffmanCode */ + +} JPEG_AC_HuffCodeTableTypeDef; + +typedef struct +{ + uint8_t CodeLength[JPEG_DC_HUFF_TABLE_SIZE]; /*!< Code length */ + + uint32_t HuffmanCode[JPEG_DC_HUFF_TABLE_SIZE]; /*!< HuffmanCode */ + +} JPEG_DC_HuffCodeTableTypeDef; +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @addtogroup JPEG_Private_Macros + * @{ + */ +#define JPEG_ENABLE_DMA(__HANDLE__,__DMA__) ((__HANDLE__)->Instance->CR |= ((__DMA__) & JPEG_DMA_MASK)) +/*note : To disable a DMA request we must use MODIFY_REG macro to avoid writing "1" to the FIFO flush bits + located in the same DMA request enable register (CR register). */ +#define JPEG_DISABLE_DMA(__HANDLE__,__DMA__) MODIFY_REG((__HANDLE__)->Instance->CR, ((__DMA__) & JPEG_DMA_MASK), 0UL) +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup JPEG_Private_Variables + * @{ + */ + +/* The following Huffman tables, are based on the JPEG standard as defined by the ITU-T Recommendation T.81. */ +static const JPEG_DCHuffTableTypeDef JPEG_DCLUM_HuffTable = +{ + { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, /*Bits*/ + + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb } /*HUFFVAL */ + +}; + +static const JPEG_DCHuffTableTypeDef JPEG_DCCHROM_HuffTable = +{ + { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, /*Bits*/ + + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb } /*HUFFVAL */ +}; + +static const JPEG_ACHuffTableTypeDef JPEG_ACLUM_HuffTable = +{ + { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }, /*Bits*/ + + { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, /*HUFFVAL */ + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + } +}; + +static const JPEG_ACHuffTableTypeDef JPEG_ACCHROM_HuffTable = +{ + { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }, /*Bits*/ + + { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, /*HUFFVAL */ + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + } +}; + +static const uint8_t JPEG_ZIGZAG_ORDER[JPEG_QUANT_TABLE_SIZE] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup JPEG_Private_Functions_Prototypes + * @{ + */ + +static HAL_StatusTypeDef JPEG_Bits_To_SizeCodes(const uint8_t *Bits, uint8_t *Huffsize, uint32_t *Huffcode, + uint32_t *LastK); +static HAL_StatusTypeDef JPEG_DCHuff_BitsVals_To_SizeCodes(JPEG_DCHuffTableTypeDef *DC_BitsValsTable, + JPEG_DC_HuffCodeTableTypeDef *DC_SizeCodesTable); +static HAL_StatusTypeDef JPEG_ACHuff_BitsVals_To_SizeCodes(JPEG_ACHuffTableTypeDef *AC_BitsValsTable, + JPEG_AC_HuffCodeTableTypeDef *AC_SizeCodesTable); +static HAL_StatusTypeDef JPEG_Set_HuffDC_Mem(const JPEG_HandleTypeDef *hjpeg, JPEG_DCHuffTableTypeDef *HuffTableDC, + const __IO uint32_t *DCTableAddress); +static HAL_StatusTypeDef JPEG_Set_HuffAC_Mem(const JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC, + const __IO uint32_t *ACTableAddress); +static HAL_StatusTypeDef JPEG_Set_HuffEnc_Mem(JPEG_HandleTypeDef *hjpeg); +static void JPEG_Set_Huff_DHTMem(const JPEG_HandleTypeDef *hjpeg); +static uint32_t JPEG_Set_Quantization_Mem(const JPEG_HandleTypeDef *hjpeg, const uint8_t *QTable, + __IO uint32_t *QTableAddress); +static void JPEG_SetColorYCBCR(JPEG_HandleTypeDef *hjpeg); +static void JPEG_SetColorGrayScale(JPEG_HandleTypeDef *hjpeg); +static void JPEG_SetColorCMYK(JPEG_HandleTypeDef *hjpeg); + +static void JPEG_Init_Process(JPEG_HandleTypeDef *hjpeg); +static uint32_t JPEG_Process(JPEG_HandleTypeDef *hjpeg); +static void JPEG_ReadInputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbRequestWords); +static void JPEG_StoreOutputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbOutputWords); +static uint32_t JPEG_GetQuality(const JPEG_HandleTypeDef *hjpeg); + +static HAL_StatusTypeDef JPEG_DMA_StartProcess(JPEG_HandleTypeDef *hjpeg); +static void JPEG_DMA_ContinueProcess(JPEG_HandleTypeDef *hjpeg); +static void JPEG_DMA_EndProcess(JPEG_HandleTypeDef *hjpeg); +static void JPEG_DMA_PollResidualData(JPEG_HandleTypeDef *hjpeg); +static void JPEG_DMAOutCpltCallback(DMA_HandleTypeDef *hdma); +static void JPEG_DMAInCpltCallback(DMA_HandleTypeDef *hdma); +static void JPEG_DMAErrorCallback(DMA_HandleTypeDef *hdma); +static void JPEG_DMAOutAbortCallback(DMA_HandleTypeDef *hdma) ; + +/** + * @} + */ + +/** @defgroup JPEG_Exported_Functions JPEG Exported Functions + * @{ + */ + +/** @defgroup JPEG_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: + (+) Initialize the JPEG peripheral and creates the associated handle + (+) DeInitialize the JPEG peripheral + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the JPEG according to the specified + * parameters in the JPEG_InitTypeDef and creates the associated handle. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Init(JPEG_HandleTypeDef *hjpeg) +{ + /* These are the sample quantization tables given in JPEG spec ISO/IEC 10918-1 standard , section K.1. */ + static const uint8_t JPEG_LUM_QuantTable[JPEG_QUANT_TABLE_SIZE] = + { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 + }; + static const uint8_t JPEG_CHROM_QuantTable[JPEG_QUANT_TABLE_SIZE] = + { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }; + + /* Check the JPEG handle allocation */ + if (hjpeg == NULL) + { + return HAL_ERROR; + } + +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + if (hjpeg->State == HAL_JPEG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hjpeg->Lock = HAL_UNLOCKED; + + hjpeg->InfoReadyCallback = HAL_JPEG_InfoReadyCallback; /* Legacy weak InfoReadyCallback */ + hjpeg->EncodeCpltCallback = HAL_JPEG_EncodeCpltCallback; /* Legacy weak EncodeCpltCallback */ + hjpeg->DecodeCpltCallback = HAL_JPEG_DecodeCpltCallback; /* Legacy weak DecodeCpltCallback */ + hjpeg->ErrorCallback = HAL_JPEG_ErrorCallback; /* Legacy weak ErrorCallback */ + hjpeg->GetDataCallback = HAL_JPEG_GetDataCallback; /* Legacy weak GetDataCallback */ + hjpeg->DataReadyCallback = HAL_JPEG_DataReadyCallback; /* Legacy weak DataReadyCallback */ + + if (hjpeg->MspInitCallback == NULL) + { + hjpeg->MspInitCallback = HAL_JPEG_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hjpeg->MspInitCallback(hjpeg); + } +#else + if (hjpeg->State == HAL_JPEG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hjpeg->Lock = HAL_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK */ + HAL_JPEG_MspInit(hjpeg); + } +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_BUSY; + + /* Start the JPEG Core*/ + __HAL_JPEG_ENABLE(hjpeg); + + /* Stop the JPEG encoding/decoding process*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + /* Disable All Interrupts */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + /* Disable All DMA requests */ + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_MASK); + + /* Flush input and output FIFOs*/ + hjpeg->Instance->CR |= JPEG_CR_IFF; + hjpeg->Instance->CR |= JPEG_CR_OFF; + + /* Clear all flags */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); + + /* init default quantization tables*/ + hjpeg->QuantTable0 = (uint8_t *)((uint32_t)JPEG_LUM_QuantTable); + hjpeg->QuantTable1 = (uint8_t *)((uint32_t)JPEG_CHROM_QuantTable); + hjpeg->QuantTable2 = NULL; + hjpeg->QuantTable3 = NULL; + + /* init the default Huffman tables*/ + if (JPEG_Set_HuffEnc_Mem(hjpeg) != HAL_OK) + { + hjpeg->ErrorCode = HAL_JPEG_ERROR_HUFF_TABLE; + + return HAL_ERROR; + } + + /* Enable header processing*/ + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_HDR; + + /* Reset JpegInCount and JpegOutCount */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /* Reset the JPEG ErrorCode */ + hjpeg->ErrorCode = HAL_JPEG_ERROR_NONE; + + /* Clear the context fields */ + hjpeg->Context = 0; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitializes the JPEG peripheral. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_DeInit(JPEG_HandleTypeDef *hjpeg) +{ + /* Check the JPEG handle allocation */ + if (hjpeg == NULL) + { + return HAL_ERROR; + } + +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + if (hjpeg->MspDeInitCallback == NULL) + { + hjpeg->MspDeInitCallback = HAL_JPEG_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hjpeg->MspDeInitCallback(hjpeg); + +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_JPEG_MspDeInit(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_BUSY; + + /* Reset the JPEG ErrorCode */ + hjpeg->ErrorCode = HAL_JPEG_ERROR_NONE; + + /* Reset JpegInCount and JpegOutCount */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_RESET; + + /*Clear the context fields*/ + hjpeg->Context = 0; + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the JPEG MSP. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +__weak void HAL_JPEG_MspInit(JPEG_HandleTypeDef *hjpeg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes JPEG MSP. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +__weak void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef *hjpeg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User JPEG Callback + * To be used to override the weak predefined callback + * @param hjpeg JPEG handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_JPEG_ENCODE_CPLT_CB_ID Encode Complete callback ID + * @arg @ref HAL_JPEG_DECODE_CPLT_CB_ID Decode Complete callback ID + * @arg @ref HAL_JPEG_ERROR_CB_ID Error callback ID + * @arg @ref HAL_JPEG_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_JPEG_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_RegisterCallback(JPEG_HandleTypeDef *hjpeg, HAL_JPEG_CallbackIDTypeDef CallbackID, + pJPEG_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + switch (CallbackID) + { + case HAL_JPEG_ENCODE_CPLT_CB_ID : + hjpeg->EncodeCpltCallback = pCallback; + break; + + case HAL_JPEG_DECODE_CPLT_CB_ID : + hjpeg->DecodeCpltCallback = pCallback; + break; + + case HAL_JPEG_ERROR_CB_ID : + hjpeg->ErrorCallback = pCallback; + break; + + case HAL_JPEG_MSPINIT_CB_ID : + hjpeg->MspInitCallback = pCallback; + break; + + case HAL_JPEG_MSPDEINIT_CB_ID : + hjpeg->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_JPEG_STATE_RESET == hjpeg->State) + { + switch (CallbackID) + { + case HAL_JPEG_MSPINIT_CB_ID : + hjpeg->MspInitCallback = pCallback; + break; + + case HAL_JPEG_MSPDEINIT_CB_ID : + hjpeg->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief Unregister a JPEG Callback + * JPEG callback is redirected to the weak predefined callback + * @param hjpeg JPEG handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_JPEG_ENCODE_CPLT_CB_ID Encode Complete callback ID + * @arg @ref HAL_JPEG_DECODE_CPLT_CB_ID Decode Complete callback ID + * @arg @ref HAL_JPEG_ERROR_CB_ID Error callback ID + * @arg @ref HAL_JPEG_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_JPEG_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_UnRegisterCallback(JPEG_HandleTypeDef *hjpeg, HAL_JPEG_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + switch (CallbackID) + { + case HAL_JPEG_ENCODE_CPLT_CB_ID : + hjpeg->EncodeCpltCallback = HAL_JPEG_EncodeCpltCallback; /* Legacy weak EncodeCpltCallback */ + break; + + case HAL_JPEG_DECODE_CPLT_CB_ID : + hjpeg->DecodeCpltCallback = HAL_JPEG_DecodeCpltCallback; /* Legacy weak DecodeCpltCallback */ + break; + + case HAL_JPEG_ERROR_CB_ID : + hjpeg->ErrorCallback = HAL_JPEG_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_JPEG_MSPINIT_CB_ID : + hjpeg->MspInitCallback = HAL_JPEG_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_JPEG_MSPDEINIT_CB_ID : + hjpeg->MspDeInitCallback = HAL_JPEG_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_JPEG_STATE_RESET == hjpeg->State) + { + switch (CallbackID) + { + case HAL_JPEG_MSPINIT_CB_ID : + hjpeg->MspInitCallback = HAL_JPEG_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_JPEG_MSPDEINIT_CB_ID : + hjpeg->MspDeInitCallback = HAL_JPEG_MspDeInit; /* Legacy weak MspInit */ + break; + + default : + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief Register Info Ready JPEG Callback + * To be used instead of the weak HAL_JPEG_InfoReadyCallback() predefined callback + * @param hjpeg JPEG handle + * @param pCallback pointer to the Info Ready Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_RegisterInfoReadyCallback(JPEG_HandleTypeDef *hjpeg, + pJPEG_InfoReadyCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + hjpeg->InfoReadyCallback = pCallback; + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief UnRegister the Info Ready JPEG Callback + * Info Ready JPEG Callback is redirected to the weak HAL_JPEG_InfoReadyCallback() predefined callback + * @param hjpeg JPEG handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_UnRegisterInfoReadyCallback(JPEG_HandleTypeDef *hjpeg) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + hjpeg->InfoReadyCallback = HAL_JPEG_InfoReadyCallback; /* Legacy weak InfoReadyCallback */ + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief Register Get Data JPEG Callback + * To be used instead of the weak HAL_JPEG_GetDataCallback() predefined callback + * @param hjpeg JPEG handle + * @param pCallback pointer to the Get Data Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_RegisterGetDataCallback(JPEG_HandleTypeDef *hjpeg, pJPEG_GetDataCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + hjpeg->GetDataCallback = pCallback; + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief UnRegister the Get Data JPEG Callback + * Get Data JPEG Callback is redirected to the weak HAL_JPEG_GetDataCallback() predefined callback + * @param hjpeg JPEG handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_UnRegisterGetDataCallback(JPEG_HandleTypeDef *hjpeg) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + hjpeg->GetDataCallback = HAL_JPEG_GetDataCallback; /* Legacy weak GetDataCallback */ + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief Register Data Ready JPEG Callback + * To be used instead of the weak HAL_JPEG_DataReadyCallback() predefined callback + * @param hjpeg JPEG handle + * @param pCallback pointer to the Get Data Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_RegisterDataReadyCallback(JPEG_HandleTypeDef *hjpeg, + pJPEG_DataReadyCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + hjpeg->DataReadyCallback = pCallback; + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +/** + * @brief UnRegister the Data Ready JPEG Callback + * Get Data Ready Callback is redirected to the weak HAL_JPEG_DataReadyCallback() predefined callback + * @param hjpeg JPEG handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_UnRegisterDataReadyCallback(JPEG_HandleTypeDef *hjpeg) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (HAL_JPEG_STATE_READY == hjpeg->State) + { + hjpeg->DataReadyCallback = HAL_JPEG_DataReadyCallback; /* Legacy weak DataReadyCallback */ + } + else + { + /* Update the error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hjpeg); + return status; +} + +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup JPEG_Exported_Functions_Group2 Configuration functions + * @brief JPEG Configuration functions. + * +@verbatim + ============================================================================== + ##### Configuration functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) HAL_JPEG_ConfigEncoding() : JPEG encoding configuration + (+) HAL_JPEG_GetInfo() : Extract the image configuration from the JPEG header during the decoding + (+) HAL_JPEG_EnableHeaderParsing() : Enable JPEG Header parsing for decoding + (+) HAL_JPEG_DisableHeaderParsing() : Disable JPEG Header parsing for decoding + (+) HAL_JPEG_SetUserQuantTables : Modify the default Quantization tables used for JPEG encoding. + +@endverbatim + * @{ + */ + +/** + * @brief Set the JPEG encoding configuration. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pConf pointer to a JPEG_ConfTypeDef structure that contains + * the encoding configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_ConfigEncoding(JPEG_HandleTypeDef *hjpeg, const JPEG_ConfTypeDef *pConf) +{ + uint32_t error; + uint32_t numberMCU; + uint32_t hfactor; + uint32_t vfactor; + uint32_t hMCU; + uint32_t vMCU; + + /* Check the JPEG handle allocation */ + if ((hjpeg == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + else + { + /* Check the parameters */ + assert_param(IS_JPEG_COLORSPACE(pConf->ColorSpace)); + assert_param(IS_JPEG_CHROMASUBSAMPLING(pConf->ChromaSubsampling)); + assert_param(IS_JPEG_IMAGE_QUALITY(pConf->ImageQuality)); + + /* Process Locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + hjpeg->State = HAL_JPEG_STATE_BUSY; + + hjpeg->Conf.ColorSpace = pConf->ColorSpace; + hjpeg->Conf.ChromaSubsampling = pConf->ChromaSubsampling; + hjpeg->Conf.ImageHeight = pConf->ImageHeight; + hjpeg->Conf.ImageWidth = pConf->ImageWidth; + hjpeg->Conf.ImageQuality = pConf->ImageQuality; + + /* Reset the Color Space : by default only one quantization table is used*/ + hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_COLORSPACE; + + /* Set Number of color components*/ + if (hjpeg->Conf.ColorSpace == JPEG_GRAYSCALE_COLORSPACE) + { + /*Gray Scale is only one component 8x8 blocks i.e 4:4:4*/ + hjpeg->Conf.ChromaSubsampling = JPEG_444_SUBSAMPLING; + + JPEG_SetColorGrayScale(hjpeg); + /* Set quantization table 0*/ + error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (hjpeg->Instance->QMEM0)); + } + else if (hjpeg->Conf.ColorSpace == JPEG_YCBCR_COLORSPACE) + { + /* + Set the Color Space for YCbCr : 2 quantization tables are used + one for Luminance(Y) and one for both Chrominances (Cb & Cr) + */ + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_COLORSPACE_0; + + JPEG_SetColorYCBCR(hjpeg); + + /* Set quantization table 0*/ + error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (hjpeg->Instance->QMEM0)); + /*By default quantization table 0 for component 0 and quantization table 1 for both components 1 and 2*/ + (void) JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable1, (hjpeg->Instance->QMEM1)); + + if ((hjpeg->Context & JPEG_CONTEXT_CUSTOM_TABLES) != 0UL) + { + /*Use user customized quantization tables , 1 table per component*/ + /* use 3 quantization tables , one for each component*/ + hjpeg->Instance->CONFR1 &= (~JPEG_CONFR1_COLORSPACE); + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_COLORSPACE_1; + + (void) JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable2, (hjpeg->Instance->QMEM2)); + + /*Use Quantization 1 table for component 1*/ + hjpeg->Instance->CONFR5 &= (~JPEG_CONFR5_QT); + hjpeg->Instance->CONFR5 |= JPEG_CONFR5_QT_0; + + /*Use Quantization 2 table for component 2*/ + hjpeg->Instance->CONFR6 &= (~JPEG_CONFR6_QT); + hjpeg->Instance->CONFR6 |= JPEG_CONFR6_QT_1; + } + } + else /* ColorSpace == JPEG_CMYK_COLORSPACE */ + { + JPEG_SetColorCMYK(hjpeg); + + /* Set quantization table 0*/ + error = JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable0, (hjpeg->Instance->QMEM0)); + /*By default quantization table 0 for All components*/ + + if ((hjpeg->Context & JPEG_CONTEXT_CUSTOM_TABLES) != 0UL) + { + /*Use user customized quantization tables , 1 table per component*/ + /* use 4 quantization tables , one for each component*/ + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_COLORSPACE; + + (void) JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable1, (hjpeg->Instance->QMEM1)); + (void) JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable2, (hjpeg->Instance->QMEM2)); + (void) JPEG_Set_Quantization_Mem(hjpeg, hjpeg->QuantTable3, (hjpeg->Instance->QMEM3)); + + /*Use Quantization 1 table for component 1*/ + hjpeg->Instance->CONFR5 |= JPEG_CONFR5_QT_0; + + /*Use Quantization 2 table for component 2*/ + hjpeg->Instance->CONFR6 |= JPEG_CONFR6_QT_1; + + /*Use Quantization 3 table for component 3*/ + hjpeg->Instance->CONFR7 |= JPEG_CONFR7_QT; + } + } + + if (error != 0UL) + { + hjpeg->ErrorCode = HAL_JPEG_ERROR_QUANT_TABLE; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Set the JPEG State to ready */ + hjpeg->State = HAL_JPEG_STATE_READY; + + return HAL_ERROR; + } + /* Set the image size*/ + /* set the number of lines*/ + MODIFY_REG(hjpeg->Instance->CONFR1, JPEG_CONFR1_YSIZE, ((hjpeg->Conf.ImageHeight & 0x0000FFFFUL) << 16)); + /* set the number of pixels per line*/ + MODIFY_REG(hjpeg->Instance->CONFR3, JPEG_CONFR3_XSIZE, ((hjpeg->Conf.ImageWidth & 0x0000FFFFUL) << 16)); + + + if (hjpeg->Conf.ChromaSubsampling == JPEG_420_SUBSAMPLING) /* 4:2:0*/ + { + hfactor = 16; + vfactor = 16; + } + else if (hjpeg->Conf.ChromaSubsampling == JPEG_422_SUBSAMPLING) /* 4:2:2*/ + { + hfactor = 16; + vfactor = 8; + } + else /* Default is 8x8 MCU, 4:4:4*/ + { + hfactor = 8; + vfactor = 8; + } + + hMCU = (hjpeg->Conf.ImageWidth / hfactor); + if ((hjpeg->Conf.ImageWidth % hfactor) != 0UL) + { + hMCU++; /*+1 for horizontal incomplete MCU */ + } + + vMCU = (hjpeg->Conf.ImageHeight / vfactor); + if ((hjpeg->Conf.ImageHeight % vfactor) != 0UL) + { + vMCU++; /*+1 for vertical incomplete MCU */ + } + + numberMCU = (hMCU * vMCU) - 1UL; /* Bit Field JPEG_CONFR2_NMCU shall be set to NB_MCU - 1*/ + /* Set the number of MCU*/ + hjpeg->Instance->CONFR2 = (numberMCU & JPEG_CONFR2_NMCU); + + hjpeg->Context |= JPEG_CONTEXT_CONF_ENCODING; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Set the JPEG State to ready */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Return function status */ + return HAL_BUSY; + } + } +} + +/** + * @brief Extract the image configuration from the JPEG header during the decoding + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pInfo pointer to a JPEG_ConfTypeDef structure that contains + * The JPEG decoded header information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) +{ + uint32_t yblockNb; + uint32_t cBblockNb; + uint32_t cRblockNb; + + /* Check the JPEG handle allocation */ + if ((hjpeg == NULL) || (pInfo == NULL)) + { + return HAL_ERROR; + } + + /*Read the conf parameters */ + if ((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF_1) + { + pInfo->ColorSpace = JPEG_YCBCR_COLORSPACE; + } + else if ((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == 0UL) + { + pInfo->ColorSpace = JPEG_GRAYSCALE_COLORSPACE; + } + else if ((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF) + { + pInfo->ColorSpace = JPEG_CMYK_COLORSPACE; + } + else + { + return HAL_ERROR; + } + + pInfo->ImageHeight = (hjpeg->Instance->CONFR1 & 0xFFFF0000UL) >> 16; + pInfo->ImageWidth = (hjpeg->Instance->CONFR3 & 0xFFFF0000UL) >> 16; + + if ((pInfo->ColorSpace == JPEG_YCBCR_COLORSPACE) || (pInfo->ColorSpace == JPEG_CMYK_COLORSPACE)) + { + yblockNb = (hjpeg->Instance->CONFR4 & JPEG_CONFR4_NB) >> 4; + cBblockNb = (hjpeg->Instance->CONFR5 & JPEG_CONFR5_NB) >> 4; + cRblockNb = (hjpeg->Instance->CONFR6 & JPEG_CONFR6_NB) >> 4; + + if ((yblockNb == 1UL) && (cBblockNb == 0UL) && (cRblockNb == 0UL)) + { + pInfo->ChromaSubsampling = JPEG_422_SUBSAMPLING; /*16x8 block*/ + } + else if ((yblockNb == 0UL) && (cBblockNb == 0UL) && (cRblockNb == 0UL)) + { + pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; + } + else if ((yblockNb == 3UL) && (cBblockNb == 0UL) && (cRblockNb == 0UL)) + { + pInfo->ChromaSubsampling = JPEG_420_SUBSAMPLING; + } + else /*Default is 4:4:4*/ + { + pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; + } + } + else + { + pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; + } + + pInfo->ImageQuality = JPEG_GetQuality(hjpeg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enable JPEG Header parsing for decoding + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for the JPEG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_EnableHeaderParsing(JPEG_HandleTypeDef *hjpeg) +{ + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_BUSY; + + /* Enable header processing*/ + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_HDR; + + /* Process unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + return HAL_OK; + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } +} + +/** + * @brief Disable JPEG Header parsing for decoding + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for the JPEG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_DisableHeaderParsing(JPEG_HandleTypeDef *hjpeg) +{ + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_BUSY; + + /* Disable header processing*/ + hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_HDR; + + /* Process unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + return HAL_OK; + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } +} + +/** + * @brief Modify the default Quantization tables used for JPEG encoding. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param QTable0 pointer to uint8_t , define the user quantification table for color component 1. + * If NULL assume no need to update the table and no error return + * @param QTable1 pointer to uint8_t , define the user quantification table for color component 2. + * If NULL assume no need to update the table and no error return. + * @param QTable2 pointer to uint8_t , define the user quantification table for color component 3, + * If NULL assume no need to update the table and no error return. + * @param QTable3 pointer to uint8_t , define the user quantification table for color component 4. + * If NULL assume no need to update the table and no error return. + * + * @retval HAL status + */ + + +HAL_StatusTypeDef HAL_JPEG_SetUserQuantTables(JPEG_HandleTypeDef *hjpeg, uint8_t *QTable0, uint8_t *QTable1, + uint8_t *QTable2, uint8_t *QTable3) +{ + /* Process Locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + /* Change the DMA state */ + hjpeg->State = HAL_JPEG_STATE_BUSY; + + hjpeg->Context |= JPEG_CONTEXT_CUSTOM_TABLES; + + hjpeg->QuantTable0 = QTable0; + hjpeg->QuantTable1 = QTable1; + hjpeg->QuantTable2 = QTable2; + hjpeg->QuantTable3 = QTable3; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Change the DMA state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } +} + +/** + * @} + */ + +/** @defgroup JPEG_Exported_Functions_Group3 encoding/decoding processing functions + * @brief processing functions. + * +@verbatim + ============================================================================== + ##### JPEG processing functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) HAL_JPEG_Encode() : JPEG encoding with polling process + (+) HAL_JPEG_Decode() : JPEG decoding with polling process + (+) HAL_JPEG_Encode_IT() : JPEG encoding with interrupt process + (+) HAL_JPEG_Decode_IT() : JPEG decoding with interrupt process + (+) HAL_JPEG_Encode_DMA() : JPEG encoding with DMA process + (+) HAL_JPEG_Decode_DMA() : JPEG decoding with DMA process + (+) HAL_JPEG_Pause() : Pause the Input/Output processing + (+) HAL_JPEG_Resume() : Resume the JPEG Input/Output processing + (+) HAL_JPEG_ConfigInputBuffer() : Config Encoding/Decoding Input Buffer + (+) HAL_JPEG_ConfigOutputBuffer() : Config Encoding/Decoding Output Buffer + (+) HAL_JPEG_Abort() : Aborts the JPEG Encoding/Decoding + +@endverbatim + * @{ + */ + +/** + * @brief Starts JPEG encoding with polling processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataInMCU Pointer to the Input buffer + * @param InDataLength size in bytes Input buffer + * @param pDataOut Pointer to the jpeg output data buffer + * @param OutDataLength size in bytes of the Output buffer + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Encode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, + uint8_t *pDataOut, uint32_t OutDataLength, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param((InDataLength >= 4UL)); + assert_param((OutDataLength >= 4UL)); + + /* Check In/out buffer allocation and size */ + if ((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL)) + { + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State != HAL_JPEG_STATE_READY) + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + if ((hjpeg->Context & JPEG_CONTEXT_CONF_ENCODING) == JPEG_CONTEXT_CONF_ENCODING) + { + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_BUSY_ENCODING; + + /*Set the Context to Encode with Polling*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); + hjpeg->Context |= (JPEG_CONTEXT_ENCODE | JPEG_CONTEXT_POLLING); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /*Store In/out buffers pointers and size*/ + hjpeg->pJpegInBuffPtr = pDataInMCU; + hjpeg->pJpegOutBuffPtr = pDataOut; + hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /* In Data length must be multiple + of 4 Bytes (1 word)*/ + hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /* Out Data length must be multiple + of 4 Bytes (1 word)*/ + + /*Reset In/out data counter */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Init decoding process*/ + JPEG_Init_Process(hjpeg); + + /*JPEG data processing : In/Out FIFO transfer*/ + while ((JPEG_Process(hjpeg) == JPEG_PROCESS_ONGOING)) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + + /* Update error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_READY; + + return HAL_TIMEOUT; + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_READY; + + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts JPEG decoding with polling processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataIn Pointer to the input data buffer + * @param InDataLength size in bytes Input buffer + * @param pDataOutMCU Pointer to the Output data buffer + * @param OutDataLength size in bytes of the Output buffer + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Decode(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, + uint8_t *pDataOutMCU, uint32_t OutDataLength, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param((InDataLength >= 4UL)); + assert_param((OutDataLength >= 4UL)); + + /* Check In/out buffer allocation and size */ + if ((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hjpeg); + + /* Get tick */ + tickstart = HAL_GetTick(); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; + + /*Set the Context to Decode with Polling*/ + /*Set the Context to Encode with Polling*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); + hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_POLLING); + + /*Store In/out buffers pointers and size*/ + hjpeg->pJpegInBuffPtr = pDataIn; + hjpeg->pJpegOutBuffPtr = pDataOutMCU; + hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /*In Data length must be multiple + of 4 Bytes (1 word)*/ + hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /*Out Data length must be multiple + of 4 Bytes (1 word)*/ + + /*Reset In/out data counter */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Init decoding process*/ + JPEG_Init_Process(hjpeg); + + /*JPEG data processing : In/Out FIFO transfer*/ + while ((JPEG_Process(hjpeg) == JPEG_PROCESS_ONGOING)) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + + /* Update error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_READY; + + return HAL_TIMEOUT; + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_READY; + + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts JPEG encoding with interrupt processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataInMCU Pointer to the Input buffer + * @param InDataLength size in bytes Input buffer + * @param pDataOut Pointer to the jpeg output data buffer + * @param OutDataLength size in bytes of the Output buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Encode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, + uint8_t *pDataOut, uint32_t OutDataLength) +{ + /* Check the parameters */ + assert_param((InDataLength >= 4UL)); + assert_param((OutDataLength >= 4UL)); + + /* Check In/out buffer allocation and size */ + if ((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State != HAL_JPEG_STATE_READY) + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } + else + { + if ((hjpeg->Context & JPEG_CONTEXT_CONF_ENCODING) == JPEG_CONTEXT_CONF_ENCODING) + { + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_BUSY_ENCODING; + + /*Set the Context to Encode with IT*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); + hjpeg->Context |= (JPEG_CONTEXT_ENCODE | JPEG_CONTEXT_IT); + + /*Store In/out buffers pointers and size*/ + hjpeg->pJpegInBuffPtr = pDataInMCU; + hjpeg->pJpegOutBuffPtr = pDataOut; + hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /*In Data length must be multiple + of 4 Bytes (1 word)*/ + hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /*Out Data length must be multiple + of 4 Bytes (1 word)*/ + + /*Reset In/out data counter */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Init decoding process*/ + JPEG_Init_Process(hjpeg); + + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts JPEG decoding with interrupt processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataIn Pointer to the input data buffer + * @param InDataLength size in bytes Input buffer + * @param pDataOutMCU Pointer to the Output data buffer + * @param OutDataLength size in bytes of the Output buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Decode_IT(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, + uint8_t *pDataOutMCU, uint32_t OutDataLength) +{ + /* Check the parameters */ + assert_param((InDataLength >= 4UL)); + assert_param((OutDataLength >= 4UL)); + + /* Check In/out buffer allocation and size */ + if ((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; + + /*Set the Context to Decode with IT*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); + hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_IT); + + /*Store In/out buffers pointers and size*/ + hjpeg->pJpegInBuffPtr = pDataIn; + hjpeg->pJpegOutBuffPtr = pDataOutMCU; + hjpeg->InDataLength = InDataLength - (InDataLength % 4UL); /*In Data length must be multiple + of 4 Bytes (1 word)*/ + hjpeg->OutDataLength = OutDataLength - (OutDataLength % 4UL); /*Out Data length must be multiple + of 4 Bytes (1 word)*/ + + /*Reset In/out data counter */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Init decoding process*/ + JPEG_Init_Process(hjpeg); + + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts JPEG encoding with DMA processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataInMCU Pointer to the Input buffer + * @param InDataLength size in bytes Input buffer + * @param pDataOut Pointer to the jpeg output data buffer + * @param OutDataLength size in bytes of the Output buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Encode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataInMCU, uint32_t InDataLength, + uint8_t *pDataOut, uint32_t OutDataLength) +{ + /* Check the parameters */ + assert_param((InDataLength >= 4UL)); + assert_param((OutDataLength >= 4UL)); + + /* Check In/out buffer allocation and size */ + if ((hjpeg == NULL) || (pDataInMCU == NULL) || (pDataOut == NULL)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State != HAL_JPEG_STATE_READY) + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } + else + { + if ((hjpeg->Context & JPEG_CONTEXT_CONF_ENCODING) == JPEG_CONTEXT_CONF_ENCODING) + { + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_BUSY_ENCODING; + + /*Set the Context to Encode with DMA*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); + hjpeg->Context |= (JPEG_CONTEXT_ENCODE | JPEG_CONTEXT_DMA); + + /*Store In/out buffers pointers and size*/ + hjpeg->pJpegInBuffPtr = pDataInMCU; + hjpeg->pJpegOutBuffPtr = pDataOut; + hjpeg->InDataLength = InDataLength; + hjpeg->OutDataLength = OutDataLength; + + /*Reset In/out data counter */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Init decoding process*/ + JPEG_Init_Process(hjpeg); + + /* JPEG encoding process using DMA */ + if (JPEG_DMA_StartProcess(hjpeg) != HAL_OK) + { + /* Update State */ + hjpeg->State = HAL_JPEG_STATE_ERROR; + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts JPEG decoding with DMA processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataIn Pointer to the input data buffer + * @param InDataLength size in bytes Input buffer + * @param pDataOutMCU Pointer to the Output data buffer + * @param OutDataLength size in bytes of the Output buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataIn, uint32_t InDataLength, + uint8_t *pDataOutMCU, uint32_t OutDataLength) +{ + /* Check the parameters */ + assert_param((InDataLength >= 4UL)); + assert_param((OutDataLength >= 4UL)); + + /* Check In/out buffer allocation and size */ + if ((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hjpeg); + + if (hjpeg->State == HAL_JPEG_STATE_READY) + { + /*Change JPEG state*/ + hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; + + /*Set the Context to Decode with DMA*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); + hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_DMA); + + /*Store In/out buffers pointers and size*/ + hjpeg->pJpegInBuffPtr = pDataIn; + hjpeg->pJpegOutBuffPtr = pDataOutMCU; + hjpeg->InDataLength = InDataLength; + hjpeg->OutDataLength = OutDataLength; + + /*Reset In/out data counter */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Init decoding process*/ + JPEG_Init_Process(hjpeg); + + /* JPEG decoding process using DMA */ + if (JPEG_DMA_StartProcess(hjpeg) != HAL_OK) + { + /* Update State */ + hjpeg->State = HAL_JPEG_STATE_ERROR; + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_BUSY; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Pause the JPEG Input/Output processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param XferSelection This parameter can be one of the following values : + * JPEG_PAUSE_RESUME_INPUT : Pause Input processing + * JPEG_PAUSE_RESUME_OUTPUT: Pause Output processing + * JPEG_PAUSE_RESUME_INPUT_OUTPUT: Pause Input and Output processing + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Pause(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) +{ + uint32_t mask = 0; + + assert_param(IS_JPEG_PAUSE_RESUME_STATE(XferSelection)); + + if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) + { + if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) + { + hjpeg->Context |= JPEG_CONTEXT_PAUSE_INPUT; + mask |= JPEG_DMA_IDMA; + } + if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) + { + hjpeg->Context |= JPEG_CONTEXT_PAUSE_OUTPUT; + mask |= JPEG_DMA_ODMA; + } + JPEG_DISABLE_DMA(hjpeg, mask); + + } + else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) + { + + if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) + { + hjpeg->Context |= JPEG_CONTEXT_PAUSE_INPUT; + mask |= (JPEG_IT_IFT | JPEG_IT_IFNF); + } + if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) + { + hjpeg->Context |= JPEG_CONTEXT_PAUSE_OUTPUT; + mask |= (JPEG_IT_OFT | JPEG_IT_OFNE | JPEG_IT_EOC); + } + __HAL_JPEG_DISABLE_IT(hjpeg, mask); + + } + else + { + /* Nothing to do */ + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Resume the JPEG Input/Output processing + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param XferSelection This parameter can be one of the following values : + * JPEG_PAUSE_RESUME_INPUT : Resume Input processing + * JPEG_PAUSE_RESUME_OUTPUT: Resume Output processing + * JPEG_PAUSE_RESUME_INPUT_OUTPUT: Resume Input and Output processing + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) +{ + uint32_t mask = 0; + + assert_param(IS_JPEG_PAUSE_RESUME_STATE(XferSelection)); + + if ((hjpeg->Context & (JPEG_CONTEXT_PAUSE_INPUT | JPEG_CONTEXT_PAUSE_OUTPUT)) == 0UL) + { + /* if nothing paused to resume return error*/ + return HAL_ERROR; + } + + if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) + { + + if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) + { + hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_INPUT); + mask |= JPEG_DMA_IDMA; + + /*JPEG Input DMA transfer data number must be multiple of DMA buffer size + as the destination is a 32 bits register */ + hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4UL); + + if (hjpeg->InDataLength > 0UL) + { + /* Start DMA FIFO In transfer */ + if (HAL_DMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, + hjpeg->InDataLength) != HAL_OK) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + hjpeg->State = HAL_JPEG_STATE_ERROR; + return HAL_ERROR; + } + } + } + if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) + { + hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_OUTPUT); + + if ((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) != 0UL) + { + JPEG_DMA_PollResidualData(hjpeg); + } + else + { + mask |= JPEG_DMA_ODMA; + + /* Start DMA FIFO Out transfer */ + if (HAL_DMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, + hjpeg->OutDataLength) != HAL_OK) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + hjpeg->State = HAL_JPEG_STATE_ERROR; + return HAL_ERROR; + } + } + + } + JPEG_ENABLE_DMA(hjpeg, mask); + + } + else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) + { + if ((XferSelection & JPEG_PAUSE_RESUME_INPUT) == JPEG_PAUSE_RESUME_INPUT) + { + hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_INPUT); + mask |= (JPEG_IT_IFT | JPEG_IT_IFNF); + } + if ((XferSelection & JPEG_PAUSE_RESUME_OUTPUT) == JPEG_PAUSE_RESUME_OUTPUT) + { + hjpeg->Context &= (~JPEG_CONTEXT_PAUSE_OUTPUT); + mask |= (JPEG_IT_OFT | JPEG_IT_OFNE | JPEG_IT_EOC); + } + __HAL_JPEG_ENABLE_IT(hjpeg, mask); + + } + else + { + /* Nothing to do */ + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Config Encoding/Decoding Input Buffer. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module. + * @param pNewInputBuffer Pointer to the new input data buffer + * @param InDataLength Size in bytes of the new Input data buffer + * @retval HAL status + */ +void HAL_JPEG_ConfigInputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewInputBuffer, uint32_t InDataLength) +{ + hjpeg->pJpegInBuffPtr = pNewInputBuffer; + hjpeg->InDataLength = InDataLength; +} + +/** + * @brief Config Encoding/Decoding Output Buffer. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module. + * @param pNewOutputBuffer Pointer to the new output data buffer + * @param OutDataLength Size in bytes of the new Output data buffer + * @retval HAL status + */ +void HAL_JPEG_ConfigOutputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewOutputBuffer, uint32_t OutDataLength) +{ + hjpeg->pJpegOutBuffPtr = pNewOutputBuffer; + hjpeg->OutDataLength = OutDataLength; +} + +/** + * @brief Aborts the JPEG Encoding/Decoding. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_JPEG_Abort(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t tickstart; + uint32_t tmpContext; + tmpContext = hjpeg->Context; + + /*Reset the Context operation and method*/ + hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK | JPEG_CONTEXT_ENDING_DMA); + + if ((tmpContext & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) + { + /* Stop the DMA In/out Xfer*/ + if (HAL_DMA_Abort(hjpeg->hdmaout) != HAL_OK) + { + if (hjpeg->hdmaout->ErrorCode == HAL_DMA_ERROR_TIMEOUT) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + } + } + if (HAL_DMA_Abort(hjpeg->hdmain) != HAL_OK) + { + if (hjpeg->hdmain->ErrorCode == HAL_DMA_ERROR_TIMEOUT) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + } + } + + } + + /* Stop the JPEG encoding/decoding process*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the JPEG Codec is effectively disabled */ + while (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_COF) != 0UL) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > JPEG_TIMEOUT_VALUE) + { + /* Update error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_TIMEOUT; + + /* Change the DMA state */ + hjpeg->State = HAL_JPEG_STATE_ERROR; + break; + } + } + + /* Disable All Interrupts */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + /* Disable All DMA requests */ + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_MASK); + + /* Flush input and output FIFOs*/ + hjpeg->Instance->CR |= JPEG_CR_IFF; + hjpeg->Instance->CR |= JPEG_CR_OFF; + + /* Clear all flags */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); + + /* Reset JpegInCount and JpegOutCount */ + hjpeg->JpegInCount = 0; + hjpeg->JpegOutCount = 0; + + /*Reset the Context Pause*/ + hjpeg->Context &= ~(JPEG_CONTEXT_PAUSE_INPUT | JPEG_CONTEXT_PAUSE_OUTPUT); + + /* Change the DMA state*/ + if (hjpeg->ErrorCode != HAL_JPEG_ERROR_NONE) + { + hjpeg->State = HAL_JPEG_STATE_ERROR; + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + /* Return function status */ + return HAL_ERROR; + } + else + { + hjpeg->State = HAL_JPEG_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + /* Return function status */ + return HAL_OK; + } + +} + + +/** + * @} + */ + +/** @defgroup JPEG_Exported_Functions_Group4 JPEG Decode/Encode callback functions + * @brief JPEG process callback functions. + * +@verbatim + ============================================================================== + ##### JPEG Decode and Encode callback functions ##### + ============================================================================== + [..] This section provides callback functions: + (+) HAL_JPEG_InfoReadyCallback() : Decoding JPEG Info ready callback + (+) HAL_JPEG_EncodeCpltCallback() : Encoding complete callback. + (+) HAL_JPEG_DecodeCpltCallback() : Decoding complete callback. + (+) HAL_JPEG_ErrorCallback() : JPEG error callback. + (+) HAL_JPEG_GetDataCallback() : Get New Data chunk callback. + (+) HAL_JPEG_DataReadyCallback() : Decoded/Encoded Data ready callback. + +@endverbatim + * @{ + */ + +/** + * @brief Decoding JPEG Info ready callback. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pInfo pointer to a JPEG_ConfTypeDef structure that contains + * The JPEG decoded header information + * @retval None + */ +__weak void HAL_JPEG_InfoReadyCallback(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + UNUSED(pInfo); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_HeaderParsingCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Encoding complete callback. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +__weak void HAL_JPEG_EncodeCpltCallback(JPEG_HandleTypeDef *hjpeg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_EncodeCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Decoding complete callback. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +__weak void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef *hjpeg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_EncodeCpltCallback could be implemented in the user file + */ +} + +/** + * @brief JPEG error callback. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +__weak void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef *hjpeg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Get New Data chunk callback. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param NbDecodedData Number of consumed data in the previous chunk in bytes + * @retval None + */ +__weak void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef *hjpeg, uint32_t NbDecodedData) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + UNUSED(NbDecodedData); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_GetDataCallback could be implemented in the user file + */ +} + +/** + * @brief Decoded/Encoded Data ready callback. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param pDataOut pointer to the output data buffer + * @param OutDataLength number in bytes of data available in the specified output buffer + * @retval None + */ +__weak void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, uint32_t OutDataLength) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hjpeg); + UNUSED(pDataOut); + UNUSED(OutDataLength); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_JPEG_DataReadyCallback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** @defgroup JPEG_Exported_Functions_Group5 JPEG IRQ handler management + * @brief JPEG IRQ handler. + * +@verbatim + ============================================================================== + ##### JPEG IRQ handler management ##### + ============================================================================== + [..] This section provides JPEG IRQ handler function. + (+) HAL_JPEG_IRQHandler() : handles JPEG interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief This function handles JPEG interrupt request. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +void HAL_JPEG_IRQHandler(JPEG_HandleTypeDef *hjpeg) +{ + switch (hjpeg->State) + { + case HAL_JPEG_STATE_BUSY_ENCODING: + case HAL_JPEG_STATE_BUSY_DECODING: + /* continue JPEG data encoding/Decoding*/ + /* JPEG data processing : In/Out FIFO transfer*/ + if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) + { + (void) JPEG_Process(hjpeg); + } + else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) + { + JPEG_DMA_ContinueProcess(hjpeg); + } + else + { + /* Nothing to do */ + } + break; + + default: + break; + } +} + +/** + * @} + */ + +/** @defgroup JPEG_Exported_Functions_Group6 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] This section provides JPEG State and Errors function. + (+) HAL_JPEG_GetState() : permits to get in run-time the JPEG state. + (+) HAL_JPEG_GetError() : Returns the JPEG error code if any. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the JPEG state. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval JPEG state + */ +HAL_JPEG_STATETypeDef HAL_JPEG_GetState(const JPEG_HandleTypeDef *hjpeg) +{ + return hjpeg->State; +} + +/** + * @brief Return the JPEG error code + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for the specified JPEG. + * @retval JPEG Error Code + */ +uint32_t HAL_JPEG_GetError(const JPEG_HandleTypeDef *hjpeg) +{ + return hjpeg->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + + +/** @addtogroup JPEG_Private_Functions + * @{ + */ + +/** + * @brief Generates Huffman sizes/Codes Table from Bits/vals Table + * @param Bits pointer to bits table + * @param Huffsize pointer to sizes table + * @param Huffcode pointer to codes table + * @param LastK pointer to last Coeff (table dimension) + * @retval HAL status + */ +static HAL_StatusTypeDef JPEG_Bits_To_SizeCodes(const uint8_t *Bits, uint8_t *Huffsize, uint32_t *Huffcode, + uint32_t *LastK) +{ + uint32_t i; + uint32_t j; + uint32_t k; + uint32_t code; + uint32_t si; + + /* Figure C.1: Generation of table of Huffman code sizes */ + j = 0; + for (k = 0; k < 16UL; k++) + { + i = (uint32_t)Bits[k]; + if ((j + i) > 256UL) + { + /* check for table overflow */ + return HAL_ERROR; + } + while (i != 0UL) + { + Huffsize[j] = (uint8_t) k + 1U; + j++; + i--; + } + } + Huffsize[j] = 0; + *LastK = j; + + /* Figure C.2: Generation of table of Huffman codes */ + code = 0; + si = Huffsize[0]; + j = 0; + while (Huffsize[j] != 0U) + { + while (((uint32_t) Huffsize[j]) == si) + { + Huffcode[j] = code; + j++; + code++; + } + /* code must fit in "size" bits (si), no code is allowed to be all ones*/ + if (si > 31UL) + { + return HAL_ERROR; + } + if (((uint32_t) code) >= (((uint32_t) 1) << si)) + { + return HAL_ERROR; + } + code <<= 1; + si++; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Transform a Bits/Vals AC Huffman table to sizes/Codes huffman Table + * that can programmed to the JPEG encoder registers + * @param AC_BitsValsTable pointer to AC huffman bits/vals table + * @param AC_SizeCodesTable pointer to AC huffman Sizes/Codes table + * @retval HAL status + */ +static HAL_StatusTypeDef JPEG_ACHuff_BitsVals_To_SizeCodes(JPEG_ACHuffTableTypeDef *AC_BitsValsTable, + JPEG_AC_HuffCodeTableTypeDef *AC_SizeCodesTable) +{ + HAL_StatusTypeDef error; + uint8_t huffsize[257]; + uint32_t huffcode[257]; + uint32_t k; + uint32_t i; + uint32_t lsb; + uint32_t msb; + uint32_t lastK; + + error = JPEG_Bits_To_SizeCodes(AC_BitsValsTable->Bits, huffsize, huffcode, &lastK); + if (error != HAL_OK) + { + return error; + } + + /* Figure C.3: Ordering procedure for encoding procedure code tables */ + k = 0; + + while (k < lastK) + { + i = AC_BitsValsTable->HuffVal[k]; + if (i == 0UL) + { + i = JPEG_AC_HUFF_TABLE_SIZE - 2UL; /*i = 0x00 EOB code*/ + } + else if (i == 0xF0UL) /* i = 0xF0 ZRL code*/ + { + i = JPEG_AC_HUFF_TABLE_SIZE - 1UL; + } + else + { + msb = (i & 0xF0UL) >> 4; + lsb = (i & 0x0FUL); + i = (msb * 10UL) + lsb - 1UL; + } + if (i >= JPEG_AC_HUFF_TABLE_SIZE) + { + return HAL_ERROR; /* Huffman Table overflow error*/ + } + else + { + AC_SizeCodesTable->HuffmanCode[i] = huffcode[k]; + AC_SizeCodesTable->CodeLength[i] = huffsize[k] - 1U; + k++; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Transform a Bits/Vals DC Huffman table to sizes/Codes huffman Table + * that can programmed to the JPEG encoder registers + * @param DC_BitsValsTable pointer to DC huffman bits/vals table + * @param DC_SizeCodesTable pointer to DC huffman Sizes/Codes table + * @retval HAL status + */ +static HAL_StatusTypeDef JPEG_DCHuff_BitsVals_To_SizeCodes(JPEG_DCHuffTableTypeDef *DC_BitsValsTable, + JPEG_DC_HuffCodeTableTypeDef *DC_SizeCodesTable) +{ + HAL_StatusTypeDef error; + + uint32_t k; + uint32_t i; + uint32_t lastK; + uint8_t huffsize[257]; + uint32_t huffcode[257]; + error = JPEG_Bits_To_SizeCodes(DC_BitsValsTable->Bits, huffsize, huffcode, &lastK); + if (error != HAL_OK) + { + return error; + } + /* Figure C.3: ordering procedure for encoding procedure code tables */ + k = 0; + + while (k < lastK) + { + i = DC_BitsValsTable->HuffVal[k]; + if (i >= JPEG_DC_HUFF_TABLE_SIZE) + { + return HAL_ERROR; /* Huffman Table overflow error*/ + } + else + { + DC_SizeCodesTable->HuffmanCode[i] = huffcode[k]; + DC_SizeCodesTable->CodeLength[i] = huffsize[k] - 1U; + k++; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set the JPEG register with an DC huffman table at the given DC table address + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param HuffTableDC pointer to DC huffman table + * @param DCTableAddress Encoder DC huffman table address it could be HUFFENC_DC0 or HUFFENC_DC1. + * @retval HAL status + */ +static HAL_StatusTypeDef JPEG_Set_HuffDC_Mem(const JPEG_HandleTypeDef *hjpeg, JPEG_DCHuffTableTypeDef *HuffTableDC, + const __IO uint32_t *DCTableAddress) +{ + HAL_StatusTypeDef error; + JPEG_DC_HuffCodeTableTypeDef dcSizeCodesTable; + uint32_t i; + uint32_t lsb; + uint32_t msb; + __IO uint32_t *address; + __IO uint32_t *addressDef; + + if (DCTableAddress == (hjpeg->Instance->HUFFENC_DC0)) + { + address = (hjpeg->Instance->HUFFENC_DC0 + (JPEG_DC_HUFF_TABLE_SIZE / 2UL)); + } + else if (DCTableAddress == (hjpeg->Instance->HUFFENC_DC1)) + { + address = (hjpeg->Instance->HUFFENC_DC1 + (JPEG_DC_HUFF_TABLE_SIZE / 2UL)); + } + else + { + return HAL_ERROR; + } + + if (HuffTableDC != NULL) + { + error = JPEG_DCHuff_BitsVals_To_SizeCodes(HuffTableDC, &dcSizeCodesTable); + if (error != HAL_OK) + { + return error; + } + addressDef = address; + *addressDef = 0x0FFF0FFF; + addressDef++; + *addressDef = 0x0FFF0FFF; + + i = JPEG_DC_HUFF_TABLE_SIZE; + while (i > 1UL) + { + i--; + address --; + msb = ((uint32_t)(((uint32_t)dcSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | + ((uint32_t)dcSizeCodesTable.HuffmanCode[i] & 0xFFUL); + i--; + lsb = ((uint32_t)(((uint32_t)dcSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | + ((uint32_t)dcSizeCodesTable.HuffmanCode[i] & 0xFFUL); + + *address = lsb | (msb << 16); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set the JPEG register with an AC huffman table at the given AC table address + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param HuffTableAC pointer to AC huffman table + * @param ACTableAddress Encoder AC huffman table address it could be HUFFENC_AC0 or HUFFENC_AC1. + * @retval HAL status + */ +static HAL_StatusTypeDef JPEG_Set_HuffAC_Mem(const JPEG_HandleTypeDef *hjpeg, JPEG_ACHuffTableTypeDef *HuffTableAC, + const __IO uint32_t *ACTableAddress) +{ + HAL_StatusTypeDef error; + JPEG_AC_HuffCodeTableTypeDef acSizeCodesTable; + uint32_t i; + uint32_t lsb; + uint32_t msb; + __IO uint32_t *address; + __IO uint32_t *addressDef; + + if (ACTableAddress == (hjpeg->Instance->HUFFENC_AC0)) + { + address = (hjpeg->Instance->HUFFENC_AC0 + (JPEG_AC_HUFF_TABLE_SIZE / 2UL)); + } + else if (ACTableAddress == (hjpeg->Instance->HUFFENC_AC1)) + { + address = (hjpeg->Instance->HUFFENC_AC1 + (JPEG_AC_HUFF_TABLE_SIZE / 2UL)); + } + else + { + return HAL_ERROR; + } + + if (HuffTableAC != NULL) + { + error = JPEG_ACHuff_BitsVals_To_SizeCodes(HuffTableAC, &acSizeCodesTable); + if (error != HAL_OK) + { + return error; + } + /* Default values settings: 162:167 FFFh , 168:175 FD0h_FD7h */ + /* Locations 162:175 of each AC table contain information used internally by the core */ + + addressDef = address; + for (i = 0; i < 3UL; i++) + { + *addressDef = 0x0FFF0FFF; + addressDef++; + } + *addressDef = 0x0FD10FD0; + addressDef++; + *addressDef = 0x0FD30FD2; + addressDef++; + *addressDef = 0x0FD50FD4; + addressDef++; + *addressDef = 0x0FD70FD6; + /* end of Locations 162:175 */ + + + i = JPEG_AC_HUFF_TABLE_SIZE; + while (i > 1UL) + { + i--; + address--; + msb = ((uint32_t)(((uint32_t)acSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | + ((uint32_t)acSizeCodesTable.HuffmanCode[i] & 0xFFUL); + i--; + lsb = ((uint32_t)(((uint32_t)acSizeCodesTable.CodeLength[i] & 0xFU) << 8)) | + ((uint32_t)acSizeCodesTable.HuffmanCode[i] & 0xFFUL); + + *address = lsb | (msb << 16); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configure the JPEG encoder register huffman tables to used during + * the encdoing operation + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +static HAL_StatusTypeDef JPEG_Set_HuffEnc_Mem(JPEG_HandleTypeDef *hjpeg) +{ + HAL_StatusTypeDef error; + + JPEG_Set_Huff_DHTMem(hjpeg); + error = JPEG_Set_HuffAC_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACLUM_HuffTable, + (hjpeg->Instance->HUFFENC_AC0)); + if (error != HAL_OK) + { + return error; + } + + error = JPEG_Set_HuffAC_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACCHROM_HuffTable, + (hjpeg->Instance->HUFFENC_AC1)); + if (error != HAL_OK) + { + return error; + } + + error = JPEG_Set_HuffDC_Mem(hjpeg, (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCLUM_HuffTable, + hjpeg->Instance->HUFFENC_DC0); + if (error != HAL_OK) + { + return error; + } + + error = JPEG_Set_HuffDC_Mem(hjpeg, (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCCHROM_HuffTable, + hjpeg->Instance->HUFFENC_DC1); + if (error != HAL_OK) + { + return error; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configure the JPEG register huffman tables to be included in the JPEG + * file header (used for encoding only) + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +static void JPEG_Set_Huff_DHTMem(const JPEG_HandleTypeDef *hjpeg) +{ + const JPEG_ACHuffTableTypeDef *HuffTableAC0 = (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACLUM_HuffTable; + const JPEG_ACHuffTableTypeDef *HuffTableAC1 = (JPEG_ACHuffTableTypeDef *)(uint32_t)&JPEG_ACCHROM_HuffTable; + const JPEG_DCHuffTableTypeDef *HuffTableDC0 = (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCLUM_HuffTable; + const JPEG_DCHuffTableTypeDef *HuffTableDC1 = (JPEG_DCHuffTableTypeDef *)(uint32_t)&JPEG_DCCHROM_HuffTable; + uint32_t value; + uint32_t index; + __IO uint32_t *address; + + /* DC0 Huffman Table : BITS*/ + /* DC0 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM base address to DHTMEM + 3*/ + address = (hjpeg->Instance->DHTMEM + 3); + index = 16; + while (index > 3UL) + { + + *address = (((uint32_t)HuffTableDC0->Bits[index - 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableDC0->Bits[index - 2UL] & 0xFFUL) << 16) | + (((uint32_t)HuffTableDC0->Bits[index - 3UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableDC0->Bits[index - 4UL] & 0xFFUL); + address--; + index -= 4UL; + + } + /* DC0 Huffman Table : Val*/ + /* DC0 VALS is a 12 Bytes table i.e 3x32bits words from DHTMEM base address +4 to DHTMEM + 6 */ + address = (hjpeg->Instance->DHTMEM + 6); + index = 12; + while (index > 3UL) + { + *address = (((uint32_t)HuffTableDC0->HuffVal[index - 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableDC0->HuffVal[index - 2UL] & 0xFFUL) << 16) | + (((uint32_t)HuffTableDC0->HuffVal[index - 3UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableDC0->HuffVal[index - 4UL] & 0xFFUL); + address--; + index -= 4UL; + } + + /* AC0 Huffman Table : BITS*/ + /* AC0 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM base address + 7 to DHTMEM + 10*/ + address = (hjpeg->Instance->DHTMEM + 10UL); + index = 16; + while (index > 3UL) + { + + *address = (((uint32_t)HuffTableAC0->Bits[index - 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableAC0->Bits[index - 2UL] & 0xFFUL) << 16) | + (((uint32_t)HuffTableAC0->Bits[index - 3UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableAC0->Bits[index - 4UL] & 0xFFUL); + address--; + index -= 4UL; + + } + /* AC0 Huffman Table : Val*/ + /* AC0 VALS is a 162 Bytes table i.e 41x32bits words from DHTMEM base address + 11 to DHTMEM + 51 */ + /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 51) belong to AC0 VALS table */ + address = (hjpeg->Instance->DHTMEM + 51); + value = *address & 0xFFFF0000U; + value = value | (((uint32_t)HuffTableAC0->HuffVal[161] & 0xFFUL) << 8) | + ((uint32_t)HuffTableAC0->HuffVal[160] & 0xFFUL); + *address = value; + + /*continue setting 160 AC0 huffman values */ + address--; /* address = hjpeg->Instance->DHTMEM + 50*/ + index = JPEG_AC_HUFF_TABLE_SIZE - 2UL; + while (index > 3UL) + { + *address = (((uint32_t)HuffTableAC0->HuffVal[index - 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableAC0->HuffVal[index - 2UL] & 0xFFUL) << 16) | + (((uint32_t)HuffTableAC0->HuffVal[index - 3UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableAC0->HuffVal[index - 4UL] & 0xFFUL); + address--; + index -= 4UL; + } + + /* DC1 Huffman Table : BITS*/ + /* DC1 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM + 51 base address to DHTMEM + 55*/ + /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 51) belong to DC1 Bits table */ + address = (hjpeg->Instance->DHTMEM + 51); + value = *address & 0x0000FFFFU; + value = value | (((uint32_t)HuffTableDC1->Bits[1] & 0xFFUL) << 24) | + (((uint32_t)HuffTableDC1->Bits[0] & 0xFFUL) << 16); + *address = value; + + /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 55) belong to DC1 Bits table */ + address = (hjpeg->Instance->DHTMEM + 55); + value = *address & 0xFFFF0000U; + value = value | (((uint32_t)HuffTableDC1->Bits[15] & 0xFFUL) << 8) | + ((uint32_t)HuffTableDC1->Bits[14] & 0xFFUL); + *address = value; + + /*continue setting 12 DC1 huffman Bits from DHTMEM + 54 down to DHTMEM + 52*/ + address--; + index = 12; + while (index > 3UL) + { + + *address = (((uint32_t)HuffTableDC1->Bits[index + 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableDC1->Bits[index] & 0xFFUL) << 16) | + (((uint32_t)HuffTableDC1->Bits[index - 1UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableDC1->Bits[index - 2UL] & 0xFFUL); + address--; + index -= 4UL; + + } + /* DC1 Huffman Table : Val*/ + /* DC1 VALS is a 12 Bytes table i.e 3x32bits words from DHTMEM base address +55 to DHTMEM + 58 */ + /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 55) belong to DC1 Val table */ + address = (hjpeg->Instance->DHTMEM + 55); + value = *address & 0x0000FFFFUL; + value = value | (((uint32_t)HuffTableDC1->HuffVal[1] & 0xFFUL) << 24) | + (((uint32_t)HuffTableDC1->HuffVal[0] & 0xFFUL) << 16); + *address = value; + + /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 58) belong to DC1 Val table */ + address = (hjpeg->Instance->DHTMEM + 58); + value = *address & 0xFFFF0000UL; + value = value | (((uint32_t)HuffTableDC1->HuffVal[11] & 0xFFUL) << 8) | + ((uint32_t)HuffTableDC1->HuffVal[10] & 0xFFUL); + *address = value; + + /*continue setting 8 DC1 huffman val from DHTMEM + 57 down to DHTMEM + 56*/ + address--; + index = 8; + while (index > 3UL) + { + *address = (((uint32_t)HuffTableDC1->HuffVal[index + 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableDC1->HuffVal[index] & 0xFFUL) << 16) | + (((uint32_t)HuffTableDC1->HuffVal[index - 1UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableDC1->HuffVal[index - 2UL] & 0xFFUL); + address--; + index -= 4UL; + } + + /* AC1 Huffman Table : BITS*/ + /* AC1 BITS is a 16 Bytes table i.e 4x32bits words from DHTMEM base address + 58 to DHTMEM + 62*/ + /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 58) belong to AC1 Bits table */ + address = (hjpeg->Instance->DHTMEM + 58); + value = *address & 0x0000FFFFU; + value = value | (((uint32_t)HuffTableAC1->Bits[1] & 0xFFUL) << 24) | + (((uint32_t)HuffTableAC1->Bits[0] & 0xFFUL) << 16); + *address = value; + + /* only Byte 0 and Byte 1 of the last word (@ DHTMEM + 62) belong to Bits Val table */ + address = (hjpeg->Instance->DHTMEM + 62); + value = *address & 0xFFFF0000U; + value = value | (((uint32_t)HuffTableAC1->Bits[15] & 0xFFUL) << 8) | ((uint32_t)HuffTableAC1->Bits[14] & 0xFFUL); + *address = value; + + /*continue setting 12 AC1 huffman Bits from DHTMEM + 61 down to DHTMEM + 59*/ + address--; + index = 12; + while (index > 3UL) + { + + *address = (((uint32_t)HuffTableAC1->Bits[index + 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableAC1->Bits[index] & 0xFFUL) << 16) | + (((uint32_t)HuffTableAC1->Bits[index - 1UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableAC1->Bits[index - 2UL] & 0xFFUL); + address--; + index -= 4UL; + + } + /* AC1 Huffman Table : Val*/ + /* AC1 VALS is a 162 Bytes table i.e 41x32bits words from DHTMEM base address + 62 to DHTMEM + 102 */ + /* only Byte 2 and Byte 3 of the first word (@ DHTMEM + 62) belong to AC1 VALS table */ + address = (hjpeg->Instance->DHTMEM + 62); + value = *address & 0x0000FFFFUL; + value = value | (((uint32_t)HuffTableAC1->HuffVal[1] & 0xFFUL) << 24) | + (((uint32_t)HuffTableAC1->HuffVal[0] & 0xFFUL) << 16); + *address = value; + + /*continue setting 160 AC1 huffman values from DHTMEM + 63 to DHTMEM+102 */ + address = (hjpeg->Instance->DHTMEM + 102); + index = JPEG_AC_HUFF_TABLE_SIZE - 2UL; + while (index > 3UL) + { + *address = (((uint32_t)HuffTableAC1->HuffVal[index + 1UL] & 0xFFUL) << 24) | + (((uint32_t)HuffTableAC1->HuffVal[index] & 0xFFUL) << 16) | + (((uint32_t)HuffTableAC1->HuffVal[index - 1UL] & 0xFFUL) << 8) | + ((uint32_t)HuffTableAC1->HuffVal[index - 2UL] & 0xFFUL); + address--; + index -= 4UL; + } + +} + +/** + * @brief Configure the JPEG registers with a given quantization table + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param QTable pointer to an array of 64 bytes giving the quantization table + * @param QTableAddress destination quantization address in the JPEG peripheral + * it could be QMEM0, QMEM1, QMEM2 or QMEM3 + * @retval 0 if no error, 1 if error + */ +static uint32_t JPEG_Set_Quantization_Mem(const JPEG_HandleTypeDef *hjpeg, const uint8_t *QTable, + __IO uint32_t *QTableAddress) +{ + uint32_t i; + uint32_t j; + uint32_t quantRow; + uint32_t quantVal; + uint32_t ScaleFactor; + __IO uint32_t *tableAddress; + + tableAddress = QTableAddress; + + if ((hjpeg->Conf.ImageQuality >= 50UL) && (hjpeg->Conf.ImageQuality <= 100UL)) + { + ScaleFactor = JPEG_HIGH_QUALITY_REFERENCE - (hjpeg->Conf.ImageQuality * 2UL); + } + else if (hjpeg->Conf.ImageQuality > 0UL) + { + ScaleFactor = JPEG_LOW_QUALITY_REFERENCE / ((uint32_t) hjpeg->Conf.ImageQuality); + } + else + { + return 1UL; + } + + /*Quantization_table = (Standard_quanization_table * ScaleFactor + 50) / 100*/ + i = 0; + while (i < (JPEG_QUANT_TABLE_SIZE - 3UL)) + { + quantRow = 0; + for (j = 0; j < 4UL; j++) + { + /* Note that the quantization coefficients must be specified in the table in zigzag order */ + quantVal = ((((uint32_t) QTable[JPEG_ZIGZAG_ORDER[i + j]]) * ScaleFactor) + 50UL) / 100UL; + + if (quantVal == 0UL) + { + quantVal = 1UL; + } + else if (quantVal > 255UL) + { + quantVal = JPEG_QUANTVAL_MAX; + } + else + { + /* Nothing to do, keep same value of quantVal */ + } + + quantRow |= ((quantVal & 0xFFUL) << (8UL * j)); + } + + i += 4UL; + *tableAddress = quantRow; + tableAddress ++; + } + + /* Return function status */ + return 0UL; +} + +/** + * @brief Configure the JPEG registers for YCbCr color space + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +static void JPEG_SetColorYCBCR(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t ySamplingH; + uint32_t ySamplingV; + uint32_t yblockNb; + + /*Set Number of color components to 3*/ + hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_NF; + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_NF_1; + + /* compute MCU block size and Y, Cb ,Cr sampling factors*/ + if (hjpeg->Conf.ChromaSubsampling == JPEG_420_SUBSAMPLING) + { + ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ + ySamplingV = JPEG_CONFR4_VSF_1; /* Vs = 2*/ + + yblockNb = 0x30; /* 4 blocks of 8x8*/ + } + else if (hjpeg->Conf.ChromaSubsampling == JPEG_422_SUBSAMPLING) + { + ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ + ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ + + yblockNb = 0x10; /* 2 blocks of 8x8*/ + } + else /*JPEG_444_SUBSAMPLING and default*/ + { + ySamplingH = JPEG_CONFR4_HSF_0; /* Hs = 1*/ + ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ + + yblockNb = 0; /* 1 block of 8x8*/ + } + + hjpeg->Instance->CONFR1 &= ~(JPEG_CONFR1_NF | JPEG_CONFR1_NS); + hjpeg->Instance->CONFR1 |= (JPEG_CONFR1_NF_1 | JPEG_CONFR1_NS_1); + + /*Reset CONFR4 register*/ + hjpeg->Instance->CONFR4 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 0*/ + hjpeg->Instance->CONFR4 |= (ySamplingH | ySamplingV | (yblockNb & JPEG_CONFR4_NB)); + + /*Reset CONFR5 register*/ + hjpeg->Instance->CONFR5 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 1*/ + hjpeg->Instance->CONFR5 |= (JPEG_CONFR5_HSF_0 | JPEG_CONFR5_VSF_0 | JPEG_CONFR5_QT_0 | JPEG_CONFR5_HA | + JPEG_CONFR5_HD); + + /*Reset CONFR6 register*/ + hjpeg->Instance->CONFR6 = 0; + /*Set Horizental and Vertical sampling factor and number of blocks for component 2*/ + /* In YCBCR , by default, both chrominance components (component 1 and component 2) + use the same Quantization table (table 1) */ + /* In YCBCR , both chrominance components (component 1 and component 2) use the same Huffman tables (table 1) */ + hjpeg->Instance->CONFR6 |= (JPEG_CONFR6_HSF_0 | JPEG_CONFR6_VSF_0 | JPEG_CONFR6_QT_0 | JPEG_CONFR6_HA | + JPEG_CONFR6_HD); + +} + +/** + * @brief Configure the JPEG registers for GrayScale color space + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +static void JPEG_SetColorGrayScale(JPEG_HandleTypeDef *hjpeg) +{ + /*Set Number of color components to 1*/ + hjpeg->Instance->CONFR1 &= ~(JPEG_CONFR1_NF | JPEG_CONFR1_NS); + + /*in GrayScale use 1 single Quantization table (Table 0)*/ + /*in GrayScale use only one couple of AC/DC huffman table (table 0)*/ + + /*Reset CONFR4 register*/ + hjpeg->Instance->CONFR4 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 0*/ + hjpeg->Instance->CONFR4 |= JPEG_CONFR4_HSF_0 | JPEG_CONFR4_VSF_0 ; +} + +/** + * @brief Configure the JPEG registers for CMYK color space + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +static void JPEG_SetColorCMYK(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t ySamplingH; + uint32_t ySamplingV; + uint32_t yblockNb; + + /*Set Number of color components to 4*/ + hjpeg->Instance->CONFR1 |= (JPEG_CONFR1_NF | JPEG_CONFR1_NS); + + /* compute MCU block size and Y, Cb ,Cr sampling factors*/ + if (hjpeg->Conf.ChromaSubsampling == JPEG_420_SUBSAMPLING) + { + ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ + ySamplingV = JPEG_CONFR4_VSF_1; /* Vs = 2*/ + + yblockNb = 0x30; /* 4 blocks of 8x8*/ + } + else if (hjpeg->Conf.ChromaSubsampling == JPEG_422_SUBSAMPLING) + { + ySamplingH = JPEG_CONFR4_HSF_1; /* Hs = 2*/ + ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ + + yblockNb = 0x10; /* 2 blocks of 8x8*/ + } + else /*JPEG_444_SUBSAMPLING and default*/ + { + ySamplingH = JPEG_CONFR4_HSF_0; /* Hs = 1*/ + ySamplingV = JPEG_CONFR4_VSF_0; /* Vs = 1*/ + + yblockNb = 0; /* 1 block of 8x8*/ + } + + /*Reset CONFR4 register*/ + hjpeg->Instance->CONFR4 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 0*/ + hjpeg->Instance->CONFR4 |= (ySamplingH | ySamplingV | (yblockNb & JPEG_CONFR4_NB)); + + /*Reset CONFR5 register*/ + hjpeg->Instance->CONFR5 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 1*/ + hjpeg->Instance->CONFR5 |= (JPEG_CONFR5_HSF_0 | JPEG_CONFR5_VSF_0); + + /*Reset CONFR6 register*/ + hjpeg->Instance->CONFR6 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 2*/ + hjpeg->Instance->CONFR6 |= (JPEG_CONFR6_HSF_0 | JPEG_CONFR6_VSF_0); + + /*Reset CONFR7 register*/ + hjpeg->Instance->CONFR7 = 0; + /*Set Horizental and Vertical sampling factor , number of blocks, + Quantization table and Huffman AC/DC tables for component 3*/ + hjpeg->Instance->CONFR7 |= (JPEG_CONFR7_HSF_0 | JPEG_CONFR7_VSF_0); +} + +/** + * @brief Init the JPEG encoding/decoding process in case of Polling or Interrupt and DMA + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None + */ +static void JPEG_Init_Process(JPEG_HandleTypeDef *hjpeg) +{ + /*Reset pause*/ + hjpeg->Context &= (~(JPEG_CONTEXT_PAUSE_INPUT | JPEG_CONTEXT_PAUSE_OUTPUT)); + + if ((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) + { + /*Set JPEG Codec to Decoding mode */ + hjpeg->Instance->CONFR1 |= JPEG_CONFR1_DE; + } + else /* JPEG_CONTEXT_ENCODE */ + { + /*Set JPEG Codec to Encoding mode */ + hjpeg->Instance->CONFR1 &= ~JPEG_CONFR1_DE; + } + + /*Stop JPEG processing */ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + /* Disable All Interrupts */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + /* Disable All DMA requests */ + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_MASK); + /* Flush input and output FIFOs*/ + hjpeg->Instance->CR |= JPEG_CR_IFF; + hjpeg->Instance->CR |= JPEG_CR_OFF; + + /* Clear all flags */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); + + /*Start Encoding/Decoding*/ + hjpeg->Instance->CONFR0 |= JPEG_CONFR0_START; + + if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) + { + /*Enable IN/OUT, end of Conversation, and end of header parsing interruptions*/ + __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_IFT | JPEG_IT_IFNF | JPEG_IT_OFT | JPEG_IT_OFNE | JPEG_IT_EOC | JPEG_IT_HPD); + } + else if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_DMA) + { + /*Enable End Of Conversation, and End Of Header parsing interruptions*/ + __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_EOC | JPEG_IT_HPD); + + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief JPEG encoding/decoding process in case of Polling or Interrupt + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval JPEG_PROCESS_DONE if the process has ends else JPEG_PROCESS_ONGOING + */ +static uint32_t JPEG_Process(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t tmpContext; + uint32_t itflag = hjpeg->Instance->SR; + + /*End of header processing flag */ + if ((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) + { + if ((itflag & JPEG_FLAG_HPDF) != 0UL) + { + /*Call Header parsing complete callback */ + (void) HAL_JPEG_GetInfo(hjpeg, &hjpeg->Conf); + /* Reset the ImageQuality */ + hjpeg->Conf.ImageQuality = 0; + /* Note : the image quality is only available at the end of the decoding operation */ + /* at the current stage the calculated image quality is not correct so reset it */ + + /*Call Info Ready callback */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->InfoReadyCallback(hjpeg, &hjpeg->Conf); +#else + HAL_JPEG_InfoReadyCallback(hjpeg, &hjpeg->Conf); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_IT_HPD); + + /* Clear header processing done flag */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_HPDF); + } + } + + /*Input FIFO status handling*/ + if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0UL) + { + if ((itflag & JPEG_FLAG_IFTF) != 0UL) + { + /*Input FIFO threshold flag */ + /*JPEG_FIFO_TH_SIZE words can be written in */ + JPEG_ReadInputData(hjpeg, JPEG_FIFO_TH_SIZE); + } + else if ((itflag & JPEG_FLAG_IFNFF) != 0UL) + { + /*Input FIFO Not Full flag */ + /*32-bit value can be written in */ + JPEG_ReadInputData(hjpeg, 1); + } + else + { + /* Nothing to do */ + } + } + + /*Output FIFO flag handling*/ + if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) + { + if ((itflag & JPEG_FLAG_OFTF) != 0UL) + { + /*Output FIFO threshold flag */ + /*JPEG_FIFO_TH_SIZE words can be read out */ + JPEG_StoreOutputData(hjpeg, JPEG_FIFO_TH_SIZE); + } + else if ((itflag & JPEG_FLAG_OFNEF) != 0UL) + { + /*Output FIFO Not Empty flag */ + /*32-bit value can be read out */ + JPEG_StoreOutputData(hjpeg, 1); + } + else + { + /* Nothing to do */ + } + } + + /*End of Conversion handling :i.e EOC flag is high and OFTF low and OFNEF low*/ + if ((itflag & (JPEG_FLAG_EOCF | JPEG_FLAG_OFTF | JPEG_FLAG_OFNEF)) == JPEG_FLAG_EOCF) + { + /*Stop Encoding/Decoding*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + if ((hjpeg->Context & JPEG_CONTEXT_METHOD_MASK) == JPEG_CONTEXT_IT) + { + /* Disable All Interrupts */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + } + + /* Clear all flags */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); + + /*Call End of conversion callback */ + if (hjpeg->JpegOutCount > 0UL) + { + /*Output Buffer is not empty, call DecodedDataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + hjpeg->JpegOutCount = 0; + } + + /*Reset Context Operation*/ + tmpContext = hjpeg->Context; + /*Clear all context fields execpt JPEG_CONTEXT_CONF_ENCODING and JPEG_CONTEXT_CUSTOM_TABLES*/ + hjpeg->Context &= (JPEG_CONTEXT_CONF_ENCODING | JPEG_CONTEXT_CUSTOM_TABLES); + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /*Call End of Encoding/Decoding callback */ + if ((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DecodeCpltCallback(hjpeg); +#else + HAL_JPEG_DecodeCpltCallback(hjpeg); +#endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ + } + else /* JPEG_CONTEXT_ENCODE */ + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->EncodeCpltCallback(hjpeg); +#else + HAL_JPEG_EncodeCpltCallback(hjpeg); +#endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ + } + + return JPEG_PROCESS_DONE; + } + + return JPEG_PROCESS_ONGOING; +} + +/** + * @brief Store some output data from the JPEG peripheral to the output buffer. + * This function is used when the JPEG peripheral has new data to output + * in case of Polling or Interrupt process + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param nbOutputWords Number of output words (of 32 bits) ready from the JPEG peripheral + * @retval None + */ +static void JPEG_StoreOutputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbOutputWords) +{ + uint32_t index; + uint32_t nb_words; + uint32_t nb_bytes; + uint32_t dataword; + + if (hjpeg->OutDataLength >= (hjpeg->JpegOutCount + (nbOutputWords * 4UL))) + { + for (index = 0; index < nbOutputWords; index++) + { + /*Transfer 32 bits from the JPEG output FIFO*/ + dataword = hjpeg->Instance->DOR; + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)(dataword & 0x000000FFUL); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 1UL] = (uint8_t)((dataword & 0x0000FF00UL) >> 8); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 2UL] = (uint8_t)((dataword & 0x00FF0000UL) >> 16); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 3UL] = (uint8_t)((dataword & 0xFF000000UL) >> 24); + hjpeg->JpegOutCount += 4UL; + } + if (hjpeg->OutDataLength == hjpeg->JpegOutCount) + { + /*Output Buffer is full, call DecodedDataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ + hjpeg->JpegOutCount = 0; + } + } + else if (hjpeg->OutDataLength > hjpeg->JpegOutCount) + { + nb_words = (hjpeg->OutDataLength - hjpeg->JpegOutCount) / 4UL; + for (index = 0; index < nb_words; index++) + { + /*Transfer 32 bits from the JPEG output FIFO*/ + dataword = hjpeg->Instance->DOR; + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)(dataword & 0x000000FFUL); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 1UL] = (uint8_t)((dataword & 0x0000FF00UL) >> 8); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 2UL] = (uint8_t)((dataword & 0x00FF0000UL) >> 16); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 3UL] = (uint8_t)((dataword & 0xFF000000UL) >> 24); + hjpeg->JpegOutCount += 4UL; + } + if (hjpeg->OutDataLength == hjpeg->JpegOutCount) + { + /*Output Buffer is full, call DecodedDataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + hjpeg->JpegOutCount = 0; + } + else + { + nb_bytes = hjpeg->OutDataLength - hjpeg->JpegOutCount; + dataword = hjpeg->Instance->DOR; + for (index = 0; index < nb_bytes; index++) + { + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)((dataword >> (8UL * (index & 0x3UL))) & 0xFFUL); + hjpeg->JpegOutCount++; + } + /*Output Buffer is full, call DecodedDataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + hjpeg->JpegOutCount = 0; + + nb_bytes = 4UL - nb_bytes; + for (index = nb_bytes; index < 4UL; index++) + { + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)((dataword >> (8UL * index)) & 0xFFUL); + hjpeg->JpegOutCount++; + } + } + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief Read some input Data from the input buffer. + * This function is used when the JPEG peripheral needs new data + * in case of Polling or Interrupt process + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @param nbRequestWords Number of input words (of 32 bits) that the JPE peripheral request + * @retval None + */ +static void JPEG_ReadInputData(JPEG_HandleTypeDef *hjpeg, uint32_t nbRequestWords) +{ + uint32_t nb_bytes = 0; + uint32_t nb_words; + uint32_t index; + uint32_t dataword; + uint32_t input_count; + + if ((hjpeg->InDataLength == 0UL) || (nbRequestWords == 0UL)) + { + /* No more Input data : nothing to do*/ + (void) HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_INPUT); + } + else if (hjpeg->InDataLength > hjpeg->JpegInCount) + { + nb_bytes = hjpeg->InDataLength - hjpeg->JpegInCount; + } + else if (hjpeg->InDataLength == hjpeg->JpegInCount) + { + /*Call HAL_JPEG_GetDataCallback to get new data */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->GetDataCallback(hjpeg, hjpeg->JpegInCount); +#else + HAL_JPEG_GetDataCallback(hjpeg, hjpeg->JpegInCount); +#endif /*USE_HAL_JPEG_REGISTER_CALLBACKS*/ + + if (hjpeg->InDataLength > 4UL) + { + hjpeg->InDataLength = ((hjpeg->InDataLength + 3UL) / 4UL) * 4UL; + } + hjpeg->JpegInCount = 0; + nb_bytes = hjpeg->InDataLength; + } + else + { + /* Nothing to do */ + } + if (((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0UL) && (nb_bytes > 0UL)) + { + nb_words = nb_bytes / 4UL; + if (nb_words >= nbRequestWords) + { + for (index = 0; index < nbRequestWords; index++) + { + input_count = hjpeg->JpegInCount; + hjpeg->Instance->DIR = (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count])) | \ + (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 1UL])) << 8) | \ + (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 2UL])) << 16) | \ + (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 3UL])) << 24)); + + hjpeg->JpegInCount += 4UL; + } + } + else /*nb_words < nbRequestWords*/ + { + if (nb_words > 0UL) + { + for (index = 0; index < nb_words; index++) + { + input_count = hjpeg->JpegInCount; + hjpeg->Instance->DIR = (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count])) | \ + (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 1UL])) << 8) | \ + (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 2UL])) << 16) | \ + (((uint32_t)(hjpeg->pJpegInBuffPtr[input_count + 3UL])) << 24)); + + hjpeg->JpegInCount += 4UL; + } + } + else + { + /* end of file*/ + dataword = 0; + for (index = 0; index < nb_bytes; index++) + { + dataword |= (uint32_t)hjpeg->pJpegInBuffPtr[hjpeg->JpegInCount] << (8UL * (index & 0x03UL)); + hjpeg->JpegInCount++; + } + hjpeg->Instance->DIR = dataword; + } + } + } +} + +/** + * @brief Start the JPEG DMA process (encoding/decoding) + * @note The DMA interrupt must have a higher priority than the JPEG + * interrupt to prevent the JPEG interrupt from preempting the DMA interrupt + * before the DMA state is updated to ready. + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval JPEG_PROCESS_DONE if process ends else JPEG_PROCESS_ONGOING + */ +static HAL_StatusTypeDef JPEG_DMA_StartProcess(JPEG_HandleTypeDef *hjpeg) +{ + if ((hjpeg->InDataLength < 4UL) || (hjpeg->OutDataLength < 4UL)) + { + return HAL_ERROR; + } + /* Reset Ending DMA internal context flag*/ + hjpeg->Context &= ~JPEG_CONTEXT_ENDING_DMA; + + /* Disable DMA In/Out Request*/ + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_ODMA | JPEG_DMA_IDMA); + + /* Set the JPEG DMA In transfer complete callback */ + hjpeg->hdmain->XferCpltCallback = JPEG_DMAInCpltCallback; + /* Set the DMA In error callback */ + hjpeg->hdmain->XferErrorCallback = JPEG_DMAErrorCallback; + + /* Set the JPEG DMA Out transfer complete callback */ + hjpeg->hdmaout->XferCpltCallback = JPEG_DMAOutCpltCallback; + /* Set the DMA Out error callback */ + hjpeg->hdmaout->XferErrorCallback = JPEG_DMAErrorCallback; + /* Set the DMA Out Abort callback */ + hjpeg->hdmaout->XferAbortCallback = JPEG_DMAOutAbortCallback; + + /*DMA transfer size must be a multiple of 4 bytes i.e multiple of 32bits words*/ + hjpeg->InDataLength = hjpeg->InDataLength - (hjpeg->InDataLength % 4UL); + + /*DMA transfer size must be a multiple of 4 bytes i.e multiple of 32bits words*/ + hjpeg->OutDataLength = hjpeg->OutDataLength - (hjpeg->OutDataLength % 4UL); + + if ((hjpeg->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hjpeg->hdmain->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hjpeg->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hjpeg->InDataLength; + + /* Set DMA source address */ + hjpeg->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hjpeg->pJpegInBuffPtr; + + /* Set DMA destination address */ + hjpeg->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hjpeg->Instance->DIR; + + if (HAL_DMAEx_List_Start_IT(hjpeg->hdmain) != HAL_OK) + { + return HAL_ERROR; + } + } + else + { + /* Set the JPEG State to ready */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /* Update JPEG error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + } + else + { + /* Start DMA FIFO In transfer */ + if (HAL_DMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, + hjpeg->InDataLength) != HAL_OK) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + return HAL_ERROR; + } + } + + if ((hjpeg->hdmaout->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hjpeg->hdmaout->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hjpeg->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hjpeg->OutDataLength; + + /* Set DMA source address */ + hjpeg->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hjpeg->Instance->DOR; + + /* Set DMA destination address */ + hjpeg->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hjpeg->pJpegOutBuffPtr; + + if (HAL_DMAEx_List_Start_IT(hjpeg->hdmaout) != HAL_OK) + { + return HAL_ERROR; + } + } + else + { + /* Set the JPEG State to ready */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /* Update JPEG error code */ + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + return HAL_ERROR; + } + } + else + { + /* Start DMA FIFO Out transfer */ + if (HAL_DMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, + hjpeg->OutDataLength) != HAL_OK) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + return HAL_ERROR; + } + } + + /* Enable JPEG In/Out DMA requests*/ + JPEG_ENABLE_DMA(hjpeg, JPEG_DMA_IDMA | JPEG_DMA_ODMA); + + return HAL_OK; +} + +/** + * @brief Continue the current JPEG DMA process (encoding/decoding) + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval JPEG_PROCESS_DONE if process ends else JPEG_PROCESS_ONGOING + */ +static void JPEG_DMA_ContinueProcess(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t itflag = hjpeg->Instance->SR; + + /*End of header processing flag rises*/ + if ((hjpeg->Context & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) + { + if ((itflag & JPEG_FLAG_HPDF) != 0UL) + { + /*Call Header parsing complete callback */ + (void) HAL_JPEG_GetInfo(hjpeg, &hjpeg->Conf); + + /* Reset the ImageQuality */ + hjpeg->Conf.ImageQuality = 0; + /* Note : the image quality is only available at the end of the decoding operation */ + /* at the current stage the calculated image quality is not correct so reset it */ + + /*Call Info Ready callback */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->InfoReadyCallback(hjpeg, &hjpeg->Conf); +#else + HAL_JPEG_InfoReadyCallback(hjpeg, &hjpeg->Conf); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_IT_HPD); + + /* Clear header processing done flag */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_HPDF); + } + } + + /*End of Conversion handling*/ + if ((itflag & JPEG_FLAG_EOCF) != 0UL) + { + /*Disable JPEG In/Out DMA Requests*/ + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_ODMA | JPEG_DMA_IDMA); + + hjpeg->Context |= JPEG_CONTEXT_ENDING_DMA; + + /*Stop Encoding/Decoding*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + /* Clear all flags */ + __HAL_JPEG_CLEAR_FLAG(hjpeg, JPEG_FLAG_ALL); + + if (hjpeg->hdmain->State == HAL_DMA_STATE_BUSY) + { + /* Stop the DMA In Xfer*/ + (void) HAL_DMA_Abort_IT(hjpeg->hdmain); + } + + if (hjpeg->hdmaout->State == HAL_DMA_STATE_BUSY) + { + /* Stop the DMA out Xfer*/ + (void) HAL_DMA_Abort_IT(hjpeg->hdmaout); + } + else + { + JPEG_DMA_EndProcess(hjpeg); + } + } +} + +/** + * @brief Finalize the current JPEG DMA process (encoding/decoding) + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval JPEG_PROCESS_DONE + */ +static void JPEG_DMA_EndProcess(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t tmpContext; + hjpeg->JpegOutCount = hjpeg->OutDataLength - JPEG_GET_DMA_REMAIN_DATA(hjpeg->hdmaout); + + /*if Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ + if (hjpeg->JpegOutCount == hjpeg->OutDataLength) + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + hjpeg->JpegOutCount = 0; + } + + /*Check if remaining data in the output FIFO*/ + if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) == 0UL) + { + if (hjpeg->JpegOutCount > 0UL) + { + /*Output Buffer is not empty, call DecodedDataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + hjpeg->JpegOutCount = 0; + } + + /*Stop Encoding/Decoding*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + tmpContext = hjpeg->Context; + /*Clear all context fields execpt JPEG_CONTEXT_CONF_ENCODING and JPEG_CONTEXT_CUSTOM_TABLES*/ + hjpeg->Context &= (JPEG_CONTEXT_CONF_ENCODING | JPEG_CONTEXT_CUSTOM_TABLES); + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /*Call End of Encoding/Decoding callback */ + if ((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DecodeCpltCallback(hjpeg); +#else + HAL_JPEG_DecodeCpltCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + } + else /* JPEG_CONTEXT_ENCODE */ + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->EncodeCpltCallback(hjpeg); +#else + HAL_JPEG_EncodeCpltCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + } + } + else if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) + { + JPEG_DMA_PollResidualData(hjpeg); + } + else + { + /* Nothing to do */ + } + +} + +/** + * @brief Poll residual output data when DMA process (encoding/decoding) + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval None. + */ +static void JPEG_DMA_PollResidualData(JPEG_HandleTypeDef *hjpeg) +{ + uint32_t tmpContext; + uint32_t count; + uint32_t dataOut; + + for (count = JPEG_FIFO_SIZE; count > 0UL; count--) + { + if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) + { + if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) != 0UL) + { + dataOut = hjpeg->Instance->DOR; + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount] = (uint8_t)(dataOut & 0x000000FFUL); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 1UL] = (uint8_t)((dataOut & 0x0000FF00UL) >> 8); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 2UL] = (uint8_t)((dataOut & 0x00FF0000UL) >> 16); + hjpeg->pJpegOutBuffPtr[hjpeg->JpegOutCount + 3UL] = (uint8_t)((dataOut & 0xFF000000UL) >> 24); + hjpeg->JpegOutCount += 4UL; + + if (hjpeg->JpegOutCount == hjpeg->OutDataLength) + { + /*Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + hjpeg->JpegOutCount = 0; + } + + } + } + } + + tmpContext = hjpeg->Context; + + if ((__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_OFNEF) == 0UL) || ((tmpContext & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL)) + { + /*Stop Encoding/Decoding*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + if (hjpeg->JpegOutCount > 0UL) + { + /*Output Buffer is not empty, call DecodedDataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + hjpeg->JpegOutCount = 0; + } + + tmpContext = hjpeg->Context; + /*Clear all context fields execpt JPEG_CONTEXT_CONF_ENCODING and JPEG_CONTEXT_CUSTOM_TABLES*/ + hjpeg->Context &= (JPEG_CONTEXT_CONF_ENCODING | JPEG_CONTEXT_CUSTOM_TABLES); + + /* Process Unlocked */ + __HAL_UNLOCK(hjpeg); + + /* Change the JPEG state */ + hjpeg->State = HAL_JPEG_STATE_READY; + + /*Call End of Encoding/Decoding callback */ + if ((tmpContext & JPEG_CONTEXT_OPERATION_MASK) == JPEG_CONTEXT_DECODE) + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DecodeCpltCallback(hjpeg); +#else + HAL_JPEG_DecodeCpltCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + } + else /* JPEG_CONTEXT_ENCODE */ + { +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->EncodeCpltCallback(hjpeg); +#else + HAL_JPEG_EncodeCpltCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief DMA input transfer complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure. + * @retval None + */ +static void JPEG_DMAInCpltCallback(DMA_HandleTypeDef *hdma) +{ + JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable The JPEG IT so the DMA Input Callback can not be interrupted by the JPEG EOC IT or JPEG HPD IT */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + if ((hjpeg->Context & (JPEG_CONTEXT_METHOD_MASK | JPEG_CONTEXT_ENDING_DMA)) == + JPEG_CONTEXT_DMA) /* Check if context method is DMA and we are not in ending DMA stage */ + { + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_IDMA); + + hjpeg->JpegInCount = hjpeg->InDataLength - JPEG_GET_DMA_REMAIN_DATA(hdma); + + /*Call HAL_JPEG_GetDataCallback to get new data */ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->GetDataCallback(hjpeg, hjpeg->JpegInCount); +#else + HAL_JPEG_GetDataCallback(hjpeg, hjpeg->JpegInCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + if (hjpeg->InDataLength >= 4UL) + { + /*JPEG Input DMA transfer data number must be multiple of 32 bits word + as the destination is a 32 bits (4 bytes) register */ + hjpeg->InDataLength = ((hjpeg->InDataLength + 3UL) / 4UL) * 4UL; + } + else + { + /* Nothing to do */ + } + + if (((hjpeg->Context & JPEG_CONTEXT_PAUSE_INPUT) == 0UL) && (hjpeg->InDataLength > 0UL)) + { + /* Start DMA FIFO In transfer */ + if (HAL_DMA_Start_IT(hjpeg->hdmain, (uint32_t)hjpeg->pJpegInBuffPtr, (uint32_t)&hjpeg->Instance->DIR, + hjpeg->InDataLength) != HAL_OK) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + hjpeg->State = HAL_JPEG_STATE_ERROR; +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->ErrorCallback(hjpeg); +#else + HAL_JPEG_ErrorCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + return; + } + JPEG_ENABLE_DMA(hjpeg, JPEG_DMA_IDMA); + } + + /* JPEG Conversion still on going : Enable the JPEG IT */ + __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_EOC | JPEG_IT_HPD); + } +} + +/** + * @brief DMA output transfer complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure. + * @retval None + */ +static void JPEG_DMAOutCpltCallback(DMA_HandleTypeDef *hdma) +{ + JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable The JPEG IT so the DMA Output Callback can not be interrupted by the JPEG EOC IT or JPEG HPD IT */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + if ((hjpeg->Context & (JPEG_CONTEXT_METHOD_MASK | JPEG_CONTEXT_ENDING_DMA)) == + JPEG_CONTEXT_DMA) /* Check if context method is DMA and we are not in ending DMA stage */ + { + if (__HAL_JPEG_GET_FLAG(hjpeg, JPEG_FLAG_EOCF) == 0UL) + { + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_ODMA); + hjpeg->JpegOutCount = hjpeg->OutDataLength - JPEG_GET_DMA_REMAIN_DATA(hdma); + + /*Output Buffer is full, call HAL_JPEG_DataReadyCallback*/ +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#else + HAL_JPEG_DataReadyCallback(hjpeg, hjpeg->pJpegOutBuffPtr, hjpeg->JpegOutCount); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + + if ((hjpeg->Context & JPEG_CONTEXT_PAUSE_OUTPUT) == 0UL) + { + /* Start DMA FIFO Out transfer */ + if (HAL_DMA_Start_IT(hjpeg->hdmaout, (uint32_t)&hjpeg->Instance->DOR, (uint32_t)hjpeg->pJpegOutBuffPtr, + hjpeg->OutDataLength) != HAL_OK) + { + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; + hjpeg->State = HAL_JPEG_STATE_ERROR; +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->ErrorCallback(hjpeg); +#else + HAL_JPEG_ErrorCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + return; + } + JPEG_ENABLE_DMA(hjpeg, JPEG_DMA_ODMA); + } + } + + /* JPEG Conversion still on going : Enable the JPEG IT */ + __HAL_JPEG_ENABLE_IT(hjpeg, JPEG_IT_EOC | JPEG_IT_HPD); + } +} + + +/** + * @brief DMA Transfer error callback + * @param hdma pointer to a DMA_HandleTypeDef structure. + * @retval None + */ +static void JPEG_DMAErrorCallback(DMA_HandleTypeDef *hdma) +{ + JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_NONE) + { + /*Stop Encoding/Decoding*/ + hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; + + /* Disable All Interrupts */ + __HAL_JPEG_DISABLE_IT(hjpeg, JPEG_INTERRUPT_MASK); + + /* Disable All DMA requests */ + JPEG_DISABLE_DMA(hjpeg, JPEG_DMA_MASK); + + hjpeg->State = HAL_JPEG_STATE_READY; + hjpeg->ErrorCode |= HAL_JPEG_ERROR_DMA; +#if (USE_HAL_JPEG_REGISTER_CALLBACKS == 1) + hjpeg->ErrorCallback(hjpeg); +#else + HAL_JPEG_ErrorCallback(hjpeg); +#endif /* USE_HAL_JPEG_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA output Abort callback + * @param hdma pointer to a DMA_HandleTypeDef structure. + * @retval None + */ +static void JPEG_DMAOutAbortCallback(DMA_HandleTypeDef *hdma) +{ + JPEG_HandleTypeDef *hjpeg = (JPEG_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if ((hjpeg->Context & JPEG_CONTEXT_ENDING_DMA) != 0UL) + { + JPEG_DMA_EndProcess(hjpeg); + } +} + + +/** + * @brief Calculate the decoded image quality (from 1 to 100) + * @param hjpeg pointer to a JPEG_HandleTypeDef structure that contains + * the configuration information for JPEG module + * @retval JPEG image quality from 1 to 100. + */ +static uint32_t JPEG_GetQuality(const JPEG_HandleTypeDef *hjpeg) +{ + uint32_t quality = 0; + uint32_t quantRow; + uint32_t quantVal; + uint32_t scale; + uint32_t i; + uint32_t j; + const __IO uint32_t *tableAddress = hjpeg->Instance->QMEM0; + + i = 0; + while (i < (JPEG_QUANT_TABLE_SIZE - 3UL)) + { + quantRow = *tableAddress; + for (j = 0; j < 4UL; j++) + { + quantVal = (quantRow >> (8UL * j)) & 0xFFUL; + if (quantVal == 1UL) + { + /* if Quantization value = 1 then quality is 100%*/ + quality += 100UL; + } + else + { + /* Note that the quantization coefficients must be specified in the table in zigzag order */ + scale = (quantVal * 100UL) / ((uint32_t) hjpeg->QuantTable0[JPEG_ZIGZAG_ORDER[i + j]]); + + if (scale <= 100UL) + { + quality += (200UL - scale) / 2UL; + } + else + { + quality += 5000UL / scale; + } + } + } + + i += 4UL; + tableAddress ++; + } + + return (quality / 64UL); +} +/** + * @} + */ + +/** + * @} + */ +#endif /* JPEG */ +#endif /* HAL_JPEG_MODULE_ENABLED */ + + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c new file mode 100644 index 0000000..e3e7208 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c @@ -0,0 +1,2216 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_ltdc.c + * @author MCD Application Team + * @brief LTDC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the LTDC peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors 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 + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LTDC HAL driver can be used as follows: + + (#) Declare a LTDC_HandleTypeDef handle structure, for example: LTDC_HandleTypeDef hltdc; + + (#) Initialize the LTDC low level resources by implementing the HAL_LTDC_MspInit() API: + (##) Enable the LTDC interface clock + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the LTDC interrupt priority + (+++) Enable the NVIC LTDC IRQ Channel + + (#) Initialize the required configuration through the following parameters: + the LTDC timing, the horizontal and vertical polarity, the pixel clock polarity, + Data Enable polarity and the LTDC background color value using HAL_LTDC_Init() function + + *** Configuration *** + ========================= + [..] + (#) Program the required configuration through the following parameters: + the pixel format, the blending factors, input alpha value, the window size + and the image size using HAL_LTDC_ConfigLayer() function for foreground + or/and background layer. + + (#) Optionally, configure and enable the CLUT using HAL_LTDC_ConfigCLUT() and + HAL_LTDC_EnableCLUT functions. + + (#) Optionally, enable the Dither using HAL_LTDC_EnableDither(). + + (#) Optionally, configure and enable the Color keying using HAL_LTDC_ConfigColorKeying() + and HAL_LTDC_EnableColorKeying functions. + + (#) Optionally, configure LineInterrupt using HAL_LTDC_ProgramLineEvent() + function + + (#) If needed, reconfigure and change the pixel format value, the alpha value + value, the window size, the window position and the layer start address + for foreground or/and background layer using respectively the following + functions: HAL_LTDC_SetPixelFormat(), HAL_LTDC_SetAlpha(), HAL_LTDC_SetWindowSize(), + HAL_LTDC_SetWindowPosition() and HAL_LTDC_SetAddress(). + + (#) Variant functions with _NoReload suffix allows to set the LTDC configuration/settings without immediate reload. + This is useful in case when the program requires to modify serval LTDC settings (on one or both layers) + then applying(reload) these settings in one shot by calling the function HAL_LTDC_Reload(). + + After calling the _NoReload functions to set different color/format/layer settings, + the program shall call the function HAL_LTDC_Reload() to apply(reload) these settings. + Function HAL_LTDC_Reload() can be called with the parameter ReloadType set to LTDC_RELOAD_IMMEDIATE if + an immediate reload is required. + Function HAL_LTDC_Reload() can be called with the parameter ReloadType set to LTDC_RELOAD_VERTICAL_BLANKING if + the reload should be done in the next vertical blanking period, + this option allows to avoid display flicker by applying the new settings during the vertical blanking period. + + + (#) To control LTDC state you can use the following function: HAL_LTDC_GetState() + + *** LTDC HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in LTDC HAL driver. + + (+) __HAL_LTDC_ENABLE: Enable the LTDC. + (+) __HAL_LTDC_DISABLE: Disable the LTDC. + (+) __HAL_LTDC_LAYER_ENABLE: Enable an LTDC Layer. + (+) __HAL_LTDC_LAYER_DISABLE: Disable an LTDC Layer. + (+) __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG: Reload Layer Configuration. + (+) __HAL_LTDC_GET_FLAG: Get the LTDC pending flags. + (+) __HAL_LTDC_CLEAR_FLAG: Clear the LTDC pending flags. + (+) __HAL_LTDC_ENABLE_IT: Enable the specified LTDC interrupts. + (+) __HAL_LTDC_DISABLE_IT: Disable the specified LTDC interrupts. + (+) __HAL_LTDC_GET_IT_SOURCE: Check whether the specified LTDC interrupt has occurred or not. + + [..] + (@) You can refer to the LTDC HAL driver header file for more useful macros + + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_LTDC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use function HAL_LTDC_RegisterCallback() to register a callback. + + [..] + Function HAL_LTDC_RegisterCallback() allows to register following callbacks: + (+) LineEventCallback : LTDC Line Event Callback. + (+) ReloadEventCallback : LTDC Reload Event Callback. + (+) ErrorCallback : LTDC Error Callback + (+) MspInitCallback : LTDC MspInit. + (+) MspDeInitCallback : LTDC MspDeInit. + [..] + This function takes as parameters the HAL peripheral handle, the callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_LTDC_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_LTDC_UnRegisterCallback() takes as parameters the HAL peripheral handle + and the callback ID. + [..] + This function allows to reset following callbacks: + (+) LineEventCallback : LTDC Line Event Callback + (+) ReloadEventCallback : LTDC Reload Event Callback + (+) ErrorCallback : LTDC Error Callback + (+) MspInitCallback : LTDC MspInit + (+) MspDeInitCallback : LTDC MspDeInit. + + [..] + By default, after the HAL_LTDC_Init and when the state is HAL_LTDC_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_LTDC_LineEventCallback(), HAL_LTDC_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak (surcharged) functions in the HAL_LTDC_Init() and HAL_LTDC_DeInit() + only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_LTDC_Init() and HAL_LTDC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_LTDC_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_LTDC_STATE_READY or HAL_LTDC_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_LTDC_RegisterCallback() before calling HAL_LTDC_DeInit() + or HAL_LTDC_Init() function. + + [..] + When the compilation define USE_HAL_LTDC_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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +#ifdef HAL_LTDC_MODULE_ENABLED + +#if defined (LTDC) + +/** @defgroup LTDC LTDC + * @brief LTDC HAL module driver + * @{ + */ + + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup LTDC_Private_Define LTDC Private Define + * @{ + */ +#define LTDC_TIMEOUT_VALUE ((uint32_t)100U) /* 100ms */ +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void LTDC_SetConfig(LTDC_HandleTypeDef *hltdc, const LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx); +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup LTDC_Exported_Functions LTDC Exported Functions + * @{ + */ + +/** @defgroup LTDC_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 LTDC + (+) De-initialize the LTDC + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the LTDC according to the specified parameters in the LTDC_InitTypeDef. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_Init(LTDC_HandleTypeDef *hltdc) +{ + uint32_t tmp; + uint32_t tmp1; + + /* Check the LTDC peripheral state */ + if (hltdc == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_LTDC_ALL_INSTANCE(hltdc->Instance)); + assert_param(IS_LTDC_HSYNC(hltdc->Init.HorizontalSync)); + assert_param(IS_LTDC_VSYNC(hltdc->Init.VerticalSync)); + assert_param(IS_LTDC_AHBP(hltdc->Init.AccumulatedHBP)); + assert_param(IS_LTDC_AVBP(hltdc->Init.AccumulatedVBP)); + assert_param(IS_LTDC_AAH(hltdc->Init.AccumulatedActiveH)); + assert_param(IS_LTDC_AAW(hltdc->Init.AccumulatedActiveW)); + assert_param(IS_LTDC_TOTALH(hltdc->Init.TotalHeigh)); + assert_param(IS_LTDC_TOTALW(hltdc->Init.TotalWidth)); + assert_param(IS_LTDC_HSPOL(hltdc->Init.HSPolarity)); + assert_param(IS_LTDC_VSPOL(hltdc->Init.VSPolarity)); + assert_param(IS_LTDC_DEPOL(hltdc->Init.DEPolarity)); + assert_param(IS_LTDC_PCPOL(hltdc->Init.PCPolarity)); + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + if (hltdc->State == HAL_LTDC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hltdc->Lock = HAL_UNLOCKED; + + /* Reset the LTDC callback to the legacy weak callbacks */ + hltdc->LineEventCallback = HAL_LTDC_LineEventCallback; /* Legacy weak LineEventCallback */ + hltdc->ReloadEventCallback = HAL_LTDC_ReloadEventCallback; /* Legacy weak ReloadEventCallback */ + hltdc->ErrorCallback = HAL_LTDC_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hltdc->MspInitCallback == NULL) + { + hltdc->MspInitCallback = HAL_LTDC_MspInit; + } + /* Init the low level hardware */ + hltdc->MspInitCallback(hltdc); + } +#else + if (hltdc->State == HAL_LTDC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hltdc->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_LTDC_MspInit(hltdc); + } +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Configure the HS, VS, DE and PC polarity */ + hltdc->Instance->GCR &= ~(LTDC_GCR_HSPOL | LTDC_GCR_VSPOL | LTDC_GCR_DEPOL | LTDC_GCR_PCPOL); + hltdc->Instance->GCR |= (uint32_t)(hltdc->Init.HSPolarity | hltdc->Init.VSPolarity | \ + hltdc->Init.DEPolarity | hltdc->Init.PCPolarity); + + /* Set Synchronization size */ + tmp = (hltdc->Init.HorizontalSync << 16U); + WRITE_REG(hltdc->Instance->SSCR, (tmp | hltdc->Init.VerticalSync)); + + /* Set Accumulated Back porch */ + tmp = (hltdc->Init.AccumulatedHBP << 16U); + WRITE_REG(hltdc->Instance->BPCR, (tmp | hltdc->Init.AccumulatedVBP)); + + /* Set Accumulated Active Width */ + tmp = (hltdc->Init.AccumulatedActiveW << 16U); + WRITE_REG(hltdc->Instance->AWCR, (tmp | hltdc->Init.AccumulatedActiveH)); + + /* Set Total Width */ + tmp = (hltdc->Init.TotalWidth << 16U); + WRITE_REG(hltdc->Instance->TWCR, (tmp | hltdc->Init.TotalHeigh)); + + /* Set the background color value */ + tmp = ((uint32_t)(hltdc->Init.Backcolor.Green) << 8U); + tmp1 = ((uint32_t)(hltdc->Init.Backcolor.Red) << 16U); + hltdc->Instance->BCCR &= ~(LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED); + hltdc->Instance->BCCR |= (tmp1 | tmp | hltdc->Init.Backcolor.Blue); + + /* Enable the Transfer Error and FIFO underrun interrupts */ + __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_TE | LTDC_IT_FU); + + /* Enable LTDC by setting LTDCEN bit */ + __HAL_LTDC_ENABLE(hltdc); + + /* Initialize the error code */ + hltdc->ErrorCode = HAL_LTDC_ERROR_NONE; + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief De-initialize the LTDC peripheral. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ + +HAL_StatusTypeDef HAL_LTDC_DeInit(LTDC_HandleTypeDef *hltdc) +{ + uint32_t tickstart; + + /* Check the LTDC peripheral state */ + if (hltdc == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_LTDC_ALL_INSTANCE(hltdc->Instance)); + + /* Disable LTDC Layer 1 */ + __HAL_LTDC_LAYER_DISABLE(hltdc, LTDC_LAYER_1); + +#if defined(LTDC_Layer2_BASE) + /* Disable LTDC Layer 2 */ + __HAL_LTDC_LAYER_DISABLE(hltdc, LTDC_LAYER_2); +#endif /* LTDC_Layer2_BASE */ + + /* Reload during vertical blanking period */ + __HAL_LTDC_VERTICAL_BLANKING_RELOAD_CONFIG(hltdc); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for VSYNC Interrupt */ + while (READ_BIT(hltdc->Instance->CDSR, LTDC_CDSR_VSYNCS) == 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > LTDC_TIMEOUT_VALUE) + { + break; + } + } + + /* Disable LTDC */ + __HAL_LTDC_DISABLE(hltdc); + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + if (hltdc->MspDeInitCallback == NULL) + { + hltdc->MspDeInitCallback = HAL_LTDC_MspDeInit; + } + /* DeInit the low level hardware */ + hltdc->MspDeInitCallback(hltdc); +#else + /* DeInit the low level hardware */ + HAL_LTDC_MspDeInit(hltdc); +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + + /* Initialize the error code */ + hltdc->ErrorCode = HAL_LTDC_ERROR_NONE; + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Initialize the LTDC MSP. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_MspInit(LTDC_HandleTypeDef *hltdc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hltdc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LTDC_MspInit could be implemented in the user file + */ +} + +/** + * @brief De-initialize the LTDC MSP. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hltdc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LTDC_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User LTDC Callback + * To be used instead of the weak predefined callback + * @param hltdc ltdc handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_LTDC_LINE_EVENT_CB_ID Line Event Callback ID + * @arg @ref HAL_LTDC_RELOAD_EVENT_CB_ID Reload Event Callback ID + * @arg @ref HAL_LTDC_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_LTDC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_LTDC_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_LTDC_RegisterCallback(LTDC_HandleTypeDef *hltdc, HAL_LTDC_CallbackIDTypeDef CallbackID, + pLTDC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hltdc); + + if (hltdc->State == HAL_LTDC_STATE_READY) + { + switch (CallbackID) + { + case HAL_LTDC_LINE_EVENT_CB_ID : + hltdc->LineEventCallback = pCallback; + break; + + case HAL_LTDC_RELOAD_EVENT_CB_ID : + hltdc->ReloadEventCallback = pCallback; + break; + + case HAL_LTDC_ERROR_CB_ID : + hltdc->ErrorCallback = pCallback; + break; + + case HAL_LTDC_MSPINIT_CB_ID : + hltdc->MspInitCallback = pCallback; + break; + + case HAL_LTDC_MSPDEINIT_CB_ID : + hltdc->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hltdc->State == HAL_LTDC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_LTDC_MSPINIT_CB_ID : + hltdc->MspInitCallback = pCallback; + break; + + case HAL_LTDC_MSPDEINIT_CB_ID : + hltdc->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hltdc); + + return status; +} + +/** + * @brief Unregister an LTDC Callback + * LTDC callback is redirected to the weak predefined callback + * @param hltdc ltdc handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_LTDC_LINE_EVENT_CB_ID Line Event Callback ID + * @arg @ref HAL_LTDC_RELOAD_EVENT_CB_ID Reload Event Callback ID + * @arg @ref HAL_LTDC_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_LTDC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_LTDC_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_LTDC_UnRegisterCallback(LTDC_HandleTypeDef *hltdc, HAL_LTDC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hltdc); + + if (hltdc->State == HAL_LTDC_STATE_READY) + { + switch (CallbackID) + { + case HAL_LTDC_LINE_EVENT_CB_ID : + hltdc->LineEventCallback = HAL_LTDC_LineEventCallback; /* Legacy weak LineEventCallback */ + break; + + case HAL_LTDC_RELOAD_EVENT_CB_ID : + hltdc->ReloadEventCallback = HAL_LTDC_ReloadEventCallback; /* Legacy weak ReloadEventCallback */ + break; + + case HAL_LTDC_ERROR_CB_ID : + hltdc->ErrorCallback = HAL_LTDC_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_LTDC_MSPINIT_CB_ID : + hltdc->MspInitCallback = HAL_LTDC_MspInit; /* Legcay weak MspInit Callback */ + break; + + case HAL_LTDC_MSPDEINIT_CB_ID : + hltdc->MspDeInitCallback = HAL_LTDC_MspDeInit; /* Legcay weak MspDeInit Callback */ + break; + + default : + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hltdc->State == HAL_LTDC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_LTDC_MSPINIT_CB_ID : + hltdc->MspInitCallback = HAL_LTDC_MspInit; /* Legcay weak MspInit Callback */ + break; + + case HAL_LTDC_MSPDEINIT_CB_ID : + hltdc->MspDeInitCallback = HAL_LTDC_MspDeInit; /* Legcay weak MspDeInit Callback */ + break; + + default : + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hltdc); + + return status; +} +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup LTDC_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides function allowing to: + (+) Handle LTDC interrupt request + +@endverbatim + * @{ + */ +/** + * @brief Handle LTDC interrupt request. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ +void HAL_LTDC_IRQHandler(LTDC_HandleTypeDef *hltdc) +{ + uint32_t isrflags = READ_REG(hltdc->Instance->ISR); + uint32_t itsources = READ_REG(hltdc->Instance->IER); + + /* Transfer Error Interrupt management ***************************************/ + if (((isrflags & LTDC_ISR_TERRIF) != 0U) && ((itsources & LTDC_IER_TERRIE) != 0U)) + { + /* Disable the transfer Error interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_TE); + + /* Clear the transfer error flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_TE); + + /* Update error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_TE; + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Transfer error Callback */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + hltdc->ErrorCallback(hltdc); +#else + /* Call legacy error callback*/ + HAL_LTDC_ErrorCallback(hltdc); +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + } + + /* FIFO underrun Interrupt management ***************************************/ + if (((isrflags & LTDC_ISR_FUIF) != 0U) && ((itsources & LTDC_IER_FUIE) != 0U)) + { + /* Disable the FIFO underrun interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_FU); + + /* Clear the FIFO underrun flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_FU); + + /* Update error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_FU; + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Transfer error Callback */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + hltdc->ErrorCallback(hltdc); +#else + /* Call legacy error callback*/ + HAL_LTDC_ErrorCallback(hltdc); +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + } + + /* Line Interrupt management ************************************************/ + if (((isrflags & LTDC_ISR_LIF) != 0U) && ((itsources & LTDC_IER_LIE) != 0U)) + { + /* Disable the Line interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_LI); + + /* Clear the Line interrupt flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_LI); + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Line interrupt Callback */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + /*Call registered Line Event callback */ + hltdc->LineEventCallback(hltdc); +#else + /*Call Legacy Line Event callback */ + HAL_LTDC_LineEventCallback(hltdc); +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + } + + /* Register reload Interrupt management ***************************************/ + if (((isrflags & LTDC_ISR_RRIF) != 0U) && ((itsources & LTDC_IER_RRIE) != 0U)) + { + /* Disable the register reload interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_RR); + + /* Clear the register reload flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_RR); + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Reload interrupt Callback */ +#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1) + /*Call registered reload Event callback */ + hltdc->ReloadEventCallback(hltdc); +#else + /*Call Legacy Reload Event callback */ + HAL_LTDC_ReloadEventCallback(hltdc); +#endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Error LTDC callback. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hltdc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LTDC_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Line Event callback. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hltdc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LTDC_LineEventCallback could be implemented in the user file + */ +} + +/** + * @brief Reload Event callback. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hltdc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LTDC_ReloadEvenCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup LTDC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the LTDC foreground or/and background parameters. + (+) Set the active layer. + (+) Configure the color keying. + (+) Configure the C-LUT. + (+) Enable / Disable the color keying. + (+) Enable / Disable the C-LUT. + (+) Update the layer position. + (+) Update the layer size. + (+) Update pixel format on the fly. + (+) Update transparency on the fly. + (+) Update address on the fly. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the LTDC Layer according to the specified + * parameters in the LTDC_InitTypeDef and create the associated handle. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pLayerCfg pointer to a LTDC_LayerCfgTypeDef structure that contains + * the configuration information for the Layer. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0)); + assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1)); + assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0)); + assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1)); + assert_param(IS_LTDC_PIXEL_FORMAT(pLayerCfg->PixelFormat)); + assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha)); + assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha0)); + assert_param(IS_LTDC_BLENDING_FACTOR1(pLayerCfg->BlendingFactor1)); + assert_param(IS_LTDC_BLENDING_FACTOR2(pLayerCfg->BlendingFactor2)); + assert_param(IS_LTDC_CFBLL(pLayerCfg->ImageWidth)); + assert_param(IS_LTDC_CFBLNBR(pLayerCfg->ImageHeight)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Copy new layer configuration into handle structure */ + hltdc->LayerCfg[LayerIdx] = *pLayerCfg; + + /* Configure the LTDC Layer */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Configure the color keying. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param RGBValue the color key value + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Configure the default color values */ + LTDC_LAYER(hltdc, LayerIdx)->CKCR &= ~(LTDC_LxCKCR_CKBLUE | LTDC_LxCKCR_CKGREEN | LTDC_LxCKCR_CKRED); + LTDC_LAYER(hltdc, LayerIdx)->CKCR = RGBValue; + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Load the color lookup table. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pCLUT pointer to the color lookup table address. + * @param CLUTSize the color lookup table size. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigCLUT(LTDC_HandleTypeDef *hltdc, const uint32_t *pCLUT, uint32_t CLUTSize, + uint32_t LayerIdx) +{ + uint32_t tmp; + uint32_t counter; + const uint32_t *pcolorlut = pCLUT; + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + for (counter = 0U; (counter < CLUTSize); counter++) + { + if (hltdc->LayerCfg[LayerIdx].PixelFormat == LTDC_PIXEL_FORMAT_AL44) + { + tmp = (((counter + (16U * counter)) << 24U) | ((uint32_t)(*pcolorlut) & 0xFFU) | \ + ((uint32_t)(*pcolorlut) & 0xFF00U) | ((uint32_t)(*pcolorlut) & 0xFF0000U)); + } + else + { + tmp = ((counter << 24U) | ((uint32_t)(*pcolorlut) & 0xFFU) | \ + ((uint32_t)(*pcolorlut) & 0xFF00U) | ((uint32_t)(*pcolorlut) & 0xFF0000U)); + } + + pcolorlut++; + + /* Specifies the C-LUT address and RGB value */ + LTDC_LAYER(hltdc, LayerIdx)->CLUTWR = tmp; + } + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable the color keying. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_EnableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Enable LTDC color keying by setting COLKEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_COLKEN; + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable the color keying. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_DisableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable LTDC color keying by setting COLKEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_COLKEN; + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable the color lookup table. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_EnableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Enable LTDC color lookup table by setting CLUTEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CLUTEN; + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable the color lookup table. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_DisableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable LTDC color lookup table by setting CLUTEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CLUTEN; + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable Dither. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_LTDC_EnableDither(LTDC_HandleTypeDef *hltdc) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Enable Dither by setting DTEN bit */ + LTDC->GCR |= (uint32_t)LTDC_GCR_DEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable Dither. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_LTDC_DisableDither(LTDC_HandleTypeDef *hltdc) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable Dither by setting DTEN bit */ + LTDC->GCR &= ~(uint32_t)LTDC_GCR_DEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Set the LTDC window size. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param XSize LTDC Pixel per line + * @param YSize LTDC Line number + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetWindowSize(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters (Layers parameters)*/ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_CFBLL(XSize)); + assert_param(IS_LTDC_CFBLNBR(YSize)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* update horizontal stop */ + pLayerCfg->WindowX1 = XSize + pLayerCfg->WindowX0; + + /* update vertical stop */ + pLayerCfg->WindowY1 = YSize + pLayerCfg->WindowY0; + + /* Reconfigures the color frame buffer pitch in byte */ + pLayerCfg->ImageWidth = XSize; + + /* Reconfigures the frame buffer line number */ + pLayerCfg->ImageHeight = YSize; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Set the LTDC window position. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param X0 LTDC window X offset + * @param Y0 LTDC window Y offset + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetWindowPosition(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_CFBLL(X0)); + assert_param(IS_LTDC_CFBLNBR(Y0)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* update horizontal start/stop */ + pLayerCfg->WindowX0 = X0; + pLayerCfg->WindowX1 = X0 + pLayerCfg->ImageWidth; + + /* update vertical start/stop */ + pLayerCfg->WindowY0 = Y0; + pLayerCfg->WindowY1 = Y0 + pLayerCfg->ImageHeight; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the pixel format. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Pixelformat new pixel format value. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetPixelFormat(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_PIXEL_FORMAT(Pixelformat)); + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the pixel format */ + pLayerCfg->PixelFormat = Pixelformat; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the layer alpha value. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Alpha new alpha value. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetAlpha(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_ALPHA(Alpha)); + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the Alpha value */ + pLayerCfg->Alpha = Alpha; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} +/** + * + * @brief Reconfigure the frame buffer Address. + * + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Address new address value. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetAddress(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the Address */ + pLayerCfg->FBStartAdress = Address; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Set the Immediate Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Function used to reconfigure the pitch for specific cases where the attached LayerIdx buffer have a width + * that is larger than the one intended to be displayed on screen. Example of a buffer 800x480 attached to + * layer for which we want to read and display on screen only a portion 320x240 taken in the center + * of the buffer. + * The pitch in pixels will be in that case 800 pixels and not 320 pixels as initially configured by previous + * call to HAL_LTDC_ConfigLayer(). + * @note This function should be called only after a previous call to HAL_LTDC_ConfigLayer() to modify the default + * pitch configured by HAL_LTDC_ConfigLayer() when required (refer to example described just above). + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LinePitchInPixels New line pitch in pixels to configure for LTDC layer 'LayerIdx'. + * @param LayerIdx LTDC layer index concerned by the modification of line pitch. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetPitch(LTDC_HandleTypeDef *hltdc, uint32_t LinePitchInPixels, uint32_t LayerIdx) +{ + uint32_t tmp; + uint32_t pitchUpdate; + uint32_t pixelFormat; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* get LayerIdx used pixel format */ + pixelFormat = hltdc->LayerCfg[LayerIdx].PixelFormat; + + if (pixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) + { + tmp = 4U; + } + else if (pixelFormat == LTDC_PIXEL_FORMAT_RGB888) + { + tmp = 3U; + } + else if ((pixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \ + (pixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \ + (pixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || \ + (pixelFormat == LTDC_PIXEL_FORMAT_AL88)) + { + tmp = 2U; + } + else + { + tmp = 1U; + } + + pitchUpdate = ((LinePitchInPixels * tmp) << 16U); + + /* Clear previously set standard pitch */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLR &= ~LTDC_LxCFBLR_CFBP; + + /* Set the Reload type as immediate update of LTDC pitch configured above */ + LTDC->SRCR |= LTDC_SRCR_IMR; + + /* Set new line pitch value */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLR |= pitchUpdate; + + /* Set the Reload type as immediate update of LTDC pitch configured above */ + LTDC->SRCR |= LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Define the position of the line interrupt. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Line Line Interrupt Position. + * @note User application may resort to HAL_LTDC_LineEventCallback() at line interrupt generation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ProgramLineEvent(LTDC_HandleTypeDef *hltdc, uint32_t Line) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LIPOS(Line)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable the Line interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_LI); + + /* Set the Line Interrupt position */ + LTDC->LIPCR = (uint32_t)Line; + + /* Enable the Line interrupt */ + __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_LI); + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reload LTDC Layers configuration. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param ReloadType This parameter can be one of the following values : + * LTDC_RELOAD_IMMEDIATE : Immediate Reload + * LTDC_RELOAD_VERTICAL_BLANKING : Reload in the next Vertical Blanking + * @note User application may resort to HAL_LTDC_ReloadEventCallback() at reload interrupt generation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_Reload(LTDC_HandleTypeDef *hltdc, uint32_t ReloadType) +{ + /* Check the parameters */ + assert_param(IS_LTDC_RELOAD(ReloadType)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Enable the Reload interrupt */ + __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_RR); + + /* Apply Reload type */ + hltdc->Instance->SRCR = ReloadType; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Configure the LTDC Layer according to the specified without reloading + * parameters in the LTDC_InitTypeDef and create the associated handle. + * Variant of the function HAL_LTDC_ConfigLayer without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pLayerCfg pointer to a LTDC_LayerCfgTypeDef structure that contains + * the configuration information for the Layer. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigLayer_NoReload(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, + uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0)); + assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1)); + assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0)); + assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1)); + assert_param(IS_LTDC_PIXEL_FORMAT(pLayerCfg->PixelFormat)); + assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha)); + assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha0)); + assert_param(IS_LTDC_BLENDING_FACTOR1(pLayerCfg->BlendingFactor1)); + assert_param(IS_LTDC_BLENDING_FACTOR2(pLayerCfg->BlendingFactor2)); + assert_param(IS_LTDC_CFBLL(pLayerCfg->ImageWidth)); + assert_param(IS_LTDC_CFBLNBR(pLayerCfg->ImageHeight)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Copy new layer configuration into handle structure */ + hltdc->LayerCfg[LayerIdx] = *pLayerCfg; + + /* Configure the LTDC Layer */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Set the LTDC window size without reloading. + * Variant of the function HAL_LTDC_SetWindowSize without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param XSize LTDC Pixel per line + * @param YSize LTDC Line number + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetWindowSize_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, + uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters (Layers parameters)*/ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_CFBLL(XSize)); + assert_param(IS_LTDC_CFBLNBR(YSize)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* update horizontal stop */ + pLayerCfg->WindowX1 = XSize + pLayerCfg->WindowX0; + + /* update vertical stop */ + pLayerCfg->WindowY1 = YSize + pLayerCfg->WindowY0; + + /* Reconfigures the color frame buffer pitch in byte */ + pLayerCfg->ImageWidth = XSize; + + /* Reconfigures the frame buffer line number */ + pLayerCfg->ImageHeight = YSize; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Set the LTDC window position without reloading. + * Variant of the function HAL_LTDC_SetWindowPosition without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param X0 LTDC window X offset + * @param Y0 LTDC window Y offset + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetWindowPosition_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, + uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_CFBLL(X0)); + assert_param(IS_LTDC_CFBLNBR(Y0)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* update horizontal start/stop */ + pLayerCfg->WindowX0 = X0; + pLayerCfg->WindowX1 = X0 + pLayerCfg->ImageWidth; + + /* update vertical start/stop */ + pLayerCfg->WindowY0 = Y0; + pLayerCfg->WindowY1 = Y0 + pLayerCfg->ImageHeight; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the pixel format without reloading. + * Variant of the function HAL_LTDC_SetPixelFormat without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDfef structure that contains + * the configuration information for the LTDC. + * @param Pixelformat new pixel format value. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetPixelFormat_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_PIXEL_FORMAT(Pixelformat)); + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the pixel format */ + pLayerCfg->PixelFormat = Pixelformat; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the layer alpha value without reloading. + * Variant of the function HAL_LTDC_SetAlpha without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Alpha new alpha value. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetAlpha_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_ALPHA(Alpha)); + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the Alpha value */ + pLayerCfg->Alpha = Alpha; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the frame buffer Address without reloading. + * Variant of the function HAL_LTDC_SetAddress without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Address new address value. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetAddress_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the Address */ + pLayerCfg->FBStartAdress = Address; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Function used to reconfigure the pitch for specific cases where the attached LayerIdx buffer have a width + * that is larger than the one intended to be displayed on screen. Example of a buffer 800x480 attached to + * layer for which we want to read and display on screen only a portion 320x240 taken in the center + * of the buffer. + * The pitch in pixels will be in that case 800 pixels and not 320 pixels as initially configured by + * previous call to HAL_LTDC_ConfigLayer(). + * @note This function should be called only after a previous call to HAL_LTDC_ConfigLayer() to modify the default + * pitch configured by HAL_LTDC_ConfigLayer() when required (refer to example described just above). + * Variant of the function HAL_LTDC_SetPitch without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LinePitchInPixels New line pitch in pixels to configure for LTDC layer 'LayerIdx'. + * @param LayerIdx LTDC layer index concerned by the modification of line pitch. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetPitch_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LinePitchInPixels, uint32_t LayerIdx) +{ + uint32_t tmp; + uint32_t pitchUpdate; + uint32_t pixelFormat; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* get LayerIdx used pixel format */ + pixelFormat = hltdc->LayerCfg[LayerIdx].PixelFormat; + + if (pixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) + { + tmp = 4U; + } + else if (pixelFormat == LTDC_PIXEL_FORMAT_RGB888) + { + tmp = 3U; + } + else if ((pixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \ + (pixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \ + (pixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || \ + (pixelFormat == LTDC_PIXEL_FORMAT_AL88)) + { + tmp = 2U; + } + else + { + tmp = 1U; + } + + pitchUpdate = ((LinePitchInPixels * tmp) << 16U); + + /* Clear previously set standard pitch */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLR &= ~LTDC_LxCFBLR_CFBP; + + /* Set new line pitch value */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLR |= pitchUpdate; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Configure the color keying without reloading. + * Variant of the function HAL_LTDC_ConfigColorKeying without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param RGBValue the color key value + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Configure the default color values */ + LTDC_LAYER(hltdc, LayerIdx)->CKCR &= ~(LTDC_LxCKCR_CKBLUE | LTDC_LxCKCR_CKGREEN | LTDC_LxCKCR_CKRED); + LTDC_LAYER(hltdc, LayerIdx)->CKCR = RGBValue; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable the color keying without reloading. + * Variant of the function HAL_LTDC_EnableColorKeying without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_EnableColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Enable LTDC color keying by setting COLKEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_COLKEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable the color keying without reloading. + * Variant of the function HAL_LTDC_DisableColorKeying without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_DisableColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable LTDC color keying by setting COLKEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_COLKEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable the color lookup table without reloading. + * Variant of the function HAL_LTDC_EnableCLUT without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_EnableCLUT_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable LTDC color lookup table by setting CLUTEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CLUTEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable the color lookup table without reloading. + * Variant of the function HAL_LTDC_DisableCLUT without immediate reload. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: + * LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_DisableCLUT_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable LTDC color lookup table by setting CLUTEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CLUTEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup LTDC_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 LTDC handle state. + (+) Get the LTDC handle error code. + +@endverbatim + * @{ + */ + +/** + * @brief Return the LTDC handle state. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL state + */ +HAL_LTDC_StateTypeDef HAL_LTDC_GetState(const LTDC_HandleTypeDef *hltdc) +{ + return hltdc->State; +} + +/** + * @brief Return the LTDC handle error code. + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval LTDC Error Code + */ +uint32_t HAL_LTDC_GetError(const LTDC_HandleTypeDef *hltdc) +{ + return hltdc->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup LTDC_Private_Functions LTDC Private Functions + * @{ + */ + +/** + * @brief Configure the LTDC peripheral + * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pLayerCfg Pointer LTDC Layer Configuration structure + * @param LayerIdx LTDC Layer index. + * This parameter can be one of the following values: LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1) + * @retval None + */ +static void LTDC_SetConfig(LTDC_HandleTypeDef *hltdc, const LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx) +{ + uint32_t tmp; + uint32_t tmp1; + uint32_t tmp2; + + /* Configure the horizontal start and stop position */ + tmp = ((pLayerCfg->WindowX1 + ((hltdc->Instance->BPCR & LTDC_BPCR_AHBP) >> 16U)) << 16U); + LTDC_LAYER(hltdc, LayerIdx)->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS); + LTDC_LAYER(hltdc, LayerIdx)->WHPCR = ((pLayerCfg->WindowX0 + \ + ((hltdc->Instance->BPCR & LTDC_BPCR_AHBP) >> 16U) + 1U) | tmp); + + /* Configure the vertical start and stop position */ + tmp = ((pLayerCfg->WindowY1 + (hltdc->Instance->BPCR & LTDC_BPCR_AVBP)) << 16U); + LTDC_LAYER(hltdc, LayerIdx)->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS); + LTDC_LAYER(hltdc, LayerIdx)->WVPCR = ((pLayerCfg->WindowY0 + (hltdc->Instance->BPCR & LTDC_BPCR_AVBP) + 1U) | tmp); + + /* Specifies the pixel format */ + LTDC_LAYER(hltdc, LayerIdx)->PFCR &= ~(LTDC_LxPFCR_PF); + LTDC_LAYER(hltdc, LayerIdx)->PFCR = (pLayerCfg->PixelFormat); + + /* Configure the default color values */ + tmp = ((uint32_t)(pLayerCfg->Backcolor.Green) << 8U); + tmp1 = ((uint32_t)(pLayerCfg->Backcolor.Red) << 16U); + tmp2 = (pLayerCfg->Alpha0 << 24U); + WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->DCCR, (pLayerCfg->Backcolor.Blue | tmp | tmp1 | tmp2)); + + /* Specifies the constant alpha value */ + LTDC_LAYER(hltdc, LayerIdx)->CACR &= ~(LTDC_LxCACR_CONSTA); + LTDC_LAYER(hltdc, LayerIdx)->CACR = (pLayerCfg->Alpha); + + /* Specifies the blending factors */ + LTDC_LAYER(hltdc, LayerIdx)->BFCR &= ~(LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1); + LTDC_LAYER(hltdc, LayerIdx)->BFCR = (pLayerCfg->BlendingFactor1 | pLayerCfg->BlendingFactor2); + + /* Configure the color frame buffer start address */ + WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CFBAR, pLayerCfg->FBStartAdress); + + if (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) + { + tmp = 4U; + } + else if (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB888) + { + tmp = 3U; + } + else if ((pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \ + (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \ + (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || \ + (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_AL88)) + { + tmp = 2U; + } + else + { + tmp = 1U; + } + + /* Configure the color frame buffer pitch in byte */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLR &= ~(LTDC_LxCFBLR_CFBLL | LTDC_LxCFBLR_CFBP); + LTDC_LAYER(hltdc, LayerIdx)->CFBLR = (((pLayerCfg->ImageWidth * tmp) << 16U) | + (((pLayerCfg->WindowX1 - pLayerCfg->WindowX0) * tmp) + 7U)); + /* Configure the frame buffer line number */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLNR &= ~(LTDC_LxCFBLNR_CFBLNBR); + LTDC_LAYER(hltdc, LayerIdx)->CFBLNR = (pLayerCfg->ImageHeight); + + /* Enable LTDC_Layer by setting LEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_LEN; +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* LTDC */ + +#endif /* HAL_LTDC_MODULE_ENABLED */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c new file mode 100644 index 0000000..49d32d7 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_ltdc_ex.c + * @author MCD Application Team + * @brief LTDC Extension HAL module driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +#if defined(HAL_LTDC_MODULE_ENABLED) && defined(HAL_DSI_MODULE_ENABLED) + +#if defined (LTDC) && defined (DSI) + +/** @defgroup LTDCEx LTDCEx + * @brief LTDC HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup LTDCEx_Exported_Functions LTDC Extended Exported Functions + * @{ + */ + +/** @defgroup LTDCEx_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 LTDC + +@endverbatim + * @{ + */ + +/** + * @brief Retrieve common parameters from DSI Video mode configuration structure + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param VidCfg pointer to a DSI_VidCfgTypeDef structure that contains + * the DSI video mode configuration parameters + * @note The implementation of this function is taking into account the LTDC + * polarities inversion as described in the current LTDC specification + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDCEx_StructInitFromVideoConfig(LTDC_HandleTypeDef *hltdc, DSI_VidCfgTypeDef *VidCfg) +{ + /* Retrieve signal polarities from DSI */ + + /* The following polarity is inverted: + LTDC_DEPOLARITY_AL <-> LTDC_DEPOLARITY_AH */ + +#if !defined(POLARITIES_INVERSION_UPDATED) + /* Note 1 : Code in line w/ Current LTDC specification */ + hltdc->Init.DEPolarity = (VidCfg->DEPolarity == \ + DSI_DATA_ENABLE_ACTIVE_HIGH) ? LTDC_DEPOLARITY_AL : LTDC_DEPOLARITY_AH; + hltdc->Init.VSPolarity = (VidCfg->VSPolarity == DSI_VSYNC_ACTIVE_HIGH) ? LTDC_VSPOLARITY_AH : LTDC_VSPOLARITY_AL; + hltdc->Init.HSPolarity = (VidCfg->HSPolarity == DSI_HSYNC_ACTIVE_HIGH) ? LTDC_HSPOLARITY_AH : LTDC_HSPOLARITY_AL; +#else + /* Note 2: Code to be used in case LTDC polarities inversion updated in the specification */ + hltdc->Init.DEPolarity = VidCfg->DEPolarity << 29; + hltdc->Init.VSPolarity = VidCfg->VSPolarity << 29; + hltdc->Init.HSPolarity = VidCfg->HSPolarity << 29; +#endif /* POLARITIES_INVERSION_UPDATED */ + + /* Retrieve vertical timing parameters from DSI */ + hltdc->Init.VerticalSync = VidCfg->VerticalSyncActive - 1U; + hltdc->Init.AccumulatedVBP = VidCfg->VerticalSyncActive + VidCfg->VerticalBackPorch - 1U; + hltdc->Init.AccumulatedActiveH = VidCfg->VerticalSyncActive + VidCfg->VerticalBackPorch + \ + VidCfg->VerticalActive - 1U; + hltdc->Init.TotalHeigh = VidCfg->VerticalSyncActive + VidCfg->VerticalBackPorch + \ + VidCfg->VerticalActive + VidCfg->VerticalFrontPorch - 1U; + + return HAL_OK; +} + +/** + * @brief Retrieve common parameters from DSI Adapted command mode configuration structure + * @param hltdc pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param CmdCfg pointer to a DSI_CmdCfgTypeDef structure that contains + * the DSI command mode configuration parameters + * @note The implementation of this function is taking into account the LTDC + * polarities inversion as described in the current LTDC specification + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDCEx_StructInitFromAdaptedCommandConfig(LTDC_HandleTypeDef *hltdc, DSI_CmdCfgTypeDef *CmdCfg) +{ + /* Retrieve signal polarities from DSI */ + + /* The following polarities are inverted: + LTDC_DEPOLARITY_AL <-> LTDC_DEPOLARITY_AH + LTDC_VSPOLARITY_AL <-> LTDC_VSPOLARITY_AH + LTDC_HSPOLARITY_AL <-> LTDC_HSPOLARITY_AH)*/ + +#if !defined(POLARITIES_INVERSION_UPDATED) + /* Note 1 : Code in line w/ Current LTDC specification */ + hltdc->Init.DEPolarity = (CmdCfg->DEPolarity == \ + DSI_DATA_ENABLE_ACTIVE_HIGH) ? LTDC_DEPOLARITY_AL : LTDC_DEPOLARITY_AH; + hltdc->Init.VSPolarity = (CmdCfg->VSPolarity == DSI_VSYNC_ACTIVE_HIGH) ? LTDC_VSPOLARITY_AL : LTDC_VSPOLARITY_AH; + hltdc->Init.HSPolarity = (CmdCfg->HSPolarity == DSI_HSYNC_ACTIVE_HIGH) ? LTDC_HSPOLARITY_AL : LTDC_HSPOLARITY_AH; +#else + /* Note 2: Code to be used in case LTDC polarities inversion updated in the specification */ + hltdc->Init.DEPolarity = CmdCfg->DEPolarity << 29; + hltdc->Init.VSPolarity = CmdCfg->VSPolarity << 29; + hltdc->Init.HSPolarity = CmdCfg->HSPolarity << 29; +#endif /* POLARITIES_INVERSION_UPDATED */ + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* LTDC && DSI */ + +#endif /* HAL_LTCD_MODULE_ENABLED && HAL_DSI_MODULE_ENABLED */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c new file mode 100644 index 0000000..11d2f4b --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c @@ -0,0 +1,2236 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_hal_mdf.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following + * functionalities of the Multi-function Digital Filter (MDF) + * peripheral: + * + Initialization and de-initialization + * + Acquisition + * + Clock absence detection + * + ****************************************************************************** + * @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 ##### + ============================================================================== + [..] + *** Initialization and de-initialization *** + ============================================ + [..] + (#) User has first to initialize ADF instance. + (#) As prerequisite, fill in the HAL_MDF_MspInit() : + (++) Enable ADFz clock interface with __HAL_RCC_ADFz_CLK_ENABLE(). + (++) Enable the clocks for the used GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE(). + (++) Configure these pins in alternate mode using HAL_GPIO_Init(). + (++) If interrupt mode is used, enable and configure ADFz_FLTx + interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). + (++) If DMA mode is used, initialize and configure DMA. + (#) Configure the common parameters, serial interface parameters and + filter bitstream selection by calling HAL_MDF_Init() function. + + [..] + (#) User can de-initialize ADF instance with HAL_MDF_DeInit() function. + + *** Acquisition *** + =================== + [..] + (#) Configure filter parameters and start acquisition using HAL_MDF_AcqStart(), + HAL_MDF_AcqStart_IT() or HAL_MDF_AcqStart_DMA(). + (#) In polling mode : + (++) Use HAL_MDF_PollForAcq() to detect the end of acquisition. + Use HAL_MDF_GetAcqValue to get acquisition value. + (++) Use HAL_MDF_PollForSndLvl() to detect and get + new sound level value and ambient noise value. + (++) Use HAL_MDF_PollForSad() to detect sound activity. + (#) In interrupt mode : + (++) HAL_MDF_AcqCpltCallback() will be called at the end of acquisition. + Use HAL_MDF_GetAcqValue to get acquisition value. + (++) HAL_MDF_SndLvlCallback() will be called when new + sound level and ambient noise values are available. + (++) HAL_MDF_SadCallback() will be called when + sound activity detection occurs. + (++) HAL_MDF_ErrorCallback() will be called if overflow, filter overrun or + saturation occurs. + Use HAL_MDF_GetErrorCode() to get the corresponding error. + (#) In DMA mode : + (++) HAL_MDF_AcqHalfCpltCallback() and HAL_MDF_AcqCpltCallback() will be called + respectively at the half acquisition and at the acquisition complete. + (++) HAL_MDF_SndLvlCallback() will be called when new + sound level and ambient noise values are available. + (++) HAL_MDF_SadCallback() will be called when + sound activity detection occurs. + (++) HAL_MDF_ErrorCallback() will be called if overflow, filter overrun, + saturation or DMA error occurs. + Use HAL_MDF_GetErrorCode() to get the corresponding error. + (#) Use HAL_MDF_GenerateTrgo() to generate pulse on TRGO signal. + (#) During acquisition, use HAL_MDF_SetDelay() and HAL_MDF_GetDelay() to respectively + set and get the delay on data source. + (#) During acquisition, use HAL_MDF_SetGain() and HAL_MDF_GetGain() to respectively + set and get the filter gain. + (#) Stop acquisition using HAL_MDF_AcqStop(), HAL_MDF_AcqStop_IT() or HAL_MDF_AcqStop_DMA(). + + *** Clock absence detection *** + =============================== + [..] + (#) Clock absence detection is always enabled so no need to start clock absence detection + in polling mode. + Use HAL_MDF_CkabStart_IT() to start clock absence detection in interrupt mode. + (#) In polling mode, use HAL_MDF_PollForCkab() to detect the clock absence. + (#) In interrupt mode, HAL_MDF_ErrorCallback() will be called if clock absence detection + occurs. + Use HAL_MDF_GetErrorCode() to get the corresponding error. + (#) Stop clock absence detection in interrupt mode using HAL_MDF_CkabStop_IT(). + + *** generic functions *** + ========================= + [..] + (#) HAL_MDF_IRQHandler will be called when ADF interrupt occurs. + (#) HAL_MDF_ErrorCallback will be called when ADF error occurs. + (#) Use HAL_MDF_GetState() to get the current ADF instance state. + (#) Use HAL_MDF_GetErrorCode() to get the current ADF instance error code. + + *** Callback registration *** + ============================= + [..] + The compilation define USE_HAL_MDF_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use functions HAL_MDF_RegisterCallback(), HAL_MDF_RegisterOldCallback() + or HAL_MDF_RegisterSndLvlCallback() to register a user callback. + + [..] + Function HAL_MDF_RegisterCallback() allows to register following callbacks : + (+) AcqCpltCallback : Acquisition complete callback. + (+) AcqHalfCpltCallback : Acquisition half complete callback. + (+) SadCallback : Sound activity detection callback (only for ADF instance). + (+) ErrorCallback : Error callback. + (+) MspInitCallback : MSP init callback. + (+) MspDeInitCallback : MSP de-init callback. + [..] + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + For specific sound level callback use dedicated register callback : + HAL_MDF_RegisterSndLvlCallback(). + + [..] + Use function HAL_MDF_UnRegisterCallback() to reset a callback to the default weak function. + + [..] + HAL_MDF_UnRegisterCallback() takes as parameters the HAL peripheral handle and the Callback ID. + [..] + This function allows to reset following callbacks : + (+) AcqCpltCallback : Acquisition complete callback. + (+) AcqHalfCpltCallback : Acquisition half complete callback. + (+) SadCallback : Sound activity detection callback (only for ADF instance). + (+) ErrorCallback : Error callback. + (+) MspInitCallback : MSP init callback. + (+) MspDeInitCallback : MSP de-init callback. + + [..] + For specific sound level callback use dedicated unregister callback : + HAL_MDF_UnRegisterSndLvlCallback(). + + [..] + By default, after the call of init function and if the state is RESET + all callbacks are reset to the corresponding legacy weak functions : + examples HAL_MDF_AcqCpltCallback(), HAL_MDF_ErrorCallback(). + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak functions in the init and de-init only when these + callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the init and de-init 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/de-init. + In that case first register the MspInit/MspDeInit user callbacks using + HAL_MDF_RegisterCallback() before calling init or de-init function. + + [..] + When the compilation define USE_HAL_MDF_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak callbacks are used. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup MDF MDF + * @brief MDF HAL module driver + * @{ + */ + +#ifdef HAL_MDF_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup MDF_Private_Typedefs MDF Private Typedefs + * @{ + */ +/** + * @} + */ + +/* Private define ------------------------------------------------------------*/ +/** @defgroup MDF_Private_Constants MDF Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup MDF_Private_Variables MDF Private Variables + * @{ + */ +static MDF_HandleTypeDef *v_mdfHandle = NULL; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup MDF_Private_Functions MDF Private Functions + * @{ + */ +static void MDF_AcqStart(MDF_HandleTypeDef *const hmdf, const MDF_FilterConfigTypeDef *const pFilterConfig); +static void MDF_DmaXferCpltCallback(DMA_HandleTypeDef *hdma); +static void MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef *hdma); +static void MDF_DmaErrorCallback(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup MDF_Exported_Functions MDF Exported Functions + * @{ + */ + +/** @defgroup MDF_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 : + (+) Initialize the ADF instance. + (+) De-initialize the ADF instance. + (+) Register and unregister callbacks. +@endverbatim + * @{ + */ + +/** + * @brief Initialize the MDF instance according to the specified parameters + * in the MDF_InitTypeDef structure and initialize the associated handle. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_Init(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check MDF handle */ + if (hmdf == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check parameters */ + assert_param(IS_MDF_ALL_INSTANCE(hmdf->Instance)); + assert_param(IS_MDF_FILTER_BITSTREAM(hmdf->Init.FilterBistream)); + assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.SerialInterface.Activation)); + + /* Check that instance has not been already initialized */ + if (v_mdfHandle != NULL) + { + status = HAL_ERROR; + } + else + { +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + /* Reset callback pointers to the weak predefined callbacks */ + hmdf->SndLvCallback = HAL_MDF_SndLvlCallback; + hmdf->SadCallback = HAL_MDF_SadCallback; + hmdf->AcqCpltCallback = HAL_MDF_AcqCpltCallback; + hmdf->AcqHalfCpltCallback = HAL_MDF_AcqHalfCpltCallback; + hmdf->ErrorCallback = HAL_MDF_ErrorCallback; + + /* Call MDF MSP init function */ + if (hmdf->MspInitCallback == NULL) + { + hmdf->MspInitCallback = HAL_MDF_MspInit; + } + hmdf->MspInitCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + /* Call MDF MSP init function */ + HAL_MDF_MspInit(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + + /* Configure common parameters */ + /* Check clock generator status */ + if ((ADF1->CKGCR & MDF_CKGCR_CKGACTIVE) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Configure processing clock divider, output clock divider, + output clock pins and output clock generation trigger */ + assert_param(IS_MDF_PROC_CLOCK_DIVIDER(hmdf->Init.CommonParam.ProcClockDivider)); + assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.CommonParam.OutputClock.Activation)); + ADF1->CKGCR = 0U; + ADF1->CKGCR |= ((hmdf->Init.CommonParam.ProcClockDivider - 1U) << MDF_CKGCR_PROCDIV_Pos); + if (hmdf->Init.CommonParam.OutputClock.Activation == ENABLE) + { + assert_param(IS_MDF_OUTPUT_CLOCK_PINS(hmdf->Init.CommonParam.OutputClock.Pins)); + assert_param(IS_MDF_OUTPUT_CLOCK_DIVIDER(hmdf->Init.CommonParam.OutputClock.Divider)); + assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.CommonParam.OutputClock.Trigger.Activation)); + ADF1->CKGCR |= (((hmdf->Init.CommonParam.OutputClock.Divider - 1U) << MDF_CKGCR_CCKDIV_Pos) | + hmdf->Init.CommonParam.OutputClock.Pins | + (hmdf->Init.CommonParam.OutputClock.Pins >> 4U)); + if (hmdf->Init.CommonParam.OutputClock.Trigger.Activation == ENABLE) + { + assert_param(IS_MDF_OUTPUT_CLOCK_TRIGGER_SOURCE(hmdf->Init.CommonParam.OutputClock.Trigger.Source)); + assert_param(IS_MDF_OUTPUT_CLOCK_TRIGGER_EDGE(hmdf->Init.CommonParam.OutputClock.Trigger.Edge)); + ADF1->CKGCR |= (hmdf->Init.CommonParam.OutputClock.Trigger.Source | + hmdf->Init.CommonParam.OutputClock.Trigger.Edge | + MDF_CKGCR_CKGMOD); + } + } + + /* Activate clock generator */ + ADF1->CKGCR |= MDF_CKGCR_CKGDEN; + } + + /* Configure serial interface */ + if ((status == HAL_OK) && (hmdf->Init.SerialInterface.Activation == ENABLE)) + { + /* Check serial interface status */ + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Configure mode, clock source and threshold */ + assert_param(IS_MDF_SITF_MODE(hmdf->Init.SerialInterface.Mode)); + assert_param(IS_MDF_SITF_CLOCK_SOURCE(hmdf->Init.SerialInterface.ClockSource)); + assert_param(IS_MDF_SITF_THRESHOLD(hmdf->Init.SerialInterface.Threshold)); + hmdf->Instance->SITFCR = 0U; + hmdf->Instance->SITFCR |= ((hmdf->Init.SerialInterface.Threshold << MDF_SITFCR_STH_Pos) | + hmdf->Init.SerialInterface.Mode | hmdf->Init.SerialInterface.ClockSource); + + /* Activate serial interface */ + hmdf->Instance->SITFCR |= MDF_SITFCR_SITFEN; + } + } + + if (status == HAL_OK) + { + /* Configure filter bitstream */ + hmdf->Instance->BSMXCR &= ~(MDF_BSMXCR_BSSEL); + hmdf->Instance->BSMXCR |= hmdf->Init.FilterBistream; + + /* Update instance pointer */ + v_mdfHandle = hmdf; + + /* Update error code and state */ + hmdf->ErrorCode = MDF_ERROR_NONE; + hmdf->State = HAL_MDF_STATE_READY; + } + } + } + + /* Return function status */ + return status; +} + +/** + * @brief De-initialize the MDF instance. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_DeInit(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check MDF handle */ + if (hmdf == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check parameters */ + assert_param(IS_MDF_ALL_INSTANCE(hmdf->Instance)); + + /* Check that instance has not been already deinitialized */ + if (v_mdfHandle == NULL) + { + status = HAL_ERROR; + } + else + { + /* Disable sound activity detector if needed */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN); + } + + /* Disable filter if needed */ + if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U) + { + hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN); + } + + /* Disable serial interface if needed */ + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) != 0U) + { + hmdf->Instance->SITFCR &= ~(MDF_SITFCR_SITFEN); + } + + /* Disable all interrupts and clear all pending flags */ + hmdf->Instance->DFLTIER = 0U; + hmdf->Instance->DFLTISR = 0xFFFFFFFFU; + + /* Disable clock generator */ + ADF1->CKGCR &= ~(MDF_CKGCR_CKGDEN); + + /* Call MDF MSP deinit function */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + if (hmdf->MspDeInitCallback == NULL) + { + hmdf->MspDeInitCallback = HAL_MDF_MspDeInit; + } + hmdf->MspDeInitCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_MspDeInit(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + + /* Update instance pointer */ + v_mdfHandle = (MDF_HandleTypeDef *) NULL; + + /* Update state */ + hmdf->State = HAL_MDF_STATE_RESET; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Initialize the MDF instance MSP. + * @param hmdf MDF handle. + * @retval None. + */ +__weak void HAL_MDF_MspInit(MDF_HandleTypeDef *hmdf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_MspInit could be implemented in the user file */ +} + +/** + * @brief De-initialize the MDF instance MSP. + * @param hmdf MDF handle. + * @retval None. + */ +__weak void HAL_MDF_MspDeInit(MDF_HandleTypeDef *hmdf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_MspDeInit could be implemented in the user file */ +} + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) +/** + * @brief Register a user MDF callback to be used instead of the weak predefined callback. + * @param hmdf MDF handle. + * @param CallbackID ID of the callback to be registered. + * This parameter can be one of the following values: + * @arg @ref HAL_MDF_ACQ_COMPLETE_CB_ID acquisition complete callback ID. + * @arg @ref HAL_MDF_ACQ_HALFCOMPLETE_CB_ID acquisition half complete callback ID. + * @arg @ref HAL_MDF_SAD_CB_ID sound activity detector callback ID (only for ADF instance). + * @arg @ref HAL_MDF_ERROR_CB_ID error callback ID. + * @arg @ref HAL_MDF_MSPINIT_CB_ID MSP init callback ID. + * @arg @ref HAL_MDF_MSPDEINIT_CB_ID MSP de-init callback ID. + * @param pCallback pointer to the callback function. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_RegisterCallback(MDF_HandleTypeDef *hmdf, + HAL_MDF_CallbackIDTypeDef CallbackID, + pMDF_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pCallback == NULL) + { + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + else + { + if (hmdf->State == HAL_MDF_STATE_READY) + { + switch (CallbackID) + { + case HAL_MDF_ACQ_COMPLETE_CB_ID : + hmdf->AcqCpltCallback = pCallback; + break; + case HAL_MDF_ACQ_HALFCOMPLETE_CB_ID : + hmdf->AcqHalfCpltCallback = pCallback; + break; + case HAL_MDF_SAD_CB_ID : + hmdf->SadCallback = pCallback; + break; + case HAL_MDF_ERROR_CB_ID : + hmdf->ErrorCallback = pCallback; + break; + case HAL_MDF_MSPINIT_CB_ID : + hmdf->MspInitCallback = pCallback; + break; + case HAL_MDF_MSPDEINIT_CB_ID : + hmdf->MspDeInitCallback = pCallback; + break; + default : + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else if (hmdf->State == HAL_MDF_STATE_RESET) + { + switch (CallbackID) + { + case HAL_MDF_MSPINIT_CB_ID : + hmdf->MspInitCallback = pCallback; + break; + case HAL_MDF_MSPDEINIT_CB_ID : + hmdf->MspDeInitCallback = pCallback; + break; + default : + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Unregister a user MDF callback. + * MDF callback is redirected to the weak predefined callback. + * @param hmdf MDF handle. + * @param CallbackID ID of the callback to be unregistered. + * This parameter can be one of the following values: + * @arg @ref HAL_MDF_ACQ_COMPLETE_CB_ID acquisition complete callback ID. + * @arg @ref HAL_MDF_ACQ_HALFCOMPLETE_CB_ID acquisition half complete callback ID. + * @arg @ref HAL_MDF_SAD_CB_ID sound activity detector callback ID (only for ADF instance). + * @arg @ref HAL_MDF_ERROR_CB_ID error callback ID. + * @arg @ref HAL_MDF_MSPINIT_CB_ID MSP init callback ID. + * @arg @ref HAL_MDF_MSPDEINIT_CB_ID MSP de-init callback ID. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_UnRegisterCallback(MDF_HandleTypeDef *hmdf, + HAL_MDF_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hmdf->State == HAL_MDF_STATE_READY) + { + switch (CallbackID) + { + case HAL_MDF_ACQ_COMPLETE_CB_ID : + hmdf->AcqCpltCallback = HAL_MDF_AcqCpltCallback; + break; + case HAL_MDF_ACQ_HALFCOMPLETE_CB_ID : + hmdf->AcqHalfCpltCallback = HAL_MDF_AcqHalfCpltCallback; + break; + case HAL_MDF_SAD_CB_ID : + hmdf->SadCallback = HAL_MDF_SadCallback; + break; + case HAL_MDF_ERROR_CB_ID : + hmdf->ErrorCallback = HAL_MDF_ErrorCallback; + break; + case HAL_MDF_MSPINIT_CB_ID : + hmdf->MspInitCallback = HAL_MDF_MspInit; + break; + case HAL_MDF_MSPDEINIT_CB_ID : + hmdf->MspDeInitCallback = HAL_MDF_MspDeInit; + break; + default : + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else if (hmdf->State == HAL_MDF_STATE_RESET) + { + switch (CallbackID) + { + case HAL_MDF_MSPINIT_CB_ID : + hmdf->MspInitCallback = HAL_MDF_MspInit; + break; + case HAL_MDF_MSPDEINIT_CB_ID : + hmdf->MspDeInitCallback = HAL_MDF_MspDeInit; + break; + default : + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + + /* Return function status */ + return status; +} + +/** + * @brief Register specific MDF sound level callback + * to be used instead of the weak predefined callback. + * @param hmdf MDF handle. + * @param pCallback pointer to the sound level callback function. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_RegisterSndLvlCallback(MDF_HandleTypeDef *hmdf, + pMDF_SndLvlCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pCallback == NULL) + { + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + else + { + if (hmdf->State == HAL_MDF_STATE_READY) + { + hmdf->SndLvCallback = pCallback; + } + else + { + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Unregister the specific MDF sound level callback. + * MDF sound level callback is redirected to the weak predefined callback. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_UnRegisterSndLvlCallback(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hmdf->State == HAL_MDF_STATE_READY) + { + hmdf->SndLvCallback = HAL_MDF_SndLvlCallback; + } + else + { + /* Update error code and status */ + hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + + /* Return function status */ + return status; +} +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup MDF_Exported_Functions_Group2 Acquisition functions + * @brief Acquisition functions + * +@verbatim + ============================================================================== + ##### Acquisition functions ##### + ============================================================================== + [..] This section provides functions allowing to : + (+) Start and stop acquisition in polling, interrupt or DMA mode. + (+) Wait and get acquisition values. + (+) Generate pulse on TRGO signal. + (+) Modify and get some filter parameters during acquisition. + (+) Wait and get sound level values. + (+) Detect sound activity. +@endverbatim + * @{ + */ + +/** + * @brief This function allows to start acquisition in polling mode. + * @param hmdf MDF handle. + * @param pFilterConfig Filter configuration parameters. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_AcqStart(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pFilterConfig == NULL) + { + status = HAL_ERROR; + } + else + { + assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode)); + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation)); + if ((pFilterConfig->SoundActivity.Activation == ENABLE) && + ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) || + (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) || + (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT))) + { + status = HAL_ERROR; + } + /* Check state */ + else if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + /* Check filter status */ + else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Check SAD status */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Configure filter and start acquisition */ + hmdf->Instance->DFLTCR = 0U; + MDF_AcqStart(hmdf, pFilterConfig); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to poll for available acquisition value. + * @param hmdf MDF handle. + * @param Timeout Timeout value in milliseconds. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_PollForAcq(MDF_HandleTypeDef *hmdf, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + else + { + uint32_t tickstart = HAL_GetTick(); + + /* Wait for available acquisition value */ + while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_RXNEF) != MDF_DFLTISR_RXNEF) && (status == HAL_OK)) + { + /* Check the timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + status = HAL_TIMEOUT; + } + } + } + + /* Check if data overflow, saturation or reshape filter occurs */ + uint32_t error_flags = (hmdf->Instance->DFLTISR & (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF)); + if (error_flags != 0U) + { + /* Update error code */ + if ((error_flags & MDF_DFLTISR_DOVRF) == MDF_DFLTISR_DOVRF) + { + hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW; + } + if ((error_flags & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF) + { + hmdf->ErrorCode |= MDF_ERROR_SATURATION; + } + if ((error_flags & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF) + { + hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN; + } + + /* Clear corresponding flags */ + hmdf->Instance->DFLTISR |= error_flags; + + /* Call error callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->ErrorCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_ErrorCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + + if (status == HAL_OK) + { + /* Update state only in asynchronous single shot mode */ + if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_ACQMOD) == MDF_MODE_ASYNC_SINGLE) + { + hmdf->State = HAL_MDF_STATE_READY; + } + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to get acquisition value. + * @param hmdf MDF handle. + * @param pValue Acquisition value on 24 MSB. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_GetAcqValue(const MDF_HandleTypeDef *hmdf, int32_t *pValue) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pValue == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + } + } + + if (status == HAL_OK) + { + /* Get acquisition value */ + *pValue = (int32_t) hmdf->Instance->DFLTDR; + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to stop acquisition in polling mode. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_AcqStop(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + /* Check if state is ready and filter active */ + if (hmdf->State == HAL_MDF_STATE_READY) + { + if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE) + { + status = HAL_ERROR; + } + } + else + { + status = HAL_ERROR; + } + } + else + { + /* Disable sound activity detector if needed */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN); + } + } + + if (status == HAL_OK) + { + /* Disable filter */ + hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN); + + /* Clear all potential pending flags */ + hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF | + MDF_DFLTISR_SDDETF | MDF_DFLTISR_SDLVLF); + + /* Update state */ + hmdf->State = HAL_MDF_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to start acquisition in interrupt mode. + * @param hmdf MDF handle. + * @param pFilterConfig Filter configuration parameters. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_AcqStart_IT(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pFilterConfig == NULL) + { + status = HAL_ERROR; + } + else + { + assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode)); + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation)); + if ((pFilterConfig->SoundActivity.Activation == ENABLE) && + ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) || + (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) || + (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT))) + { + status = HAL_ERROR; + } + /* Check state */ + else if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + /* Check filter status */ + else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Check SAD status */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + if ((pFilterConfig->SoundActivity.Activation == DISABLE) || + (pFilterConfig->SoundActivity.DataMemoryTransfer != MDF_SAD_NO_MEMORY_TRANSFER)) + { + /* Enable data overflow and fifo threshold interrupts */ + hmdf->Instance->DFLTIER |= (MDF_DFLTIER_DOVRIE | MDF_DFLTIER_FTHIE); + } + + if (pFilterConfig->ReshapeFilter.Activation == ENABLE) + { + /* Enable reshape filter overrun interrupt */ + hmdf->Instance->DFLTIER |= MDF_DFLTIER_RFOVRIE; + } + + /* Enable saturation interrupt */ + hmdf->Instance->DFLTIER |= MDF_DFLTIER_SATIE; + + if (pFilterConfig->SoundActivity.Activation == ENABLE) + { + /* Enable sound level value ready and sound activity detection interrupts */ + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.SoundLevelInterrupt)); + hmdf->Instance->DFLTIER |= (pFilterConfig->SoundActivity.SoundLevelInterrupt == ENABLE) ? + (MDF_DFLTIER_SDLVLIE | MDF_DFLTIER_SDDETIE) : + MDF_DFLTIER_SDDETIE; + } + + /* Configure filter and start acquisition */ + hmdf->Instance->DFLTCR = 0U; + MDF_AcqStart(hmdf, pFilterConfig); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to stop acquisition in interrupt mode. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_AcqStop_IT(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + /* Check if state is ready and filter active */ + if (hmdf->State == HAL_MDF_STATE_READY) + { + if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE) + { + status = HAL_ERROR; + } + } + else + { + status = HAL_ERROR; + } + } + else + { + /* Disable sound activity detector if needed */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN); + } + } + + if (status == HAL_OK) + { + /* Disable filter */ + hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN); + + /* Disable interrupts and clear all potential pending flags */ + hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_FTHIE | MDF_DFLTIER_DOVRIE | MDF_DFLTIER_SATIE | + MDF_DFLTIER_RFOVRIE | MDF_DFLTIER_SDDETIE | MDF_DFLTIER_SDLVLIE); + hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF | + MDF_DFLTISR_SDDETF | MDF_DFLTISR_SDLVLF); + + /* Update state */ + hmdf->State = HAL_MDF_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to start acquisition in DMA mode. + * @param hmdf MDF handle. + * @param pFilterConfig Filter configuration parameters. + * @param pDmaConfig DMA configuration parameters. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_AcqStart_DMA(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig, + const MDF_DmaConfigTypeDef *pDmaConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if ((pFilterConfig == NULL) || (pDmaConfig == NULL)) + { + status = HAL_ERROR; + } + else + { + assert_param(IS_FUNCTIONAL_STATE(pDmaConfig->MsbOnly)); + assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode)); + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation)); + if ((pFilterConfig->SoundActivity.Activation == ENABLE) && + ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) || + (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) || + (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT))) + { + status = HAL_ERROR; + } + /* Check state */ + else if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + /* Check filter status */ + else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Check SAD status */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + uint32_t SrcAddress; + + if (pFilterConfig->ReshapeFilter.Activation == ENABLE) + { + /* Enable reshape filter overrun interrupt */ + hmdf->Instance->DFLTIER |= MDF_DFLTIER_RFOVRIE; + } + + /* Enable saturation interrupt */ + hmdf->Instance->DFLTIER |= MDF_DFLTIER_SATIE; + + if (pFilterConfig->SoundActivity.Activation == ENABLE) + { + /* Enable sound level value ready and sound activity detection interrupts */ + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.SoundLevelInterrupt)); + hmdf->Instance->DFLTIER |= (pFilterConfig->SoundActivity.SoundLevelInterrupt == ENABLE) ? + (MDF_DFLTIER_SDLVLIE | MDF_DFLTIER_SDDETIE) : + MDF_DFLTIER_SDDETIE; + } + + /* Enable MDF DMA requests */ + hmdf->Instance->DFLTCR = MDF_DFLTCR_DMAEN; + + /* Start DMA transfer */ + hmdf->hdma->XferCpltCallback = MDF_DmaXferCpltCallback; + hmdf->hdma->XferHalfCpltCallback = MDF_DmaXferHalfCpltCallback; + hmdf->hdma->XferErrorCallback = MDF_DmaErrorCallback; + SrcAddress = (pDmaConfig->MsbOnly == ENABLE) ? (((uint32_t) &hmdf->Instance->DFLTDR) + 2U) : + (uint32_t) &hmdf->Instance->DFLTDR; + if ((hmdf->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hmdf->hdma->LinkedListQueue != NULL) + { + hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = pDmaConfig->DataLength; + hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = SrcAddress; + hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = pDmaConfig->Address; + + status = HAL_DMAEx_List_Start_IT(hmdf->hdma); + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hmdf->hdma, SrcAddress, pDmaConfig->Address, pDmaConfig->DataLength); + } + if (status != HAL_OK) + { + /* Update state */ + hmdf->State = HAL_MDF_STATE_ERROR; + status = HAL_ERROR; + } + else + { + /* Configure filter and start acquisition */ + MDF_AcqStart(hmdf, pFilterConfig); + } + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to stop acquisition in DMA mode. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_AcqStop_DMA(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check if state is ready and filter active */ + if (hmdf->State == HAL_MDF_STATE_READY) + { + if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE) + { + status = HAL_ERROR; + } + } + else + { + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + else + { + /* Stop the DMA transfer */ + if (HAL_DMA_Abort(hmdf->hdma) != HAL_OK) + { + /* Update state */ + hmdf->State = HAL_MDF_STATE_ERROR; + status = HAL_ERROR; + } + } + } + + if (status == HAL_OK) + { + /* Disable sound activity detector if needed */ + if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U) + { + hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN); + } + + /* Disable filter */ + hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN); + + /* Disable interrupts and clear all potential pending flags */ + hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_SATIE | MDF_DFLTIER_RFOVRIE | MDF_DFLTIER_SDDETIE | + MDF_DFLTIER_SDLVLIE); + hmdf->Instance->DFLTISR |= (MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF | MDF_DFLTISR_SDDETF | + MDF_DFLTISR_SDLVLF); + + /* Disable MDF DMA requests */ + hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DMAEN); + + /* Update state */ + hmdf->State = HAL_MDF_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to generate pulse on TRGO signal. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_GenerateTrgo(const MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_READY) + { + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Check if trigger output control is already active */ + if ((ADF1->GCR & MDF_GCR_TRGO) == MDF_GCR_TRGO) + { + status = HAL_ERROR; + } + else + { + /* Generate pulse on trigger output control signal */ + ADF1->GCR |= MDF_GCR_TRGO; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to set delay to apply on data source in number of samples. + * @param hmdf MDF handle. + * @param Delay Delay to apply on data source in number of samples. + * This parameter must be a number between Min_Data = 0 and Max_Data = 127. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_SetDelay(MDF_HandleTypeDef *hmdf, uint32_t Delay) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + assert_param(IS_MDF_DELAY(Delay)); + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + else + { + /* Check if bitstream delay is already active */ + if ((hmdf->Instance->DLYCR & MDF_DLYCR_SKPBF) == MDF_DLYCR_SKPBF) + { + status = HAL_ERROR; + } + else + { + /* Configure bitstream delay */ + hmdf->Instance->DLYCR |= Delay; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to get current delay applied on data source in number of samples. + * @param hmdf MDF handle. + * @param pDelay Current delay applied on data source in number of samples. + * This value is between Min_Data = 0 and Max_Data = 127. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_GetDelay(const MDF_HandleTypeDef *hmdf, uint32_t *pDelay) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pDelay == NULL) + { + status = HAL_ERROR; + } + /* Check state */ + else if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + else + { + /* Get current bitstream delay */ + *pDelay = (hmdf->Instance->DLYCR & MDF_DLYCR_SKPDLY); + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to set filter gain. + * @param hmdf MDF handle. + * @param Gain Filter gain in step of around 3db (from -48db to 72dB). + * This parameter must be a number between Min_Data = -16 and Max_Data = 24. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_SetGain(MDF_HandleTypeDef *hmdf, int32_t Gain) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + assert_param(IS_MDF_GAIN(Gain)); + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + else + { + uint32_t register_gain_value; + uint32_t tmp_register; + + if (Gain < 0) + { + int32_t adjust_gain; + + /* adjust gain value to set on register for negative value (offset of -16) */ + adjust_gain = Gain - 16; + register_gain_value = ((uint32_t) adjust_gain & 0x3FU); + } + else + { + /* for positive value, no offset to apply */ + register_gain_value = (uint32_t) Gain; + } + /* Set gain */ + tmp_register = (hmdf->Instance->DFLTCICR & ~(MDF_DFLTCICR_SCALE)); + hmdf->Instance->DFLTCICR = (tmp_register | (register_gain_value << MDF_DFLTCICR_SCALE_Pos)); + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to get filter gain. + * @param hmdf MDF handle. + * @param pGain Filter gain in step of around 3db (from -48db to 72dB). + * This parameter is between Min_Data = -16 and Max_Data = 24. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_GetGain(const MDF_HandleTypeDef *hmdf, int32_t *pGain) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pGain == NULL) + { + status = HAL_ERROR; + } + /* Check state */ + else if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + else + { + uint32_t register_gain_value; + + /* Get current gain */ + register_gain_value = ((hmdf->Instance->DFLTCICR & MDF_DFLTCICR_SCALE) >> MDF_DFLTCICR_SCALE_Pos); + if (register_gain_value > 31U) + { + /* adjust gain value to set on register for negative value (offset of +16) */ + register_gain_value |= 0xFFFFFFC0U; + *pGain = (int32_t) register_gain_value + 16; + } + else + { + /* for positive value, no offset to apply */ + *pGain = (int32_t) register_gain_value; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to poll for sound level data. + * @param hmdf MDF handle. + * @param Timeout Timeout value in milliseconds. + * @param pSoundLevel Sound level. + This parameter can be a value between Min_Data = 0 and Max_Data = 32767. + * @param pAmbientNoise Ambient noise. + This parameter can be a value between Min_Data = 0 and Max_Data = 32767. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_PollForSndLvl(MDF_HandleTypeDef *hmdf, uint32_t Timeout, uint32_t *pSoundLevel, + uint32_t *pAmbientNoise) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if ((pSoundLevel == NULL) || (pAmbientNoise == NULL)) + { + status = HAL_ERROR; + } + /* Check state */ + else if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + /* Check SAD status */ + else if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) == 0U) + { + status = HAL_ERROR; + } + else + { + uint32_t tickstart = HAL_GetTick(); + + /* Wait for available sound level data */ + while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SDLVLF) != MDF_DFLTISR_SDLVLF) && (status == HAL_OK)) + { + /* Check the timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + status = HAL_TIMEOUT; + } + } + } + + if (status == HAL_OK) + { + /* Get sound level */ + *pSoundLevel = hmdf->Instance->SADSDLVR; + + /* Get ambient noise */ + *pAmbientNoise = hmdf->Instance->SADANLVR; + + /* Clear sound level ready flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDLVLF; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to poll for sound activity detection. + * @param hmdf MDF handle. + * @param Timeout Timeout value in milliseconds. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_PollForSad(MDF_HandleTypeDef *hmdf, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + status = HAL_ERROR; + } + /* Check SAD status */ + else if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) == 0U) + { + status = HAL_ERROR; + } + else + { + uint32_t tickstart = HAL_GetTick(); + + /* Wait for sound activity detection */ + while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SDDETF) != MDF_DFLTISR_SDDETF) && (status == HAL_OK)) + { + /* Check the timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + status = HAL_TIMEOUT; + } + } + } + + if (status == HAL_OK) + { + /* Clear sound activity detection flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDDETF; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief MDF acquisition complete callback. + * @param hmdf MDF handle. + * @retval None. + */ +__weak void HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_AcqCpltCallback could be implemented in the user file */ +} + +/** + * @brief MDF acquisition half complete callback. + * @param hmdf MDF handle. + * @retval None. + */ +__weak void HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_AcqHalfCpltCallback could be implemented in the user file */ +} + +/** + * @brief MDF sound level callback. + * @param hmdf MDF handle. + * @param SoundLevel Sound level value computed by sound activity detector. + * This parameter can be a value between Min_Data = 0 and Max_Data = 32767. + * @param AmbientNoise Ambient noise value computed by sound activity detector. + * This parameter can be a value between Min_Data = 0 and Max_Data = 32767. + * @retval None. + */ +__weak void HAL_MDF_SndLvlCallback(MDF_HandleTypeDef *hmdf, uint32_t SoundLevel, uint32_t AmbientNoise) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + UNUSED(SoundLevel); + UNUSED(AmbientNoise); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_SndLvlCallback could be implemented in the user file */ +} + +/** + * @brief MDF sound activity detector callback. + * @param hmdf MDF handle. + * @retval None. + */ +__weak void HAL_MDF_SadCallback(MDF_HandleTypeDef *hmdf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_SadCallback could be implemented in the user file */ +} + +/** + * @} + */ + +/** @defgroup MDF_Exported_Functions_Group3 Clock absence detection functions + * @brief Clock absence detection functions + * +@verbatim + ============================================================================== + ##### Clock absence detection functions ##### + ============================================================================== + [..] This section provides functions allowing to : + (+) Start and stop clock absence detection in interrupt mode. + (+) Detect clock absence. +@endverbatim + * @{ + */ + +/** + * @brief This function allows to poll for the clock absence detection. + * @param hmdf MDF handle. + * @param Timeout Timeout value in milliseconds. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_PollForCkab(MDF_HandleTypeDef *hmdf, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Check serial interface status and mode */ + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U) + { + status = HAL_ERROR; + } + else + { + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE) + { + status = HAL_ERROR; + } + } + } + + if (status == HAL_OK) + { + uint32_t tickstart = HAL_GetTick(); + + /* Wait for clock absence detection */ + while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_CKABF) != MDF_DFLTISR_CKABF) && (status == HAL_OK)) + { + /* Check the timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + status = HAL_TIMEOUT; + } + } + } + + if (status == HAL_OK) + { + /* Clear clock absence detection flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to start clock absence detection in interrupt mode. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_CkabStart_IT(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Check serial interface status and mode */ + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U) + { + status = HAL_ERROR; + } + else + { + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE) + { + status = HAL_ERROR; + } + } + } + + if (status == HAL_OK) + { + /* Clear clock absence detection flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF; + + /* Check clock absence detection flag */ + if ((hmdf->Instance->DFLTISR & MDF_DFLTISR_CKABF) == MDF_DFLTISR_CKABF) + { + status = HAL_ERROR; + } + else + { + /* Enable clock absence detection interrupt */ + hmdf->Instance->DFLTIER |= MDF_DFLTIER_CKABIE; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief This function allows to stop clock absence detection in interrupt mode. + * @param hmdf MDF handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_MDF_CkabStop_IT(MDF_HandleTypeDef *hmdf) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check state */ + if (hmdf->State != HAL_MDF_STATE_ACQUISITION) + { + if (hmdf->State != HAL_MDF_STATE_READY) + { + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Check serial interface status and mode */ + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U) + { + status = HAL_ERROR; + } + else + { + if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE) + { + status = HAL_ERROR; + } + } + } + + if (status == HAL_OK) + { + /* Disable clock absence detection interrupt */ + hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_CKABIE); + + /* Clear potential pending clock absence detection flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF; + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup MDF_Exported_Functions_Group4 Generic functions + * @brief Generic functions + * +@verbatim + ============================================================================== + ##### Generic functions ##### + ============================================================================== + [..] This section provides functions allowing to : + (+) Handle MDF interrupt. + (+) Inform user that error occurs. + (+) Get the current MDF instance state. + (+) Get the current MDF instance error code. +@endverbatim + * @{ + */ + +/** + * @brief This function handles the MDF interrupts. + * @param hmdf MDF handle. + * @retval None. + */ +void HAL_MDF_IRQHandler(MDF_HandleTypeDef *hmdf) +{ + uint32_t tmp_reg1; + uint32_t tmp_reg2; + uint32_t interrupts; + + /* Read current flags and interrupts and determine which ones occur */ + tmp_reg1 = hmdf->Instance->DFLTIER; + tmp_reg2 = hmdf->Instance->DFLTISR; + interrupts = (tmp_reg1 & tmp_reg2); + + /* Check if data overflow occurs */ + if ((interrupts & MDF_DFLTISR_DOVRF) == MDF_DFLTISR_DOVRF) + { + /* Clear data overflow flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_DOVRF; + + /* Update error code */ + hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW; + + /* Call error callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->ErrorCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_ErrorCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + /* Check if RXFIFO threshold occurs */ + else if ((interrupts & MDF_DFLTISR_FTHF) == MDF_DFLTISR_FTHF) + { + /* Call acquisition complete callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->AcqCpltCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_AcqCpltCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + + /* Update state only in asynchronous single shot mode */ + if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_ACQMOD) == MDF_MODE_ASYNC_SINGLE) + { + hmdf->State = HAL_MDF_STATE_READY; + } + } + /* Check if reshape filter overrun occurs */ + else if ((interrupts & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF) + { + /* Clear reshape filter overrun flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_RFOVRF; + + /* Update error code */ + hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN; + + /* Call error callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->ErrorCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_ErrorCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + /* Check if clock absence detection occurs */ + else if ((interrupts & MDF_DFLTISR_CKABF) == MDF_DFLTISR_CKABF) + { + /* Clear clock absence detection flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF; + + /* Update error code */ + hmdf->ErrorCode |= MDF_ERROR_CLOCK_ABSENCE; + + /* Call error callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->ErrorCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_ErrorCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + /* Check if saturation occurs */ + else if ((interrupts & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF) + { + /* Clear saturation flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_SATF; + + /* Update error code */ + hmdf->ErrorCode |= MDF_ERROR_SATURATION; + + /* Call error callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->ErrorCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_ErrorCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + /* Check if sound activity detection occurs */ + else if ((interrupts & MDF_DFLTISR_SDDETF) == MDF_DFLTISR_SDDETF) + { + /* Clear sound activity detection flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDDETF; + + /* Call sound activity detection callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->SadCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_SadCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + else + { + /* Check if sound level ready occurs */ + if ((interrupts & MDF_DFLTISR_SDLVLF) == MDF_DFLTISR_SDLVLF) + { + uint32_t sound_level; + uint32_t ambient_noise; + + /* Get sound level */ + sound_level = hmdf->Instance->SADSDLVR; + + /* Get ambient noise */ + ambient_noise = hmdf->Instance->SADANLVR; + + /* Clear sound level ready flag */ + hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDLVLF; + + /* Call sound level callback */ +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->SndLvCallback(hmdf, sound_level, ambient_noise); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_SndLvlCallback(hmdf, sound_level, ambient_noise); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief MDF error callback. + * @param hmdf MDF handle. + * @retval None. + */ +__weak void HAL_MDF_ErrorCallback(MDF_HandleTypeDef *hmdf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmdf); + + /* NOTE : This function should not be modified, when the function is needed, + the HAL_MDF_ErrorCallback could be implemented in the user file */ +} + +/** + * @brief This function allows to get the current MDF state. + * @param hmdf MDF handle. + * @retval MDF state. + */ +HAL_MDF_StateTypeDef HAL_MDF_GetState(const MDF_HandleTypeDef *hmdf) +{ + /* Return MDF state */ + return hmdf->State; +} + +/** + * @brief This function allows to get the current MDF error. + * @param hmdf MDF handle. + * @retval MDF error code. + */ +uint32_t HAL_MDF_GetError(const MDF_HandleTypeDef *hmdf) +{ + /* Return MDF error code */ + return hmdf->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup MDF_Private_Functions + * @brief Private functions + * @{ + */ + +/** + * @brief This function allows to configure filter and start acquisition. + * @param hmdf MDF handle. + * @param pFilterConfig Filter configuration parameters. + * @retval None. + */ +static void MDF_AcqStart(MDF_HandleTypeDef *const hmdf, const MDF_FilterConfigTypeDef *const pFilterConfig) +{ + uint32_t register_gain_value; + + /* Configure acquisition mode, discard samples, trigger and fifo threshold */ + assert_param(IS_MDF_DISCARD_SAMPLES(pFilterConfig->DiscardSamples)); + assert_param(IS_MDF_FIFO_THRESHOLD(pFilterConfig->FifoThreshold)); + if ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_CONT) || + (pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE)) + { + /* Trigger parameters are not used */ + hmdf->Instance->DFLTCR |= (pFilterConfig->AcquisitionMode | pFilterConfig->FifoThreshold | + (pFilterConfig->DiscardSamples << MDF_DFLTCR_NBDIS_Pos)); + } + else + { + /* Trigger parameters are used */ + assert_param(IS_MDF_TRIGGER_SOURCE(pFilterConfig->Trigger.Source)); + assert_param(IS_MDF_TRIGGER_EDGE(pFilterConfig->Trigger.Edge)); + hmdf->Instance->DFLTCR |= (pFilterConfig->AcquisitionMode | pFilterConfig->FifoThreshold | + pFilterConfig->Trigger.Source | pFilterConfig->Trigger.Edge | + (pFilterConfig->DiscardSamples << MDF_DFLTCR_NBDIS_Pos)); + } + + /* Configure data source, CIC mode, decimation ratio and gain */ + assert_param(IS_MDF_DATA_SOURCE(pFilterConfig->DataSource)); + assert_param(IS_MDF_CIC_MODE(pFilterConfig->CicMode)); + assert_param(IS_MDF_DECIMATION_RATIO(pFilterConfig->DecimationRatio)); + assert_param(IS_MDF_GAIN(pFilterConfig->Gain)); + if (pFilterConfig->Gain < 0) + { + int32_t adjust_gain; + + /* adjust gain value to set on register for negative value (offset of -16) */ + adjust_gain = pFilterConfig->Gain - 16; + register_gain_value = ((uint32_t) adjust_gain & 0x3FU); + } + else + { + /* for positive value, no offset to apply */ + register_gain_value = (uint32_t) pFilterConfig->Gain; + } + hmdf->Instance->DFLTCICR = (pFilterConfig->DataSource | pFilterConfig->CicMode | + ((pFilterConfig->DecimationRatio - 1U) << MDF_DFLTCICR_MCICD_Pos) | + (register_gain_value << MDF_DFLTCICR_SCALE_Pos)); + + /* Configure bitstream delay */ + assert_param(IS_MDF_DELAY(pFilterConfig->Delay)); + hmdf->Instance->DLYCR = pFilterConfig->Delay; + + /* Configure reshape filter */ + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->ReshapeFilter.Activation)); + hmdf->Instance->DFLTRSFR = 0U; + if (pFilterConfig->ReshapeFilter.Activation == ENABLE) + { + /* Configure reshape filter decimation ratio */ + assert_param(IS_MDF_RSF_DECIMATION_RATIO(pFilterConfig->ReshapeFilter.DecimationRatio)); + hmdf->Instance->DFLTRSFR |= pFilterConfig->ReshapeFilter.DecimationRatio; + } + else + { + /* Bypass reshape filter */ + hmdf->Instance->DFLTRSFR |= MDF_DFLTRSFR_RSFLTBYP; + } + + /* Configure high-pass filter */ + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->HighPassFilter.Activation)); + if (pFilterConfig->HighPassFilter.Activation == ENABLE) + { + /* Configure high-pass filter cut-off frequency */ + assert_param(IS_MDF_HPF_CUTOFF_FREQ(pFilterConfig->HighPassFilter.CutOffFrequency)); + hmdf->Instance->DFLTRSFR |= pFilterConfig->HighPassFilter.CutOffFrequency; + } + else + { + /* Bypass high-pass filter */ + hmdf->Instance->DFLTRSFR |= MDF_DFLTRSFR_HPFBYP; + } + + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation)); + if (pFilterConfig->SoundActivity.Activation == ENABLE) + { + /* Configure SAD mode, frame size, hysteresis, sound trigger event + and data memory transfer only for ADF instance */ + assert_param(IS_MDF_SAD_MODE(pFilterConfig->SoundActivity.Mode)); + assert_param(IS_MDF_SAD_FRAME_SIZE(pFilterConfig->SoundActivity.FrameSize)); + if (pFilterConfig->SoundActivity.Mode != MDF_SAD_AMBIENT_NOISE_DETECTOR) + { + assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Hysteresis)); + } + assert_param(IS_MDF_SAD_SOUND_TRIGGER(pFilterConfig->SoundActivity.SoundTriggerEvent)); + assert_param(IS_MDF_SAD_DATA_MEMORY_TRANSFER(pFilterConfig->SoundActivity.DataMemoryTransfer)); + if ((pFilterConfig->SoundActivity.Mode != MDF_SAD_AMBIENT_NOISE_DETECTOR) && + (pFilterConfig->SoundActivity.Hysteresis == ENABLE)) + { + hmdf->Instance->SADCR = (pFilterConfig->SoundActivity.Mode | pFilterConfig->SoundActivity.FrameSize | + MDF_SADCR_HYSTEN | pFilterConfig->SoundActivity.SoundTriggerEvent | + pFilterConfig->SoundActivity.DataMemoryTransfer); + } + else + { + hmdf->Instance->SADCR = (pFilterConfig->SoundActivity.Mode | pFilterConfig->SoundActivity.FrameSize | + pFilterConfig->SoundActivity.SoundTriggerEvent | + pFilterConfig->SoundActivity.DataMemoryTransfer); + } + + /* Configure SAD minimum noise level, hangover window, learning frames, + ambient noise slope control and signal noise threshold only for ADF instance */ + assert_param(IS_MDF_SAD_MIN_NOISE_LEVEL(pFilterConfig->SoundActivity.MinNoiseLevel)); + assert_param(IS_MDF_SAD_HANGOVER_WINDOW(pFilterConfig->SoundActivity.HangoverWindow)); + assert_param(IS_MDF_SAD_LEARNING_FRAMES(pFilterConfig->SoundActivity.LearningFrames)); + assert_param(IS_MDF_SAD_SIGNAL_NOISE_THRESHOLD(pFilterConfig->SoundActivity.SignalNoiseThreshold)); + if (pFilterConfig->SoundActivity.Mode != MDF_SAD_SOUND_DETECTOR) + { + assert_param(IS_MDF_SAD_AMBIENT_NOISE_SLOPE(pFilterConfig->SoundActivity.AmbientNoiseSlope)); + hmdf->Instance->SADCFGR = ((pFilterConfig->SoundActivity.MinNoiseLevel << MDF_SADCFGR_ANMIN_Pos) | + pFilterConfig->SoundActivity.HangoverWindow | + pFilterConfig->SoundActivity.LearningFrames | + (pFilterConfig->SoundActivity.AmbientNoiseSlope << MDF_SADCFGR_ANSLP_Pos) | + pFilterConfig->SoundActivity.SignalNoiseThreshold); + } + else + { + hmdf->Instance->SADCFGR = ((pFilterConfig->SoundActivity.MinNoiseLevel << MDF_SADCFGR_ANMIN_Pos) | + pFilterConfig->SoundActivity.HangoverWindow | + pFilterConfig->SoundActivity.LearningFrames | + pFilterConfig->SoundActivity.SignalNoiseThreshold); + } + } + else + { + /* SAD is not used */ + hmdf->Instance->SADCR = 0U; + hmdf->Instance->SADCFGR = 0U; + } + + /* Update instance state */ + hmdf->State = HAL_MDF_STATE_ACQUISITION; + + /* Enable sound activity detector if needed */ + if (pFilterConfig->SoundActivity.Activation == ENABLE) + { + hmdf->Instance->SADCR |= MDF_SADCR_SADEN; + } + + /* Enable filter */ + hmdf->Instance->DFLTCR |= MDF_DFLTCR_DFLTEN; +} + +/** + * @brief This function handles DMA transfer complete callback. + * @param hdma DMA handle. + * @retval None. + */ +static void MDF_DmaXferCpltCallback(DMA_HandleTypeDef *hdma) +{ + MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Check if DMA in circular mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + hmdf->State = HAL_MDF_STATE_READY; + } + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->AcqCpltCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_AcqCpltCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +} + +/** + * @brief This function handles DMA half transfer complete callback. + * @param hdma DMA handle. + * @retval None. + */ +static void MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef *hdma) +{ + MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->AcqHalfCpltCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_AcqHalfCpltCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +} + +/** + * @brief This function handles DMA error callback. + * @param hdma DMA handle. + * @retval None. + */ +static void MDF_DmaErrorCallback(DMA_HandleTypeDef *hdma) +{ + MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Update error code */ + hmdf->ErrorCode |= MDF_ERROR_DMA; + +#if (USE_HAL_MDF_REGISTER_CALLBACKS == 1) + hmdf->ErrorCallback(hmdf); +#else /* USE_HAL_MDF_REGISTER_CALLBACKS */ + HAL_MDF_ErrorCallback(hmdf); +#endif /* USE_HAL_MDF_REGISTER_CALLBACKS */ +} + +/** + * @} + */ + +#endif /* HAL_MDF_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c new file mode 100644 index 0000000..251bacf --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c @@ -0,0 +1,692 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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. + * + ****************************************************************************** + * @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 + ============================================================================== + ##### PWR peripheral overview ##### + ============================================================================== + [..] + (#) The Power control (PWR) provides an overview of the supply architecture + for the different power domains and of the supply configuration + controller. + + (#) Several low-power modes are available to save power when the CPU does not need to + execute code : + (+) Sleep (CPU clock stopped and still in RUN mode) + (+) Stop (System clock stopped) + (+) Standby (System powered down) + + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + + (#) Call HAL_PWR_EnableBkUpAccess() and HAL_PWR_DisableBkUpAccess() functions + to enable/disable access to the backup domain (RCC Backup domain control + register RCC_BDCR, RTC registers, TAMP registers, backup registers and + backup SRAM). + + (#) Call HAL_PWR_ConfigPVD() after setting parameters to be configured (event + mode and voltage threshold) in order to set up the Programmed Voltage + Detector, then use HAL_PWR_EnablePVD() and HAL_PWR_DisablePVD() + functions to start and stop the PVD detection. + (+) PVD level can be one of the following values : + (++) 2V0 + (++) 2V2 + (++) 2V4 + (++) 2V5 + (++) 2V6 + (++) 2V8 + (++) 2V9 + (++) External input analog voltage PVD_IN (compared internally to + VREFINT) + + (#) Call HAL_PWR_EnableWakeUpPin() and HAL_PWR_DisableWakeUpPin() functions + with the right parameter to configure the wake up pin polarity (Low or + High), the wake up pin selection and to enable and disable it. + + (#) Call HAL_PWR_EnterSLEEPMode() function to enter the CPU in Sleep mode. + Wake-up from Sleep mode could be following to an event or an + interrupt according to low power mode intrinsic request called (__WFI() + or __WFE()). + + (#) Call HAL_PWR_EnterSTOPMode() function to enter the whole system to Stop + mode. Wake-up from Stop mode could be following to an event or an + interrupt according to low power mode intrinsic request called (__WFI() + or __WFE()). + + (#) Call HAL_PWR_EnterSTANDBYMode() function to enter the whole system in + Standby mode. Wake-up from Standby mode can be following only by an + interrupt. + + (#) Call HAL_PWR_EnableSleepOnExit() and HAL_PWR_DisableSleepOnExit() APIs to + enable and disable the Cortex-M7 re-entry in Sleep mode after an + interruption handling is over. + + (#) Call HAL_PWR_EnableSEVOnPend() and HAL_PWR_DisableSEVOnPend() functions + to configure the Cortex-M7 to wake-up after any pending event / interrupt + even if it's disabled or has insufficient priority to cause exception + entry. + + *** PWR HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in PWR HAL driver. + + (+) __HAL_PWR_GET_FLAG() : Get the PWR pending flags. + (+) __HAL_PWR_CLEAR_FLAG() : Clear the PWR pending flags. + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup PWR PWR + * @brief PWR HAL module driver + * @{ + */ + +#ifdef 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_MODE_IT (0x00010000U) +#define PVD_MODE_EVT (0x00020000U) +#define PVD_RISING_EDGE (0x00000001U) +#define PVD_FALLING_EDGE (0x00000002U) +#define PVD_RISING_FALLING_EDGE (0x00000003U) +/** + * @} + */ + +/** + * @} + */ + +/* 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 ##### + =============================================================================== + [..] + This section provides functions allowing to deinitialize power peripheral. + + [..] + After system reset, the backup domain (RCC Backup domain control register + RCC_BDCR, RTC registers, TAMP registers, backup registers and backup SRAM) + is protected against possible unwanted write accesses. + The HAL_PWR_EnableBkUpAccess() function enables the access to the backup + domain. + The HAL_PWR_DisableBkUpAccess() function disables the access to the backup + domain. + +@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->CR1, PWR_CR1_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->CR1, PWR_CR1_DBP); +} +/** + * @} + */ + + +/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions + * @brief Power Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control Functions ##### + =============================================================================== + [..] + This section provides functions allowing to control power peripheral. + + *** PVD configuration *** + ========================= + [..] + (+) The PVD is used to monitor the VDD power supply by comparing it to a + threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR1 + register). + + (+) A PVDO flag is available to indicate if VDD is higher or lower + than the PVD threshold. This event is internally connected to the EXTI + line 16 to generate an interrupt if enabled. + It is configurable through __HAL_PWR_PVD_EXTI_ENABLE_IT() macro. + + (+) The PVD is stopped in STANDBY mode. + + *** Wake-up pin configuration *** + ================================= + [..] + (+) Wake-up pin is used to wake up the system from STANDBY mode. + The pin pull is configurable through the WKUPEPR register to be in + No-pull, Pull-up and Pull-down. + The pin polarity is configurable through the WKUPEPR register to be + active on rising or falling edges. + + (+) There are up to four Wake-up pin in the STM32H7RS devices family. + + *** Low Power modes configuration *** + ===================================== + [..] + The device present 3 principles low-power modes : + (+) SLEEP mode : Cortex-M7 is stopped and all PWR domains are remaining + active (Powered and Clocked). + + (+) STOP mode : Cortex-M7 is stopped, clocks are stopped and the + regulator is running. The Main regulator or the LP + regulator could be selected. + + (+) STANDBY mode : All PWR domains enter DSTANDBY mode and the VCORE + supply regulator is powered off. + + *** SLEEP mode *** + ================== + [..] + (+) Entry: + The SLEEP mode is entered by using the HAL_PWR_EnterSLEEPMode(Regulator, + SLEEPEntry) function. + + (++) PWR_SLEEPENTRY_WFI : Enter SLEEP mode with WFI instruction. + (++) PWR_SLEEPENTRY_WFE : Enter SLEEP mode with WFE instruction and + clear of pending events before. + (++) PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR: Enter SLEEP mode with WFE instruction and + no clear of pending event before. + -@@- The Regulator parameter is not used for the STM32H7RS family + and is kept as parameter just to maintain compatibility with the + lower power families. (STM32L). + + (+) Exit: + Any peripheral interrupt acknowledged by the nested vectored interrupt + controller (NVIC) can wake up the device from SLEEP mode. + + *** STOP mode *** + ================= + [..] + In system STOP mode, the CPU clock is stopped. All CPU subsystem peripheral + clocks are stopped too. + The voltage regulator can be configured either in normal or low-power mode. + To minimize the consumption in STOP mode, FLASH can be powered off before + entering the STOP mode using the HAL_PWREx_EnableFlashPowerDown() function. + It can be switched on again by software after exiting the STOP mode using + the HAL_PWREx_DisableFlashPowerDown() function. + (+) Entry: + The STOP mode is entered using the HAL_PWR_EnterSTOPMode(Regulator, + STOPEntry) function with: + (++) Regulator: + (+++) PWR_MAINREGULATOR_ON: Main regulator ON. + This parameter is not used for the STM32H7RS family and is kept as parameter + just to maintain compatibility with the lower power families. + (++) STOPEntry: + (+++) PWR_STOPENTRY_WFI : Enter STOP mode with WFI instruction. + (+++) PWR_STOPENTRY_WFE : Enter STOP mode with WFE instruction and + clear of pending events before. + (+++) PWR_STOPENTRY_WFE_NO_EVT_CLEAR: Enter STOP mode with WFE instruction and + no clear of pending event before. + (+) Exit: + Any EXTI Line (Internal or External) configured in Interrupt/Event mode. + + *** STANDBY mode *** + ==================== + [..] + (+) + The system STANDBY mode allows to achieve the lowest power consumption. + It is based on the Cortex-M7 deep SLEEP mode, with the voltage regulator + disabled. The system is consequently powered off. The PLL, the HSI + oscillator and the HSE oscillator are also switched off. SRAM and register + contents are lost except for the RTC registers, RTC backup registers, + backup SRAM and standby circuitry. + + [..] + The voltage regulator is OFF. + + (++) Entry: + (+++) The STANDBY mode is entered using the HAL_PWR_EnterSTANDBYMode() + function. + + (++) Exit: + (+++) WKUP pin rising or falling edge, RTC alarm (Alarm A and Alarm B), + RTC wakeup, tamper event, time stamp event, external reset in NRST + pin, IWDG reset. + + *** Auto-wakeup (AWU) from low-power mode *** + ============================================= + [..] + (+) The MCU can be woken up from low-power mode by an RTC Alarm event, an + RTC Wakeup event, a tamper event or a time-stamp event, without + depending on an external interrupt (Auto-wakeup mode). + + (+) RTC auto-wakeup (AWU) from the STOP and STANDBY modes + + (++) To wake up from the STOP mode with an RTC alarm event, it is + necessary to configure the RTC to generate the RTC alarm using the + HAL_RTC_SetAlarm_IT() function. + + (++) To wake up from the STOP mode with an RTC Tamper or time stamp event, + it is necessary to configure the RTC to detect the tamper or time + stamp event using the HAL_RTCEx_SetTimeStamp_IT() or + HAL_RTCEx_SetTamper_IT() functions. + + (++) To wake up from the STOP mode with an RTC WakeUp event, it is + necessary to configure the RTC to generate the RTC WakeUp event + using the HAL_RTCEx_SetWakeUpTimer_IT() function. + +@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). + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection level. + * @note As PVD and AVD share the same EXTI line, the EXTI operating mode to + * configure will replace a possible previous configuration done through + * HAL_PWREx_ConfigAVD. + * @retval None. + */ +void HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD) +{ + /* Check the PVD configuration parameter */ + if (sConfigPVD == NULL) + { + return; + } + + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel)); + assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode)); + + /* Set PLS[7:5] bits according to PVDLevel value */ + MODIFY_REG(PWR->CR1, PWR_CR1_PLS, sConfigPVD->PVDLevel); + + /* Clear any previous config. Keep it clear if no event or IT mode is selected */ + __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(); + } + + /* Rising edge configuration */ + if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); + } + + /* Falling edge configuration */ + if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + } +} + +/** + * @brief Enable the programmable voltage detector (PVD). + * @retval None. + */ +void HAL_PWR_EnablePVD(void) +{ + SET_BIT(PWR->CR1, PWR_CR1_PVDE); +} + +/** + * @brief Disable the programmable voltage detector (PVD). + * @retval None. + */ +void HAL_PWR_DisablePVD(void) +{ + CLEAR_BIT(PWR->CR1, PWR_CR1_PVDE); +} + +/** + * @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. + * 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. + * @note PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent. + * @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->WKUPEPR, PWR_WKUPEPR_WKUPEN | PWR_WKUPEPR_WKUPP, 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_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. + * @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->WKUPEPR, (PWR_WKUPEPR_WKUPEN & WakeUpPinx)); +} + +/** + * @brief Enter the current core in SLEEP mode (CSLEEP). + * @param Regulator : NA in this family project + * Specifies the regulator state in SLEEP mode. + * @note This parameter is not used for the STM32H7RS family and is kept as + * parameter just to maintain compatibility with the lower power + * families. + * @param SLEEPEntry : Specifies if SLEEP mode is entered with WFI or WFE + * intrinsic instruction. + * This parameter can be one of the following values: + * @arg PWR_SLEEPENTRY_WFI : Enter SLEEP mode with WFI instruction. + * @arg PWR_SLEEPENTRY_WFE : Enter SLEEP mode with WFE instruction and + * clear of pending events before. + * @arg PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR : Enter SLEEP mode with WFE instruction and + * no clear of pending event before. + * @retval None. + */ +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Regulator); + + /* Check the parameters */ + assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); + + /* Select Sleep mode entry */ + if (SLEEPEntry == PWR_SLEEPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + if (SLEEPEntry != PWR_SLEEPENTRY_WFE_NO_EVT_CLEAR) + { + /* Clear all pending event */ + __SEV(); + __WFE(); + } + + /* Request Wait For Event */ + __WFE(); + } +} + +/** + * @brief Enter the whole system to Stop mode. + * @note This API will enter the system in STOP mode + * @param Regulator : This parameter is not used for this product family. + and is kept as parameter just to maintain compatibility with the + lower power families. + * @param STOPEntry : Specifies if STOP mode in entered with WFI or WFE + * intrinsic instruction. + * This parameter can be one of the following values: + * @arg PWR_STOPENTRY_WFI : Enter STOP mode with WFI instruction. + * @arg PWR_STOPENTRY_WFE : Enter STOP mode with WFE instruction and + * clear of pending events before. + * @arg PWR_STOPENTRY_WFE_NO_EVT_CLEAR : Enter STOP mode with WFE instruction and + * no clear of pending event before. + * @note In System STOP mode, all I/O pins keep the same state as in Run mode. + * @note When exiting System STOP mode by issuing an interrupt or a wakeup + * event, the HSI RC oscillator is selected as default system wakeup + * clock. + * @note In System STOP mode, when the voltage regulator operates in low + * power mode, an additional startup delay is incurred when the system + * is waking up. By keeping the internal regulator ON during STOP mode, + * the consumption is higher although the startup time is reduced. + * @retval None. + */ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) +{ + + /* Prevent unused argument(s) compilation warning */ + UNUSED(Regulator); + + /* Check the parameters */ + assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); + + /* Select Stop mode when device enters Deepsleep */ + CLEAR_BIT(PWR->CSR3, PWR_CSR3_PDDS); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); + + /* Ensure that all instructions are done before entering STOP mode */ + __DSB(); + __ISB(); + + /* Select Stop mode entry */ + if (STOPEntry == PWR_STOPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + if (STOPEntry != PWR_STOPENTRY_WFE_NO_EVT_CLEAR) + { + /* Clear all pending event */ + __SEV(); + __WFE(); + } + /* Request Wait For Event */ + __WFE(); + } + + /* Clear SLEEPDEEP bit of Cortex-M7 in the System Control Register */ + CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); +} + +/** + * @brief Enter the whole system to Standby mode. + * @note The Standby mode allows achieving the lowest power consumption. + * @note When the system enters in Standby mode, the voltage regulator is disabled. + * The complete VCORE domain is consequently powered off. + * The PLLs, HSI oscillator, CSI oscillator, HSI48 and the HSE oscillator are + * also switched off. + * SRAM and register contents are lost except for backup domain registers + * (RTC registers, RTC backup register and backup RAM), and Standby circuitry. + * @note When the System exit STANDBY mode by issuing an interrupt or a + * wakeup event, the HSI RC oscillator is selected as system clock. + * @retval None. + */ +void HAL_PWR_EnterSTANDBYMode(void) +{ + /* Select Standby when device enters Deepsleep */ + SET_BIT(PWR->CSR3, PWR_CSR3_PDDS); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, SCB_SCR_SLEEPDEEP_Msk); + + /* Ensure that all instructions are done before entering STANDBY mode */ + __DSB(); + __ISB(); + + /* Request Wait For Interrupt */ + __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-M7 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-M7 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-M7. + * @retval None. + */ +void HAL_PWR_EnableSEVOnPend(void) +{ + /* Set SEVONPEND bit of Cortex-M7 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-M7. + * @retval None. + */ +void HAL_PWR_DisableSEVOnPend(void) +{ + /* Clear SEVONPEND bit of Cortex-M7 System Control Register */ + CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk); +} +/** + * @} + */ + +/** + * @} + */ +#endif /* HAL_PWR_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c new file mode 100644 index 0000000..0036f4a --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c @@ -0,0 +1,1601 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 PWR extension peripheral: + * + Peripheral Extended features 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 + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Call HAL_PWREx_ConfigSupply() function to configure the regulator supply + with the following different setups according to hardware (support SMPS): + (+) PWR_DIRECT_SMPS_SUPPLY + (+) PWR_SMPS_1V8_SUPPLIES_LDO + (+) PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO + (+) PWR_SMPS_1V8_SUPPLIES_EXT + (+) PWR_LDO_SUPPLY + (+) PWR_EXTERNAL_SOURCE_SUPPLY + + (#) Call HAL_PWREx_GetSupplyConfig() function to get the current supply setup. + + (#) Call HAL_PWREx_ControlVoltageScaling() function to configure the main + internal regulator output voltage. The voltage scaling could be one of + the following scales : + (+) PWR_REGULATOR_VOLTAGE_SCALE0 + (+) PWR_REGULATOR_VOLTAGE_SCALE1 + + (#) Call HAL_PWREx_GetVoltageRange() function to get the current output + voltage applied to the main regulator. + + (#) Call HAL_PWREx_ControlStopModeVoltageScaling() function to configure the main + internal regulator output voltage in STOP mode. The voltage scaling could be one of + the following scales : + (+) PWR_REGULATOR_STOP_VOLTAGE_SCALE3 + (+) PWR_REGULATOR_STOP_VOLTAGE_SCALE5 + + (#) Call HAL_PWREx_GetStopModeVoltageRange() function to get the current output + voltage applied to the main regulator in STOP mode. + + (#) Call HAL_PWREx_EnableFlashPowerDown() and + HAL_PWREx_DisableFlashPowerDown() functions to enable and disable the + Flash Power Down in STOP mode. + + (#) Call HAL_PWREx_EnableWakeUpPin() and HAL_PWREx_DisableWakeUpPin() + functions to enable and disable the Wake-up pin functionality for + the selected pin. + + (#) Call HAL_PWREx_GetWakeupFlag() and HAL_PWREx_ClearWakeupFlag() + functions to manage wake-up flag for the selected pin. + + (#) Call HAL_PWREx_WAKEUP_PIN_IRQHandler() function to handle all wake-up + pins interrupts. + + (#) Call HAL_PWREx_EnableBkUpReg() and HAL_PWREx_DisableBkUpReg() functions + to enable and disable the backup domain regulator. + + (#) Call HAL_PWREx_EnableUSBReg(), HAL_PWREx_DisableUSBReg(), + HAL_PWREx_EnableUSBVoltageDetector() and + HAL_PWREx_DisableUSBVoltageDetector() functions to manage USB power + regulation functionalities. + + (#) Call HAL_PWREx_EnableUCPDStandbyMode() and HAL_PWREx_DisableUCPDStandbyMode() functions + to enable and disable UCPD Standby mode. + + (#) Call HAL_PWREx_EnableUCPDDeadBattery() and HAL_PWREx_DisableUCPDDeadBattery() functions + to enable and disable UCPD dead battery. + + (#) Call HAL_PWREx_EnableBatteryCharging() and + HAL_PWREx_DisableBatteryCharging() functions to enable and disable the + battery charging feature with the selected resistor. + + (#) Call HAL_PWREx_EnableAnalogBooster() and HAL_PWREx_DisableAnalogBooster() functions + to enable and disable the AVD boost feature when the VDD supply voltage is below 2V7. + + (#) Call HAL_PWREx_EnableXSPIM1() and HAL_PWREx_DisableXSPIM1() functions + to enable and disable the XSPIM1. + + (#) Call HAL_PWREx_EnableXSPIM2() and HAL_PWREx_DisableXSPIM2() functions + to enable and disable the XSPIM2. + + (#) Call HAL_PWREx_ConfigXSPIPortCap() functions to configure the XSPI capacitor port 1 and 2. + The capacitor setting could be one of the following values : + (+) PWR_CAPACITOR_OFF + (+) PWR_CAPACITOR_ONE_THIRD_CAPACITANCE + (+) PWR_CAPACITOR_TWO_THIRD_CAPACITANCE + (+) PWR_CAPACITOR_FULL_CAPACITANCE + + (#) Call HAL_PWREx_GetConfigXSPIPortCap() function to get the current + capacitor port setting. + + (#) Call HAL_PWREx_EnableMonitoring() and HAL_PWREx_DisableMonitoring() + functions to enable and disable the VBAT and Temperature monitoring. + When VBAT and Temperature monitoring feature is enables, use + HAL_PWREx_GetTemperatureLevel() and HAL_PWREx_GetVBATLevel() to get + respectively the Temperature level and VBAT level. + + (#) Call HAL_PWREx_ConfigAVD() after setting parameter to be configured + (event mode and voltage threshold) in order to set up the Analog Voltage + Detector then use HAL_PWREx_EnableAVD() and HAL_PWREx_DisableAVD() + functions to start and stop the AVD detection. + (+) AVD level could be one of the following values : + (++) 1V7 + (++) 2V1 + (++) 2V5 + (++) 2V8 + + (#) Call HAL_PWREx_PVD_AVD_IRQHandler() function to handle the PWR PVD and + AVD interrupt request. + + (#) Call HAL_PWREx_EnablePullUpPullDownConfig() and + HAL_PWREx_DisablePullUpPullDownConfig() to I/O enable / disable pull-up + and pull-down configuration. + + (#) Call HAL_PWREx_EnableGPIOPullUp() and HAL_PWREx_EnableGPIOPullDown() to + apply respectively pull-up and pull-down to selected I/O. + Call HAL_PWREx_DisableGPIOPullUp() and HAL_PWREx_DisableGPIOPullDown() to + disable applied respectively pull-up and pull-down to selected I/O. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup PWREx PWREx + * @brief PWR Extended HAL module driver + * @{ + */ + +#ifdef HAL_PWR_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @addtogroup PWREx_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) +/** + * @} + */ + +/** @defgroup PWREx_REG_SET_TIMEOUT PWR Extended Flag Setting Time Out Value + * @{ + */ +#define PWR_FLAG_SETTING_DELAY (1000U) +/** + * @} + */ + +/** @defgroup PWREx_WakeUp_Pins_Offsets PWREx Wake-Up Pins masks and offsets + * @{ + */ +/* Wake-Up Pins EXTI register mask */ +#define PWR_EXTI_WAKEUP_PINS_MASK (EXTI_IMR2_IM55 | EXTI_IMR2_IM56 |\ + EXTI_IMR2_IM57 | EXTI_IMR2_IM58 ) + +/* Wake-Up Pins PWR Pin Pull shift offsets */ +#define PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET (2U) +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @defgroup PWREx_Exported_Functions_Group1 Power Supply Control Functions + * @brief Power supply control functions + * +@verbatim + =============================================================================== + ##### Power supply control functions ##### + =============================================================================== + [..] + (#) When the system is powered on, the POR monitors VDD supply. Once VDD is + above the POR threshold level, the SMPS step-down converter and voltage + regulator are enabled in the default supply configuration: + + (+) The SMPS step-down converter output level is set at 1.35 V. + The voltage regulator LDO output level is set at 1.11 V. + Depending on the package and configuration the SMPS provides the + voltage to internal power domain and/or LDO or external supply. + + (+) The system is kept in reset mode as long as VCORE is not stable. + + (+) Once VCORE is stable, the system is taken out of reset and the HSI + oscillator is enabled. + + (+) Once the oscillator is stable, the system is initialized: Flash memory + is ready, option bytes are loaded and the CPU starts in limited run mode. + + (+) The software must then initialize the system including supply + configuration programming in PWR control register 2 (PWR_CSR2). + Once the supply configuration has been configured, the ACTVOSRDY bit in + the PWR control status register 1 (PWR_SR1) must be checked to guarantee + valid voltage levels: + a) As long as ACTVOSRDY indicates that voltage levels are invalid, the + system is in Run mode, write accesses to the RAMs are not permitted and + VOS must not be changed. + b) Once ACTVOSRDY indicates that voltage levels are valid, the system is + in normal Run mode, write accesses to RAMs are allowed and VOS can be + changed. + +@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_DIRECT_SMPS_SUPPLY : The SMPS supplies the Vcore Power + * Domains. The LDO is Bypassed. + * @arg PWR_SMPS_1V8_SUPPLIES_LDO : The SMPS 1.8V output supplies + * the LDO. The Vcore Power Domains + * are supplied from the LDO. + * @arg PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO : The SMPS 1.8V output + * supplies external + * circuits and the LDO. + * The Vcore Power Domains + * are supplied from the + * LDO. + * @arg PWR_SMPS_1V8_SUPPLIES_EXT : The SMPS 1.8V output supplies + * external circuits. The LDO is + * Bypassed. The Vcore Power + * Domains are supplied from + * external source. + * @arg PWR_LDO_SUPPLY : The LDO regulator supplies the Vcore Power + * Domains. The SMPS regulator is Bypassed. + * @arg PWR_EXTERNAL_SOURCE_SUPPLY : The SMPS is disabled and the LDO are + * Bypassed. The Vcore Power + * Domains are supplied from + * external source. + * @note The SMPS step-down converter is not available on all packages, + * and the Bypass mode is available only when the SMPS is available. + * @note The PWR_DIRECT_SMPS_SUPPLY, PWR_SMPS_1V8_SUPPLIES_LDO, + * PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO and PWR_SMPS_1V8_SUPPLIES_EXT are used + * only for lines that supports SMPS regulator. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_ConfigSupply(uint32_t SupplySource) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_PWR_SUPPLY(SupplySource)); + + /* Check if supply source was configured */ + if ((PWR->CSR2 & (PWR_CSR2_SDEN | PWR_CSR2_LDOEN | PWR_CSR2_BYPASS)) != (PWR_CSR2_SDEN | PWR_CSR2_LDOEN)) + { + /* Check supply configuration */ + if ((PWR->CSR2 & PWR_SUPPLY_CONFIG_MASK) != SupplySource) + { + /* Supply configuration update locked, can't apply a new supply config */ + return HAL_ERROR; + } + else + { + /* Supply configuration update locked, but new supply configuration + matches with old supply configuration : nothing to do + */ + return HAL_OK; + } + } + + /* Set the power supply configuration */ + MODIFY_REG(PWR->CSR2, PWR_SUPPLY_CONFIG_MASK, SupplySource); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till voltage level flag is set */ + while ((PWR->SR1 & PWR_SR1_ACTVOSRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + + /* When the SMPS supplies external circuits verify that SDEXTRDY flag is set */ + if ((SupplySource == PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO) || + (SupplySource == PWR_SMPS_1V8_SUPPLIES_EXT)) + { + /* Get the current tick number */ + tickstart = HAL_GetTick(); + + /* Wait till SMPS external supply ready flag is set */ + while ((PWR->CSR2 & PWR_CSR2_SDEXTRDY) == 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->CSR2 & 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 scaling range 0 (highest frequency). + * @arg PWR_REGULATOR_VOLTAGE_SCALE1 : Regulator voltage scaling range 1 (lowest power). + * @note When increasing the performance, the voltage scaling must be changed + * before increasing the system frequency. + * When decreasing performance, the system frequency must first be decreased + * before changing the voltage scaling. + * @note When exiting from Stop mode or Standby mode, the Run mode voltage + * scaling is reset to the default VOS low value. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR_VOLTAGE(VoltageScaling)); + + /* Set the voltage range */ + MODIFY_REG(PWR->CSR4, PWR_CSR4_VOS, VoltageScaling); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till voltage level flag is set */ + while ((PWR->CSR4 & PWR_CSR4_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->SR1 & PWR_SR1_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_STOP_VOLTAGE_SCALE3 : System Stop mode voltage scaling range 3 (highest frequency). + * @arg PWR_REGULATOR_STOP_VOLTAGE_SCALE5 : System Stop mode voltage scaling range 5 (lowest power). + * @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->CR1, PWR_CR1_SVOS, VoltageScaling); + + return HAL_OK; +} + +/** + * @brief Get the main internal regulator output voltage in STOP mode. + * @retval The actual applied SVOS selection. + */ +uint32_t HAL_PWREx_GetStopModeVoltageRange(void) +{ + /* Return the stop voltage scaling */ + return (PWR->CR1 & PWR_CR1_SVOS); +} +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group2 Low Power Control Functions + * @brief Low Power Control Functions + * +@verbatim + =============================================================================== + ##### Low Power Control Functions ##### + =============================================================================== + + *** FLASH Power Down configuration **** + ======================================= + [..] + By setting the FLPS bit in the PWR_CR1 register using the + HAL_PWREx_EnableFlashPowerDown() function, the Flash memory also enters + power down mode when the device enters STOP mode. When the Flash memory is + in power down mode, an additional startup delay is incurred when waking up + from STOP mode. + + *** Wakeup Pins configuration **** + =================================== + [..] + Wakeup pins allow the system to exit from Standby mode. The configuration + of wakeup pins is done with the HAL_PWREx_EnableWakeUpPin(sPinParams) + function with: + (+) sPinParams: structure to enable and configure a wakeup pin: + (++) WakeUpPin: Wakeup pin to be enabled. + (++) PinPolarity: Wakeup pin polarity (rising or falling edge). + (++) PinPull: Wakeup pin pull (no pull, pull-up or pull-down). + [..] + The wakeup pins are internally connected to the EXTI lines [55-58] to + generate an interrupt if enabled. The EXTI lines configuration is done by + the HAL_EXTI_Dx_EventInputConfig() functions defined in the stm32h7rsxxhal.c + file. + [..] + When a wakeup pin event is received the HAL_PWREx_WAKEUP_PIN_IRQHandler is + called and the appropriate flag is set in the PWR_WKUPFR register. Then in + the HAL_PWREx_WAKEUP_PIN_IRQHandler function the wakeup pin flag will be + cleared and the appropriate user callback will be called. The user can add + his own code by customization of function pointer HAL_PWREx_WKUPx_Callback. + +@endverbatim + * @{ + */ + +/** + * @brief Enable the Flash Power Down in Stop mode. + * @note When Flash Power Down is enabled the Flash memory enters low-power + * mode when device is in Stop 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->CR1, PWR_CR1_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 when device is in Stop 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->CR1, PWR_CR1_FLPS); +} + +/** + * @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_WKUPEPR_WKUPPUPD1; + + /* 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_WKUPEPR_WKUPP1_Pos) & 0x1FU)) | \ + (sPinParams->PinPull << (((POSITION_VAL(sPinParams->WakeUpPin) * PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET) + PWR_WKUPEPR_WKUPPUPD1_Pos) & 0x1FU)); + + regMask = sPinParams->WakeUpPin | \ + (PWR_WKUPEPR_WKUPP1 << (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->WKUPEPR, regMask, pinConfig); + + /* Configure the Wakeup Pin EXTI Line */ + MODIFY_REG(EXTI->IMR2, PWR_EXTI_WAKEUP_PINS_MASK, (sPinParams->WakeUpPin << EXTI_IMR2_IM55_Pos)); +} + +/** + * @brief Disable the Wake-up PINx functionality. + * @param WakeUpPin : Specifies the Wake-Up pin to be disabled. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_PIN1 : Disable PA0 wake-up PIN. + * @arg PWR_WAKEUP_PIN2 : Disable PA2 wake-up PIN. + * @arg PWR_WAKEUP_PIN3 : Disable PC13 wake-up PIN. + * @arg PWR_WAKEUP_PIN4 : Disable PC1 wake-up PIN. + * @retval None + */ +void HAL_PWREx_DisableWakeUpPin(uint32_t WakeUpPin) +{ + /* Check the parameter */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPin)); + + /* Disable the WakeUpPin */ + CLEAR_BIT(PWR->WKUPEPR, WakeUpPin); +} + +/** + * @brief Get the Wake-Up Pin pending flags. + * @param WakeUpFlag : Specifies the Wake-Up PIN flag to be checked. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_FLAG1 : Get wakeup event received from PA0. + * @arg PWR_WAKEUP_FLAG2 : Get wakeup event received from PA2. + * @arg PWR_WAKEUP_FLAG3 : Get wakeup event received from PC13. + * @arg PWR_WAKEUP_FLAG4 : Get wakeup event received from PC1. + * @arg PWR_WAKEUP_FLAG_ALL : Get Wakeup event received from all + * wake up pins. + * @retval The Wake-Up pin flag. + */ +uint32_t HAL_PWREx_GetWakeupFlag(uint32_t WakeUpFlag) +{ + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_FLAG(WakeUpFlag)); + + /* Return the wake up pin flag */ + return (PWR->WKUPFR & WakeUpFlag); +} + +/** + * @brief Clear the Wake-Up pin pending flag. + * @param WakeUpFlag: Specifies the Wake-Up PIN flag to clear. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_FLAG1 : Clear the wakeup event received from PA0. + * @arg PWR_WAKEUP_FLAG2 : Clear the wakeup event received from PA2. + * @arg PWR_WAKEUP_FLAG3 : Clear the wakeup event received from PC13. + * @arg PWR_WAKEUP_FLAG4 : Clear the wakeup event received from PC1. + * @arg PWR_WAKEUP_FLAG_ALL : Clear the wakeup events received from all + * wake up pins. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_ClearWakeupFlag(uint32_t WakeUpFlag) +{ + /* Check the parameter */ + assert_param(IS_PWR_WAKEUP_FLAG(WakeUpFlag)); + + /* Clear the wake up event received from wake up pin x */ + WRITE_REG(PWR->WKUPCR, WakeUpFlag); + + /* Check if the wake up event is well cleared */ + if ((PWR->WKUPFR & WakeUpFlag) != 0U) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief This function handles the PWR WAKEUP PIN interrupt request. + * @note This API should be called under the WAKEUP_PIN_IRQHandler(). + * @retval None. + */ +void HAL_PWREx_WAKEUP_PIN_IRQHandler(void) +{ + /* Wakeup pin EXTI line interrupt detected */ + if (READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF1) != 0U) + { + /* Clear PWR WKUPF1 flag */ + __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP1); + + /* PWR WKUP1 interrupt user callback */ + HAL_PWREx_WKUP1_Callback(); + } + + if (READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF2) != 0U) + { + /* Clear PWR WKUPF2 flag */ + __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP2); + + /* PWR WKUP2 interrupt user callback */ + HAL_PWREx_WKUP2_Callback(); + } + + if (READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF3) != 0U) + { + /* Clear PWR WKUPF3 flag */ + __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP3); + + /* PWR WKUP3 interrupt user callback */ + HAL_PWREx_WKUP3_Callback(); + } + + if (READ_BIT(PWR->WKUPFR, PWR_WKUPFR_WKUPF4) != 0U) + { + /* Clear PWR WKUPF4 flag */ + __HAL_PWR_CLEAR_WAKEUPFLAG(PWR_FLAG_WKUP4); + + /* PWR WKUP4 interrupt user callback */ + HAL_PWREx_WKUP4_Callback(); + } +} + +/** + * @brief PWR WKUP1 interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_WKUP1_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWREx_WKUP1Callback can be implemented in the user file + */ +} + +/** + * @brief PWR WKUP2 interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_WKUP2_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWREx_WKUP2Callback can be implemented in the user file + */ +} + +/** + * @brief PWR WKUP3 interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_WKUP3_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWREx_WKUP3Callback can be implemented in the user file + */ +} + +/** + * @brief PWR WKUP4 interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_WKUP4_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWREx_WKUP4Callback can be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group3 Peripherals Control Functions + * @brief Peripherals Control Functions + * +@verbatim + =============================================================================== + ##### Peripherals Control Functions ##### + =============================================================================== + + *** Main and Backup Regulators configuration *** + ================================================ + [..] + (+) The backup domain includes 4 Kbytes of backup SRAM accessible only + from the CPU, and addressed in 32-bit, 16-bit or 8-bit mode. Its + content is retained even in Standby or VBAT mode when the low power + backup regulator is enabled. It can be considered as an internal + EEPROM when VBAT is always present. You can use the + HAL_PWREx_EnableBkUpReg() function to enable the low power backup + regulator. + (+) When the backup domain is supplied by VDD (analog switch connected to + VDD) the backup SRAM is powered from VDD which replaces the VBAT power + supply to save battery life. + (+) The backup SRAM is not mass erased by a tamper event. It is read + protected to prevent confidential data, such as cryptographic private + key, from being accessed. The backup SRAM can be erased only through + the Flash interface when a protection level change from level 1 to + level 0 is requested. + -@- Refer to the description of Read protection (RDP) in the Flash + programming manual. + (+) The main internal regulator can be configured to have a tradeoff + between performance and power consumption when the device does not + operate at the maximum frequency. This is done through + HAL_PWREx_ControlVoltageScaling(VOS) function which configure the VOS + bit in PWR_CSR4 register. + (+) The main internal regulator can be configured to operate in Low Power + mode when the system enters STOP mode to further reduce power + consumption. + This is done through HAL_PWREx_ControlStopModeVoltageScaling(SVOS) + function which configure the SVOS bit in PWR_CR1 register. + -@- Refer to the product datasheets for more details. + + *** USB Regulator configuration *** + =================================== + [..] + (+) The USB transceivers are supplied from a dedicated VDD33USB supply + that can be provided either by the integrated USB regulator, or by an + external USB supply. + (+) The USB regulator is enabled by HAL_PWREx_EnableUSBReg() function, the + VDD33USB is then provided from the USB regulator. + (+) When the USB regulator is enabled, the VDD33USB supply level detector + shall be enabled through HAL_PWREx_EnableUSBVoltageDetector() + function. + (+) The USB regulator is disabled through HAL_PWREx_DisableUSBReg() + function and VDD33USB can be provided from an external supply. In this + case VDD33USB and VDD50USB shall be connected together. + + *** VBAT battery charging *** + ============================= + [..] + (+) When VDD is present, the external battery connected to VBAT can be + charged through an internal resistance. VBAT charging can be performed + either through a 5 KOhm resistor or through a 1.5 KOhm resistor. + (+) VBAT charging is enabled by HAL_PWREx_EnableBatteryCharging + (ResistorValue) function with: + (++) ResistorValue: + (+++) PWR_BATTERY_CHARGING_RESISTOR_5: 5 KOhm resistor. + (+++) PWR_BATTERY_CHARGING_RESISTOR_1_5: 1.5 KOhm resistor. + (+) VBAT charging is disabled by HAL_PWREx_DisableBatteryCharging() + function. + +@endverbatim + * @{ + */ + +/** + * @brief Enable the Backup Regulator. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_EnableBkUpReg(void) +{ + uint32_t tickstart; + + /* Enable the Backup regulator */ + SET_BIT(PWR->CSR1, PWR_CSR1_BREN); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till Backup regulator ready flag is set */ + while ((PWR->CSR1 & PWR_CSR1_BRRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Disable the Backup Regulator. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_DisableBkUpReg(void) +{ + uint32_t tickstart; + + /* Disable the Backup regulator */ + CLEAR_BIT(PWR->CSR1, PWR_CSR1_BREN); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till Backup regulator ready flag is reset */ + while ((PWR->CSR1 & PWR_CSR1_BRRDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Enable the USB Regulator. + * @retval None. + */ +void HAL_PWREx_EnableUSBReg(void) +{ + /* Enable the USB regulator */ + SET_BIT(PWR->CSR2, PWR_CSR2_USBREGEN); +} + +/** + * @brief Disable the USB Regulator. + * @retval None. + */ +void HAL_PWREx_DisableUSBReg(void) +{ + /* Disable the USB regulator */ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_USBREGEN); +} + +/** + * @brief Enable the USB voltage level detector. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_EnableUSBVoltageDetector(void) +{ + uint32_t tickstart; + + /* Enable the USB voltage detector */ + SET_BIT(PWR->CSR2, PWR_CSR2_USB33DEN); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till the USB regulator ready flag is set */ + while ((PWR->CSR2 & PWR_CSR2_USB33RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + return HAL_OK; +} + +/** + * @brief Disable the USB voltage level detector. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_DisableUSBVoltageDetector(void) +{ + uint32_t tickstart; + + /* Disable the USB voltage detector */ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_USB33DEN); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till the USB regulator ready flag is reset */ + while ((PWR->CSR2 & PWR_CSR2_USB33RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Enable the USB HS regulator. + * @retval None. + */ +void HAL_PWREx_EnableUSBHSregulator(void) +{ + /* Enable the USB HS regulator */ + SET_BIT(PWR->CSR2, PWR_CSR2_USBHSREGEN); +} + +/** + * @brief Disable the USB HS regulator. + * @retval None. + */ +void HAL_PWREx_DisableUSBHSregulator(void) +{ + /* Disable the USB HS regulator */ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_USBHSREGEN); +} + +/** + * @brief Enable UCPD configuration memorization in Standby. + * @retval None + * @note This function must be called just before entering Standby mode when using UCPD. + */ +void HAL_PWREx_EnableUCPDStandbyMode(void) +{ + /* Memorize UCPD configuration when entering standby mode */ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} + +/** + * @brief Disable UCPD configuration memorization in Standby. + * @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); +} + +/** + * @brief Enable dead battery behavior. + * @retval None + */ +void HAL_PWREx_EnableUCPDDeadBattery(void) +{ + /* Enable dead battery behavior */ + CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS); +} + +/** + * @brief Disable dead battery behavior. + * @retval None + */ +void HAL_PWREx_DisableUCPDDeadBattery(void) +{ + /* Disable dead battery behavior */ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS); +} + +/** + * @brief Enable the Battery charging. + * @note When VDD is present, charge the external battery through an internal + * resistor. + * It is automatically disabled in VBAT mode. + * @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 and enable the Battery charging */ + MODIFY_REG(PWR->CSR2, (PWR_CSR2_VBRS | PWR_CSR2_VBE), (ResistorValue | PWR_CSR2_VBE)); + +} + +/** + * @brief Disable the Battery charging. + * @retval None. + */ +void HAL_PWREx_DisableBatteryCharging(void) +{ + /* Disable the Battery charging and restore default charging resistor value */ + CLEAR_BIT(PWR->CSR2, (PWR_CSR2_VBE | PWR_CSR2_VBRS)); +} + +/** + * @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->CR1, PWR_CR1_AVDREADY); + + /* Enable VDDA booster */ + SET_BIT(PWR->CR1, PWR_CR1_BOOSTE); +} + +/** + * @brief Disable the analog booster. + * @retval None. + */ +void HAL_PWREx_DisableAnalogBooster(void) +{ + /* Disable VDDA booster */ + CLEAR_BIT(PWR->CR1, PWR_CR1_BOOSTE); + + /* Disable the Analog voltage */ + CLEAR_BIT(PWR->CR1, PWR_CR1_AVDREADY); +} + +/** + * @brief Enable the XSPIM_P1 interface. + * @note The XSPIM_P1 supply must be stable prior to setting + this bit. + * @retval None. + */ +void HAL_PWREx_EnableXSPIM1(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM1); +} + +/** + * @brief Disable the XSPIM_P1 interface. + * @retval None. + */ +void HAL_PWREx_DisableXSPIM1(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM1); +} + +/** + * @brief Enable the XSPIM_P2 interface. + * @note The XSPIM_P2 supply must be stable prior to setting + this bit. + * @retval None. + */ +void HAL_PWREx_EnableXSPIM2(void) +{ + SET_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM2); +} + +/** + * @brief Disable the XSPIM_P2 interface. + * @retval None. + */ +void HAL_PWREx_DisableXSPIM2(void) +{ + CLEAR_BIT(PWR->CSR2, PWR_CSR2_EN_XSPIM2); +} + +/** + * @brief Configure the capacitor port + * @param PortCapacitor Select the Port + * This parameter can be one of the following values: + * @arg @ref PWR_CAPACITOR_PORT1 XSPI port 1 capacitor + * @arg @ref PWR_CAPACITOR_PORT2 XSPI port 2 capacitor + * @param PortCapacitorSetting Select the capacitor setting + * This parameter can be one of the following values: + * @arg @ref PWR_CAPACITOR_OFF XSPI Capacitor OFF + * @arg @ref PWR_CAPACITOR_ONE_THIRD_CAPACITANCE XSPI Capacitor set to 1/3 + * @arg @ref PWR_CAPACITOR_TWO_THIRD_CAPACITANCE XSPI Capacitor set to 2/3 + * @arg @ref PWR_CAPACITOR_FULL_CAPACITANCE XSPI Capacitor set to full capacitance + * @retval None. + */ +void HAL_PWREx_ConfigXSPIPortCap(uint32_t PortCapacitor, uint32_t PortCapacitorSetting) +{ + /* Check the parameters */ + assert_param(IS_PWR_CAPACITOR(PortCapacitor)); + assert_param(IS_PWR_CAPACITOR_SETTING(PortCapacitorSetting)); + + if (PortCapacitor == PWR_CAPACITOR_PORT1) + { + /* Set Port1 Capacitor setting */ + MODIFY_REG(PWR->CSR2, PWR_CSR2_XSPICAP1, PortCapacitorSetting); + } + else + { + /* Set Port2 Capacitor setting */ + MODIFY_REG(PWR->CSR2, PWR_CSR2_XSPICAP2, PortCapacitorSetting << (PWR_CSR2_XSPICAP2_Pos - PWR_CSR2_XSPICAP1_Pos)); + } +} + +/** + * @brief Get the capacitor port setting + * @param PortCapacitor Select the Port + * This parameter can be one of the following values: + * @arg @ref PWR_CAPACITOR_PORT1 XSPI port 1 capacitor + * @arg @ref PWR_CAPACITOR_PORT2 XSPI port 2 capacitor + * @retval The capacitor setting: + * @arg @ref PWR_CAPACITOR_OFF XSPI Capacitor OFF + * @arg @ref PWR_CAPACITOR_ONE_THIRD_CAPACITANCE XSPI Capacitor set to 1/3 + * @arg @ref PWR_CAPACITOR_TWO_THIRD_CAPACITANCE XSPI Capacitor set to 2/3 + * @arg @ref PWR_CAPACITOR_FULL_CAPACITANCE XSPI Capacitor set to full capacitance + */ +uint32_t HAL_PWREx_GetConfigXSPIPortCap(uint32_t PortCapacitor) +{ + uint32_t PortCapacitorSetting; + + /* Check the parameter */ + assert_param(IS_PWR_CAPACITOR(PortCapacitor)); + + if (PortCapacitor == PWR_CAPACITOR_PORT1) + { + /* Get Port1 Capacitor setting */ + PortCapacitorSetting = READ_BIT(PWR->CSR2, PWR_CSR2_XSPICAP1); + } + else + { + /* Get Port2 Capacitor setting */ + PortCapacitorSetting = (READ_BIT(PWR->CSR2, PWR_CSR2_XSPICAP2) >> (PWR_CSR2_XSPICAP2_Pos - PWR_CSR2_XSPICAP1_Pos)); + } + + return PortCapacitorSetting; +} + +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group4 Power Monitoring functions + * @brief Power Monitoring functions + * +@verbatim + =============================================================================== + ##### Power Monitoring functions ##### + =============================================================================== + + *** VBAT and Temperature supervision *** + ======================================== + [..] + (+) The VBAT battery voltage supply can be monitored by comparing it with + two threshold levels: VBAThigh and VBATlow. VBATH flag and VBATL flags + in the PWR control register 2 (PWR_CR2), indicate if VBAT is higher or + lower than the threshold. + (+) The temperature can be monitored by comparing it with two threshold + levels, TEMPhigh and TEMPlow. TEMPH and TEMPL flags, in the PWR + control register 2 (PWR_CR2), indicate whether the device temperature + is higher or lower than the threshold. + (+) The VBAT and the temperature monitoring is enabled by + HAL_PWREx_EnableMonitoring() function and disabled by + HAL_PWREx_DisableMonitoring() function. + (+) The HAL_PWREx_GetVBATLevel() function returns the VBAT level which can + be : PWR_VBAT_BELOW_LOW_THRESHOLD or PWR_VBAT_ABOVE_HIGH_THRESHOLD or + PWR_VBAT_BETWEEN_HIGH_LOW_THRESHOLD. + (+) The HAL_PWREx_GetTemperatureLevel() function returns the Temperature + level which can be : + PWR_TEMP_BELOW_LOW_THRESHOLD or PWR_TEMP_ABOVE_HIGH_THRESHOLD or + PWR_TEMP_BETWEEN_HIGH_LOW_THRESHOLD. + + *** AVD configuration *** + ========================= + [..] + (+) The AVD is used to monitor the VDDA power supply by comparing it to a + threshold selected by the AVD Level (ALS[3:0] bits in the PWR_CR1 + register). + (+) A AVDO flag is available to indicate if VDDA is higher or lower + than the AVD threshold. This event is internally connected to the EXTI + line 16 to generate an interrupt if enabled. + It is configurable through __HAL_PWR_AVD_EXTI_ENABLE_IT() macro. + (+) The AVD is stopped in System Standby mode. + +@endverbatim + * @{ + */ + +/** + * @brief Enable the VBAT and temperature monitoring. + * @retval HAL status. + */ +void HAL_PWREx_EnableMonitoring(void) +{ + /* Enable the VBAT and Temperature monitoring */ + SET_BIT(PWR->CSR1, PWR_CSR1_MONEN); +} + +/** + * @brief Disable the VBAT and temperature monitoring. + * @retval HAL status. + */ +void HAL_PWREx_DisableMonitoring(void) +{ + /* Disable the VBAT and Temperature monitoring */ + CLEAR_BIT(PWR->CSR1, PWR_CSR1_MONEN); +} + +/** + * @brief Indicate whether the junction temperature is between, above or below + * the thresholds. + * @retval Temperature level. + */ +uint32_t HAL_PWREx_GetTemperatureLevel(void) +{ + uint32_t tempLevel; + uint32_t regValue; + + /* Read the temperature flags */ + regValue = READ_BIT(PWR->CSR1, (PWR_CSR1_TEMPH | PWR_CSR1_TEMPL)); + + /* Check if the temperature is below the threshold */ + if (regValue == PWR_CSR1_TEMPL) + { + tempLevel = PWR_TEMP_BELOW_LOW_THRESHOLD; + } + /* Check if the temperature is above the threshold */ + else if (regValue == PWR_CSR1_TEMPH) + { + tempLevel = PWR_TEMP_ABOVE_HIGH_THRESHOLD; + } + /* The temperature is between the thresholds */ + else + { + tempLevel = PWR_TEMP_BETWEEN_HIGH_LOW_THRESHOLD; + } + + return tempLevel; +} + +/** + * @brief Indicate whether the Battery voltage level is between, above or below + * the thresholds. + * @retval VBAT level. + */ +uint32_t HAL_PWREx_GetVBATLevel(void) +{ + uint32_t vbatLevel; + uint32_t regValue; + + /* Read the VBAT flags */ + regValue = READ_BIT(PWR->CSR1, (PWR_CSR1_VBATH | PWR_CSR1_VBATL)); + + /* Check if the VBAT is below the threshold */ + if (regValue == PWR_CSR1_VBATL) + { + vbatLevel = PWR_VBAT_BELOW_LOW_THRESHOLD; + } + /* Check if the VBAT is above the threshold */ + else if (regValue == PWR_CSR1_VBATH) + { + vbatLevel = PWR_VBAT_ABOVE_HIGH_THRESHOLD; + } + /* The VBAT is between the thresholds */ + else + { + vbatLevel = PWR_VBAT_BETWEEN_HIGH_LOW_THRESHOLD; + } + + return vbatLevel; +} + +/** + * @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. + * @note As PVD and AVD share the same EXTI line, the EXTI operating mode to + * configure will replace a possible previous configuration done through + * HAL_PWR_ConfigPVD. + * @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[18:17] bits according to AVDLevel value */ + MODIFY_REG(PWR->CR1, PWR_CR1_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->CR1, PWR_CR1_AVDEN); +} + +/** + * @brief Disable the Analog Voltage Detector(AVD). + * @retval None. + */ +void HAL_PWREx_DisableAVD(void) +{ + /* Disable the Analog Voltage Detector */ + CLEAR_BIT(PWR->CR1, PWR_CR1_AVDEN); +} + +/** + * @brief This function handles the PWR PVD/AVD interrupt request. + * @note This API should be called under the PVD_AVD_IRQHandler(). + * @retval None + */ +void HAL_PWREx_PVD_AVD_IRQHandler(void) +{ + /* Check PWR EXTI flags for PVD/AVD */ + if (((EXTI->PR1) & EXTI_PR1_PR16) != 0U) + { + /* Clear PVD/AVD exti pending bit */ + WRITE_REG(EXTI->PR1, EXTI_PR1_PR16); + + /* PWR PVD/AVD interrupt user callback */ + HAL_PWREx_PVD_AVD_Callback(); + } +} + +/** + * @brief PWR PVD/AVD interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_PVD_AVD_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWREx_PVD_AVD_Callback can be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group5 I/O Pull-Up Pull-Down Configuration Functions + * @brief I/O pull-up / pull-down configuration functions + * +@verbatim + =============================================================================== + ##### Voltage monitoring Functions ##### + =============================================================================== + [..] + In Standby mode, pull up and pull down can be configured to + maintain an I/O in the selected state. If the APC bit in the PWR_APCR + register is set, the I/Os can be configured either with a pull-up through + PWR_PUCRx registers (x=N,O), or with a pull-down through + PWR_PDCRx registers (x=N,O,P), or can be kept in analog state + if none of the PWR_PUCRx or PWR_PDCRx register is set. + + [..] + The pull-down configuration has highest priority over pull-up + configuration in case both PWR_PUCRx and PWR_PDCRx are set for the same + I/O. + +@endverbatim + * @{ + */ + +/** + * @brief Enable pull-up and pull-down configuration. + * @note When APC bit is set, the I/O pull-up and pull-down configurations + * defined in PWR_PUCRx and PWR_PDCRx registers are applied in Standby + * mode. + * @note Pull-up set by PUy bit of PWR_PUCRx register is not activated if the + * corresponding PDy bit of PWR_PDCRx register is also set (pull-down + * configuration priority is higher). HAL_PWREx_EnableGPIOPullUp() and + * HAL_PWREx_EnableGPIOPullDown() API's ensure there is no conflict + * when setting PUy or PDy bit. + * @retval None. + */ +void HAL_PWREx_EnablePullUpPullDownConfig(void) +{ + SET_BIT(PWR->APCR, PWR_APCR_APC); +} + +/** + * @brief Disable pull-up and pull-down configuration. + * @note When APC bit is cleared, the I/O pull-up and pull-down configurations + * defined in PWR_PUCRx and PWR_PDCRx registers are not applied in + * Standby mode. + * @retval None. + */ +void HAL_PWREx_DisablePullUpPullDownConfig(void) +{ + CLEAR_BIT(PWR->APCR, PWR_APCR_APC); +} + +/** + * @brief Enable GPIO pull-up state in Standby mode. + * @note Set the relevant PUy bits of PWR_PUCRx register to configure the I/O in + * pull-up state in Standby mode. + * @note This state is effective in Standby mode only if APC bit + * is set through HAL_PWREx_EnablePullUpPullDownConfig() API. + * @note The configuration is maintained when exiting the Standby mode. + * @note Even if a PUy bit to set is reserved, the other PUy bits entered as + * input parameter at the same time are set. + * @note The pullup is not activated if the corresponding PDy bit is also set. + * @param GPIO_Port : Specify the IO port. + * This parameter can be a value of @ref PWREx_GPIO_PullUp_Port. + * @param GPIO_Pin : Specify the I/O pins numbers. + * This parameter can be a combination of @ref PWREx_GPIO_PullUp_Pin_Mask. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullUp(uint32_t GPIO_Port, uint32_t GPIO_Pin) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_PWR_GPIO_PULLPUP_PORT(GPIO_Port)); + assert_param(IS_PWR_GPIO_PIN_MASK(GPIO_Pin)); + + switch (GPIO_Port) + { + case PWR_GPIO_PULLUP_PORT_N: + SET_BIT(PWR->PUCRN, GPIO_Pin); + break; + + case PWR_GPIO_PULLUP_PORT_O: + SET_BIT(PWR->PUCRO, GPIO_Pin); + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Disable GPIO pull-up state in Standby mode. + * @note Reset the relevant PUy bits of PWR_PUCRx register used to configure the I/O + * in pull-up state in Standby mode. + * @note Even if a PUy bit to reset is reserved, the other PUy bits entered as input + * parameter at the same time are reset. + * @param GPIO_Port : Specify the IO port. + * This parameter can be a value of @ref PWREx_GPIO_PullUp_Port. + * @param GPIO_Pin : Specify the I/O pins numbers. + * This parameter can be a combination of @ref PWREx_GPIO_PullUp_Pin_Mask. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullUp(uint32_t GPIO_Port, uint32_t GPIO_Pin) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_PWR_GPIO_PULLPUP_PORT(GPIO_Port)); + assert_param(IS_PWR_GPIO_PIN_MASK(GPIO_Pin)); + + switch (GPIO_Port) + { + case PWR_GPIO_PULLUP_PORT_N: + CLEAR_BIT(PWR->PUCRN, GPIO_Pin); + break; + + case PWR_GPIO_PULLUP_PORT_O: + CLEAR_BIT(PWR->PUCRO, GPIO_Pin); + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Enable GPIO pull-down state in Standby mode. + * @note Set the relevant PDy bits of PWR_PDCRx register to configure the I/O in + * pull-down state in Standby mode. + * @note This state is effective in Standby mode only if APC bit + * is set through HAL_PWREx_EnablePullUpPullDownConfig() API. + * @note The configuration is maintained when exiting the Standby mode. + * @note Even if a PDy bit to set is reserved, the other PDy bits entered as input + * parameter at the same time are set. + * @param GPIO_Port : Specify the IO port. + * This parameter can be a value of @ref PWREx_GPIO_PullDown_Port. + * @param GPIO_Pin : Specify the I/O pins numbers. + * This parameter can be a combination of @ref PWREx_GPIO_PullDown_Pin_Mask. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_EnableGPIOPullDown(uint32_t GPIO_Port, uint32_t GPIO_Pin) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_PWR_GPIO_PULLDOWN_PORT(GPIO_Port)); + assert_param(IS_PWR_GPIO_PIN_MASK(GPIO_Pin)); + + switch (GPIO_Port) + { + case PWR_GPIO_PULLDOWN_PORT_N: + SET_BIT(PWR->PDCRN, GPIO_Pin); + break; + + case PWR_GPIO_PULLDOWN_PORT_O: + SET_BIT(PWR->PDCRO, GPIO_Pin); + break; + + case PWR_GPIO_PULLDOWN_PORT_P: + SET_BIT(PWR->PDCRP, GPIO_Pin); + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Disable GPIO pull-down state in Standby mode. + * @note Reset the relevant PDy bits of PWR_PDCRx register used to configure the I/O + * in pull-down state in Standby mode. + * @note Even if a PDy bit to reset is reserved, the other PDy bits entered as input + * parameter at the same time are reset. + * @param GPIO_Port : Specify the IO port. + * This parameter can be a value of @ref PWREx_GPIO_PullDown_Port. + * @param GPIO_Pin : Specify the I/O pins numbers. + * This parameter can be a value of @ref PWREx_GPIO_PullDown_Pin_Mask. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_DisableGPIOPullDown(uint32_t GPIO_Port, uint32_t GPIO_Pin) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_PWR_GPIO_PULLDOWN_PORT(GPIO_Port)); + assert_param(IS_PWR_GPIO_PIN_MASK(GPIO_Pin)); + + switch (GPIO_Port) + { + case PWR_GPIO_PULLDOWN_PORT_N: + CLEAR_BIT(PWR->PDCRN, GPIO_Pin); + break; + + case PWR_GPIO_PULLDOWN_PORT_O: + CLEAR_BIT(PWR->PDCRO, GPIO_Pin); + break; + + case PWR_GPIO_PULLDOWN_PORT_P: + CLEAR_BIT(PWR->PDCRP, GPIO_Pin); + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_PWR_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c new file mode 100644 index 0000000..6af6d0e --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c @@ -0,0 +1,2332 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### RCC specific features ##### + ============================================================================== + [..] + After reset the device is running from Internal High Speed oscillator + (HSI 64MHz) with Flash 0 wait state,and all peripherals are off except + internal SRAM, Flash, JTAG and PWR + (+) There is no pre-scaler on High speed (AHB) and Low speed (APB) buses; + all peripherals mapped on these buses are running at HSI speed. + (+) The clock for all peripherals is switched off, except the SRAM and FLASH. + (+) All GPIOs are in analogue 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 buses pre-scalers + (+) Enable the clock for the peripheral(s) to be used + (+) Configure the clock kernel source(s) for peripherals which clocks are not + derived from the System clock. + + ##### 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. + (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle + after the clock enable bit is set on the hardware register + (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle + after the clock enable bit is set on the hardware register + + [..] + Implemented Workaround: + (+) For AHB & APB peripherals, a dummy read to the peripheral register has been + inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup RCC RCC + * @brief RCC HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ +#define RCC_CSI_TIMEOUT_VALUE 1U /* 1 ms */ +#define RCC_HSI_TIMEOUT_VALUE 1U /* 1 ms */ +#define RCC_HSI48_TIMEOUT_VALUE 1U /* 1 ms */ +#define RCC_HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT +#define RCC_LSI_TIMEOUT_VALUE 1U /* 1 ms */ +#define RCC_CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */ +#define RCC_PLL_FRAC_WAIT_VALUE 1U /* PLL Fractional part waiting time before new latch enable : 1 ms */ +#define RCC_PLL_INPUTRANGE0_FREQMAX 2000000U /* 2 MHz is maximum frequency for VCO input range 0 */ +#define RCC_PLL_INPUTRANGE1_FREQMAX 4000000U /* 4 MHz is maximum frequency for VCO input range 1 */ +#define RCC_PLL_INPUTRANGE2_FREQMAX 8000000U /* 8 MHz is maximum frequency for VCO input range 2 */ + +#define RCC_PLL1_CONFIG 0U +#define RCC_PLL2_CONFIG 1U +#define RCC_PLL3_CONFIG 2U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RCC_Private_Macros RCC Private Macros + * @{ + */ +#define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__) ((__RCC_MCOx__) & GPIO_PIN_MASK) + +#define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS) + +#define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS) + +#define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__) (GPIOA_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__)))) + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Variables Private Variables + * @{ + */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup RCC_Private_Functions RCC Private Functions + * @{ + */ +static uint32_t RCC_PLL1_GetVCOOutputFreq(void); +static uint32_t RCC_PLL2_GetVCOOutputFreq(void); +static uint32_t RCC_PLL3_GetVCOOutputFreq(void); +static HAL_StatusTypeDef RCC_PLL_Config(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit); +/** + * @} + */ + +/* 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/external oscillators + (HSE, HSI, LSE,CSI, LSI,HSI48, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB3, AHB1 + AHB2,AHB4,APB3, APB1L, APB1H, APB2, and APB4). + + [..] 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 as RTC clock source. + + (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + + (#) PLL , The RCC features three independent PLLs (clocked by HSI , HSE or CSI), + featuring three different output clocks and able to work either in integer or Fractional mode. + (++) A main PLL, PLL1, which is generally used to provide clocks to the CPU + and to some peripherals. + (++) Two dedicated PLLs, PLL2 and PLL3, which are used to generate the kernel clock for peripherals. + + + (#) CSS (Clock security system), once enabled and if a HSE clock failure occurs + (HSE used directly or through PLL 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-M NMI (Non-Mask-able Interrupt) + exception vector. + + (#) MCO1 (micro controller clock output), used to output HSI, LSE, HSE, PLL1(PLL1_Q) + or HSI48 clock (through a configurable pre-scaler) on PA8 pin. + + (#) MCO2 (micro controller clock output), 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 buses clocks configuration + (#) Several clock sources can be used to drive the System clock (SYSCLK): CSI,HSI, + HSE and PLL. + The AHB clock (HCLK) is derived from System core clock through configurable + pre-scaler and used to clock the CPU, memory and peripherals mapped + on AHB and APB bus through configurable pre-scalers + and used to clock the peripherals mapped on these buses. You can use + "HAL_RCC_GetSysClockFreq()" function to retrieve system clock frequency. + +@endverbatim + * @{ + */ + +/** + * @brief Resets 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, PLL1, PLL2 and PLL3 OFF + * - AHB, APB Bus pre-scaler set to 1. + * - CSS, MCO1 and MCO2 OFF + * - All interrupts disabled + * @note This function doesn't modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @note In case the FMC or XSPI clock protection have been set, it must be disabled + * prior to calling this API. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_DeInit(void) +{ + uint32_t tickstart; + + /* 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 HSITRIM[6:0] bits to the reset value */ + SET_BIT(RCC->HSICFGR, RCC_HSICFGR_HSITRIM_6); + + if (HAL_RCC_GetHCLKFreq() > HSI_VALUE) + { + /* Reset CFGR register (HSI is selected as system clock source) */ + CLEAR_REG(RCC->CFGR); + + /* Update the SystemCoreClock global variables */ + SystemCoreClock = HSI_VALUE; + + /* Adapt Systick interrupt period */ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till clock switch is ready */ + while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reduce flash latency */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1); + } + else + { + /* Increase flash latency */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1); + + /* Reset CFGR register (HSI is selected as system clock source) */ + CLEAR_REG(RCC->CFGR); + + /* Adapt Systick interrupt period */ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till clock switch is ready */ + while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Reset CSION, CSIKERON, HSEON, HSI48ON, HSECSSON, HSIDIV bits */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSIKERON | RCC_CR_HSIDIV | RCC_CR_CSION | RCC_CR_CSIKERON \ + | RCC_CR_HSI48ON | RCC_CR_HSECSSON); + + /* 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; + } + } + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Clear PLLON bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON); + + /* Wait till PLL 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 PLL2ON 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; + } + } + + /* 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; + } + } + + /* Reset CDCFGR register */ + CLEAR_REG(RCC->CDCFGR); + + /* Reset BMCFGR register */ + CLEAR_REG(RCC->BMCFGR); + + /* Reset APBCFGR register */ + CLEAR_REG(RCC->APBCFGR); + + /* Reset PLLCKSELR register to default value */ + WRITE_REG(RCC->PLLCKSELR, 0x02020200U); + + /* Reset PLLCFGR register */ + CLEAR_REG(RCC->PLLCFGR); + + /* Reset PLL1DIVR1 register to default value */ + WRITE_REG(RCC->PLL1DIVR1, 0x01010280U); + + /* Reset PLL1DIVR2 register to default value */ + WRITE_REG(RCC->PLL1DIVR2, 0x00000101U); + + /* Reset PLL1FRACR register */ + CLEAR_REG(RCC->PLL1FRACR); + + /* Reset PLL2DIVR1 register to default value */ + WRITE_REG(RCC->PLL2DIVR1, 0x01010280U); + + /* Reset PLL2DIVR2 register to default value */ + WRITE_REG(RCC->PLL2DIVR2, 0x00000101U); + + /* Reset PLL2FRACR register */ + CLEAR_REG(RCC->PLL2FRACR); + + /* Reset PLL3DIVR1 register to default value */ + WRITE_REG(RCC->PLL3DIVR1, 0x01010280U); + + /* Reset PLL3DIVR2 register to default value */ + WRITE_REG(RCC->PLL3DIVR2, 0x00000101U); + + /* Reset PLL3FRACR register */ + CLEAR_REG(RCC->PLL3FRACR); + + /* 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); + + return HAL_OK; +} + +/** + * @brief Initializes the RCC Oscillators according to the specified parameters in the + * RCC_OscInitTypeDef. + * @param RCC_OscInitStruct: 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 function. 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 function. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + uint32_t tickstart; + uint32_t sysclksrc; + uint32_t pllsrc; + uint32_t pllrdy; + uint32_t tmpreg1; + + /* Check Null pointer */ + if (RCC_OscInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + + sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + pllsrc = __HAL_RCC_GET_PLL_OSCSOURCE(); + pllrdy = RCC->CR & (RCC_CR_PLL1RDY | RCC_CR_PLL2RDY | RCC_CR_PLL3RDY); + + /*------------------------------- HSE Configuration ------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */ + if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) || + ((pllrdy != 0U) && (pllsrc == RCC_PLLSOURCE_HSE))) + { + if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF) + { + return HAL_ERROR; + } + } + else + { + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Check the HSE State */ + if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + { + /* 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 + { + /* 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 (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_HSICALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL1 source when PLL1 is selected as system clock */ + if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) || + ((pllrdy != 0U) && (pllsrc == RCC_PLLSOURCE_HSI))) + { + /* When HSI is used as system clock it will not be disabled */ + if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF) + { + return HAL_ERROR; + } + /* Otherwise, calibration is allowed, divider update also unless used for any enabled PLL */ + else + { + /* HSI must not be used as reference clock for any enabled PLL clock source */ + tmpreg1 = (RCC->CR & RCC_CR_HSIDIV); + if ((pllsrc == RCC_PLLSOURCE_HSI) && (pllrdy != 0U) && \ + (tmpreg1 != RCC_OscInitStruct->HSIDiv)) + { + return HAL_ERROR; + } + + assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv)); + + /* Set the Internal High Speed oscillator new divider */ + __HAL_RCC_HSI_CONFIG(RCC_HSI_ON | RCC_OscInitStruct->HSIDiv); + + if (sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) + { + SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos))); + } + /* Adapt Systick interrupt period */ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + } + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + else + { + /* Check the HSI State */ + if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + { + /* Enable the Internal High Speed oscillator */ + __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIState | RCC_OscInitStruct->HSIDiv); + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + + /* 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; + } + } + } + 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; + } + } + } + } + } + /*----------------------------- CSI Configuration --------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_CSI) == RCC_OSCILLATORTYPE_CSI) + { + /* Check the parameters */ + assert_param(IS_RCC_CSI(RCC_OscInitStruct->CSIState)); + + /* When the CSI is used as system clock it will not disabled */ + if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_CSI) || + ((pllrdy != 0U) && (pllsrc == RCC_PLLSOURCE_CSI))) + { + /* When CSI is used as system clock it will not disabled */ + if (RCC_OscInitStruct->CSIState == RCC_CSI_OFF) + { + return HAL_ERROR; + } + } + else + { + /* Check the CSI State */ + if ((RCC_OscInitStruct->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; + } + } + } + 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; + } + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if ((RCC_OscInitStruct->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->CSR, RCC_CSR_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 ready */ + while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + + /*------------------------------ HSI48 Configuration -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); + + /* Check the HSI48 State */ + if ((RCC_OscInitStruct->HSI48State) != RCC_HSI48_OFF) + { + /* Enable the Internal Low Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + + /* Get time-out */ + 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 Low Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + + /* Get time-out */ + 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; + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + { + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Enable write access to Backup domain */ + PWR->CR1 |= PWR_CR1_DBP; + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + /* Check the LSE State */ + if ((RCC_OscInitStruct->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; + } + } + } + } + + /*-------------------------------- PLL1 Configuration ----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL1.PLLState)); + + if (RCC_OscInitStruct->PLL1.PLLState != RCC_PLL_NONE) + { + /* Check if the PLL is used as system clock or not */ + if (sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + /* No PLL off possible */ + if (RCC_OscInitStruct->PLL1.PLLState == RCC_PLL_OFF) + { + return HAL_ERROR; + } + else + { + /* Check if only fractional part needs to be updated */ + tmpreg1 = ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> RCC_PLL1FRACR_FRACN_Pos); + + if (RCC_OscInitStruct->PLL1.PLLFractional != tmpreg1) + { + assert_param(IS_RCC_PLLFRACN_VALUE(RCC_OscInitStruct->PLL1.PLLFractional)); + + /* Disable PLL1FRACLE */ + __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) + { + /* Do nothing */ + } + + /* Configure PLL1FRACN */ + __HAL_RCC_PLL1_FRACN_CONFIG(RCC_OscInitStruct->PLL1.PLLFractional); + + /* Enable PLL1FRACLE to latch new value . */ + __HAL_RCC_PLL1_FRACN_ENABLE(); + } + } + } + else + { + /* Initialize PLL1T to 1 to use common PLL initialization function */ + RCC_OscInitStruct->PLL1.PLLT = 1U; + if (RCC_PLL_Config(RCC_PLL1_CONFIG, &(RCC_OscInitStruct->PLL1)) != HAL_OK) + { + return HAL_ERROR; + } + } + } + + /*-------------------------------- PLL2 Configuration ----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL2.PLLState)); + + if (RCC_OscInitStruct->PLL2.PLLState != RCC_PLL_NONE) + { + if (RCC_PLL_Config(RCC_PLL2_CONFIG, &(RCC_OscInitStruct->PLL2)) != HAL_OK) + { + return HAL_ERROR; + } + } + + /*-------------------------------- PLL3 Configuration ----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL3.PLLState)); + + if (RCC_OscInitStruct->PLL3.PLLState != RCC_PLL_NONE) + { + /* Initialize PLL3T to 1 to use common PLL initialization function */ + RCC_OscInitStruct->PLL3.PLLT = 1U; + if (RCC_PLL_Config(RCC_PLL3_CONFIG, &(RCC_OscInitStruct->PLL3)) != HAL_OK) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Initializes the CPU, AHB and APB buses clocks according to the specified + * parameters in the RCC_ClkInitStruct. + * @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC peripheral. + * @param FLatency: FLASH Latency, this parameter depend on device selected + * + * @note The SystemCoreClock CMSIS variable is used to store System Core Clock Frequency + * and updated by HAL_InitTick() function called within this function + * + * @note The HSI is used (enabled by hardware) as system clock source after + * start-up from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE 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 start-up delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * You can use HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * (for more details refer to section above "Initialization/de-initialization functions") + * @retval None + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) +{ + HAL_StatusTypeDef halstatus; + uint32_t tickstart; + + /* Check Null pointer */ + if (RCC_ClkInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->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 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 ? */ + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + assert_param(IS_RCC_PCLK1(RCC_ClkInitStruct->APB1CLKDivider)); + if ((RCC_ClkInitStruct->APB1CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE1)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE1, (RCC_ClkInitStruct->APB1CLKDivider)); + } + } + + /*-------------------------- PCLK2 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + { + assert_param(IS_RCC_PCLK2(RCC_ClkInitStruct->APB2CLKDivider)); + if ((RCC_ClkInitStruct->APB2CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE2)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE2, (RCC_ClkInitStruct->APB2CLKDivider)); + } + } + + /*-------------------------- PCLK4 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK4) == RCC_CLOCKTYPE_PCLK4) + { + assert_param(IS_RCC_PCLK4(RCC_ClkInitStruct->APB4CLKDivider)); + if ((RCC_ClkInitStruct->APB4CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE4)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE4, (RCC_ClkInitStruct->APB4CLKDivider)); + } + } + + /*-------------------------- PCLK5 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK5) == RCC_CLOCKTYPE_PCLK5) + { + assert_param(IS_RCC_PCLK5(RCC_ClkInitStruct->APB5CLKDivider)); + if ((RCC_ClkInitStruct->APB5CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE5)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE5, (RCC_ClkInitStruct->APB5CLKDivider)); + } + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + if ((RCC_ClkInitStruct->AHBCLKDivider) > (RCC->BMCFGR & RCC_BMCFGR_BMPRE)) + { + /* Set the new HCLK clock divider */ + MODIFY_REG(RCC->BMCFGR, RCC_BMCFGR_BMPRE, RCC_ClkInitStruct->AHBCLKDivider); + } + } + + /*------------------------- SYSCLK Configuration -------------------------*/ + if ((RCC_ClkInitStruct->ClockType & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + assert_param(IS_RCC_SYSCLK(RCC_ClkInitStruct->SYSCLKDivider)); + MODIFY_REG(RCC->CDCFGR, RCC_CDCFGR_CPRE, RCC_ClkInitStruct->SYSCLKDivider); + + /* HSE is selected as System Clock Source */ + if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + /* Check the HSE ready flag */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + { + return HAL_ERROR; + } + } + /* PLL is selected as System Clock Source */ + else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + /* Check the PLL ready flag */ + if (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U) + { + return HAL_ERROR; + } + } + /* CSI is selected as System Clock Source */ + else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI) + { + /* Check the PLL 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->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Decreasing the BUS frequency divider ? */ + + /*-------------------------- HCLK Configuration --------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + if ((RCC_ClkInitStruct->AHBCLKDivider) < (RCC->BMCFGR & RCC_BMCFGR_BMPRE)) + { + /* Set the new HCLK clock divider */ + MODIFY_REG(RCC->BMCFGR, RCC_BMCFGR_BMPRE, RCC_ClkInitStruct->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 (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + assert_param(IS_RCC_PCLK1(RCC_ClkInitStruct->APB1CLKDivider)); + if ((RCC_ClkInitStruct->APB1CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE1)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE1, (RCC_ClkInitStruct->APB1CLKDivider)); + } + } + + /*-------------------------- PCLK2 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + { + assert_param(IS_RCC_PCLK2(RCC_ClkInitStruct->APB2CLKDivider)); + if ((RCC_ClkInitStruct->APB2CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE2)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE2, (RCC_ClkInitStruct->APB2CLKDivider)); + } + } + + /*-------------------------- PCLK4 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK4) == RCC_CLOCKTYPE_PCLK4) + { + assert_param(IS_RCC_PCLK4(RCC_ClkInitStruct->APB4CLKDivider)); + if ((RCC_ClkInitStruct->APB4CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE4)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE4, (RCC_ClkInitStruct->APB4CLKDivider)); + } + } + + /*-------------------------- PCLK5 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK5) == RCC_CLOCKTYPE_PCLK5) + { + assert_param(IS_RCC_PCLK5(RCC_ClkInitStruct->APB5CLKDivider)); + if ((RCC_ClkInitStruct->APB5CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE5)) + { + MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE5, (RCC_ClkInitStruct->APB5CLKDivider)); + } + } + + /* Update the SystemCoreClock global variable with the System CPU clock */ + SystemCoreClock = HAL_RCC_GetSysClockFreq(); + + /* Configure the source of time base considering new system clocks settings*/ + halstatus = HAL_InitTick(uwTickPrio); + + return halstatus; +} + +/** + * @} + */ + +/** @defgroup RCC_Group2 Peripheral Control functions + * @brief RCC clocks control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + +@endverbatim + * @{ + */ + +/** + * @brief Selects 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. + * This parameter can be one of the following values: + * @arg RCC_MCO1_PA8 Clock source to output on MCO1 pin(PA8). + * @arg RCC_MCO2_PC9 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_PLL1Q: 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_PLL1P 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 MCOx pre-scaler. + * 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) +{ +#if defined(HAL_GPIO_MODULE_ENABLED) + GPIO_InitTypeDef GPIO_InitStruct; + uint32_t mcoindex; + uint32_t mco_gpio_index; + GPIO_TypeDef *mco_gpio_port; + + /* Check the parameters */ + assert_param(IS_RCC_MCO(RCC_MCOx)); + + /* Common GPIO init parameters */ + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + + /* Get MCOx selection */ + mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK; + + /* Get MCOx GPIO Port */ + mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx); + + /* MCOx Clock Enable */ + mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx); + SET_BIT(RCC->AHB4ENR, (1UL << mco_gpio_index)); + + /* Configure the MCOx pin in alternate function mode */ + GPIO_InitStruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx); + GPIO_InitStruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx); + HAL_GPIO_Init(mco_gpio_port, &GPIO_InitStruct); + + if (mcoindex == RCC_MCO1_INDEX) + { + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); + /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1SEL | RCC_CFGR_MCO1PRE), (RCC_MCOSource | RCC_MCODiv)); + } + else if (mcoindex == RCC_MCO2_INDEX) + { + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource)); + /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2SEL | RCC_CFGR_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 7))); + } + else + { + /* Do nothing */ + } + +#endif /* HAL_GPIO_MODULE_ENABLED */ +} + +/** + * @brief Enables the 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-Mask-able Interrupt) exception vector. + * @retval None + */ +void HAL_RCC_EnableCSS(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSECSSON); +} + +/** + * @brief Disables the Clock Security System. + * @retval None + */ +void HAL_RCC_DisableCSS(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSECSSON); +} + +/** + * @brief Returns the SYSCLK frequency + * + * @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: + * @note If SYSCLK source is CSI, function returns values based on CSI_VALUE(*) + * @note If SYSCLK source is HSI, function returns values based on HSI_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 CSI_VALUE(*), + * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors. + * @note (*) CSI_VALUE is a constant defined in stm32h7rsxx_hal_conf.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) HSI_VALUE is a constant defined in stm32h7rsxx_hal_conf.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (***) HSE_VALUE is a constant defined in stm32h7rsxx_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 + * baud rate 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 pllp; + uint32_t pllsource; + uint32_t pllm; + uint32_t pllfracen; + uint32_t hsivalue; + float_t fracn1; + float_t pllvco; + uint32_t sysclockfreq; + uint32_t prescaler; + + /* Get SYSCLK source -------------------------------------------------------*/ + + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ + + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + sysclockfreq = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + sysclockfreq = 0U; + } + + break; + + case RCC_SYSCLKSOURCE_STATUS_CSI: /* CSI used as system clock source */ + sysclockfreq = CSI_VALUE; + break; + + case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock source */ + sysclockfreq = HSE_VALUE; + break; + + case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL1 used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC); + pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ; + pllfracen = ((RCC-> PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) >> RCC_PLLCFGR_PLL1FRACEN_Pos); + fracn1 = (float_t)(uint32_t)(pllfracen * ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> 3)); + + if (pllm != 0U) + { + switch (pllsource) + { + case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ + + if (READ_BIT(RCC->CR, RCC_CR_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->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1); + } + else + { + /* Can't retrieve HSIDIV value */ + pllvco = (float_t)0; + } + break; + + case RCC_PLLSOURCE_CSI: /* CSI used as PLL clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1); + break; + + case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1); + break; + + default: + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1); + break; + } + pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U) ; + sysclockfreq = (uint32_t)(float_t)(pllvco / (float_t)pllp); + } + else + { + sysclockfreq = 0U; + } + break; + + default: + sysclockfreq = CSI_VALUE; + break; + } + + prescaler = RCC->CDCFGR & RCC_CDCFGR_CPRE; + if (prescaler >= 8U) + { + sysclockfreq = sysclockfreq >> (prescaler - RCC_CDCFGR_CPRE_3 + 1U); + } + + return sysclockfreq; +} + + +/** + * @brief Return the HCLK frequency. + * @retval HCLK frequency in Hz + */ +uint32_t HAL_RCC_GetHCLKFreq(void) +{ + uint32_t clock; + uint32_t prescaler; + const uint8_t AHBPrescTable[8] = {1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + + /* SysClk */ + clock = HAL_RCC_GetSysClockFreq(); + /* Bus matrix divider */ + prescaler = (RCC->BMCFGR & RCC_BMCFGR_BMPRE) >> RCC_BMCFGR_BMPRE_Pos; + if (prescaler >= 8U) + { + clock = clock >> AHBPrescTable[prescaler - 8U]; + } + return (clock); +} + +/** + * @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) +{ + uint32_t clock; + uint32_t prescaler; + /* Get HCLK source and compute PCLK1 frequency ---------------------------*/ + clock = HAL_RCC_GetHCLKFreq(); + /* APB1 prescaler */ + prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE1) >> RCC_APBCFGR_PPRE1_Pos; + if (prescaler >= 4U) + { + clock = clock >> (prescaler - 3U); + } + return (clock); +} + +/** + * @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) +{ + uint32_t clock; + uint32_t prescaler; + /* Get HCLK source and compute PCLK2 frequency ---------------------------*/ + clock = HAL_RCC_GetHCLKFreq(); + /* APB2 prescaler */ + prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE2) >> RCC_APBCFGR_PPRE2_Pos; + if (prescaler >= 4U) + { + clock = clock >> (prescaler - 3U); + } + return (clock); +} + +/** + * @brief Return the PCLK4 frequency. + * @note Each time PCLK4 changes, this function must be called to update the + * right PCLK4 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK4 frequency in Hz + */ +uint32_t HAL_RCC_GetPCLK4Freq(void) +{ + uint32_t clock; + uint32_t prescaler; + /* Get HCLK source and compute PCLK4 frequency ---------------------------*/ + clock = HAL_RCC_GetHCLKFreq(); + /* APB4 prescaler */ + prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE4) >> RCC_APBCFGR_PPRE4_Pos; + if (prescaler >= 4U) + { + clock = clock >> (prescaler - 3U); + } + return (clock); +} + +/** + * @brief Return the PCLK5 frequency. + * @note Each time PCLK5 changes, this function must be called to update the + * right PCLK5 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK5 frequency in Hz + */ +uint32_t HAL_RCC_GetPCLK5Freq(void) +{ + uint32_t clock; + uint32_t prescaler; + /* Get HCLK source and compute PCLK5 frequency ---------------------------*/ + clock = HAL_RCC_GetHCLKFreq(); + /* APB5 prescaler */ + prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE5) >> RCC_APBCFGR_PPRE5_Pos; + if (prescaler >= 4U) + { + clock = clock >> (prescaler - 3U); + } + return (clock); +} + +/** + * @brief Return the PLL1P frequency. + * @retval PLL1P frequency in Hz + */ +uint32_t HAL_RCC_GetPLL1PFreq(void) +{ + uint32_t pllp; + + /* PLL1P divider */ + pllp = ((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U; + + /* Compute VCO output frequency and return PLL1P one */ + return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllp); +} + +/** + * @brief Return the PLL1Q frequency. + * @retval PLL1Q frequency in Hz + */ +uint32_t HAL_RCC_GetPLL1QFreq(void) +{ + uint32_t pllq; + + /* PLL1Q divider */ + pllq = ((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVQ) >> RCC_PLL1DIVR1_DIVQ_Pos) + 1U; + + /* Compute VCO output frequency and return PLL1Q one */ + return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllq); +} + +/** + * @brief Return the PLL1R frequency. + * @retval PLL1R frequency in Hz + */ +uint32_t HAL_RCC_GetPLL1RFreq(void) +{ + uint32_t pllr; + + /* PLL1R divider */ + pllr = ((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVR) >> RCC_PLL1DIVR1_DIVR_Pos) + 1U; + + /* Compute VCO output frequency and return PLL1R one */ + return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllr); +} + +/** + * @brief Return the PLL1S frequency. + * @retval PLL1S frequency in Hz + */ +uint32_t HAL_RCC_GetPLL1SFreq(void) +{ + uint32_t plls; + + /* PLL1S divider */ + plls = ((RCC->PLL1DIVR2 & RCC_PLL1DIVR2_DIVS) >> RCC_PLL1DIVR2_DIVS_Pos) + 1U; + + /* Compute VCO output frequency and return PLL1S one */ + return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / plls); +} + +/** + * @brief Return the PLL2P frequency. + * @retval PLL2P frequency in Hz + */ +uint32_t HAL_RCC_GetPLL2PFreq(void) +{ + uint32_t pllp; + + /* PLL2P divider */ + pllp = ((RCC->PLL2DIVR1 & RCC_PLL2DIVR1_DIVP) >> RCC_PLL2DIVR1_DIVP_Pos) + 1U; + + /* Compute VCO output frequency and return PLL2P one */ + return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllp); +} + +/** + * @brief Return the PLL2Q frequency. + * @retval PLL2Q frequency in Hz + */ +uint32_t HAL_RCC_GetPLL2QFreq(void) +{ + uint32_t pllq; + + /* PLL2Q divider */ + pllq = ((RCC->PLL2DIVR1 & RCC_PLL2DIVR1_DIVQ) >> RCC_PLL2DIVR1_DIVQ_Pos) + 1U; + + /* Compute VCO output frequency and return PLL2Q one */ + return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllq); +} + +/** + * @brief Return the PLL2R frequency. + * @retval PLL2R frequency in Hz + */ +uint32_t HAL_RCC_GetPLL2RFreq(void) +{ + uint32_t pllr; + + /* PLL2R divider */ + pllr = ((RCC->PLL2DIVR1 & RCC_PLL2DIVR1_DIVR) >> RCC_PLL2DIVR1_DIVR_Pos) + 1U; + + /* Compute VCO output frequency and return PLL2R one */ + return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllr); +} + +/** + * @brief Return the PLL2S frequency. + * @retval PLL2S frequency in Hz + */ +uint32_t HAL_RCC_GetPLL2SFreq(void) +{ + uint32_t plls; + + /* PLL2S divider */ + plls = ((RCC->PLL2DIVR2 & RCC_PLL2DIVR2_DIVS) >> RCC_PLL2DIVR2_DIVS_Pos) + 1U; + + /* Compute VCO output frequency and return PLL2R one */ + return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / plls); +} + +/** + * @brief Return the PLL2T frequency. + * @retval PLL2T frequency in Hz + */ +uint32_t HAL_RCC_GetPLL2TFreq(void) +{ + uint32_t pllt; + + /* PLL2T divider */ + pllt = ((RCC->PLL2DIVR2 & RCC_PLL2DIVR2_DIVT) >> RCC_PLL2DIVR2_DIVT_Pos) + 1U; + + /* Compute VCO output frequency and return PLL2T one */ + return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllt); +} + +/** + * @brief Return the PLL3P frequency. + * @retval PLL3P frequency in Hz + */ +uint32_t HAL_RCC_GetPLL3PFreq(void) +{ + uint32_t pllp; + + /* PLL3P divider */ + pllp = ((RCC->PLL3DIVR1 & RCC_PLL3DIVR1_DIVP) >> RCC_PLL3DIVR1_DIVP_Pos) + 1U; + + /* Compute VCO output frequency and return PLL3P one */ + return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / pllp); +} + +/** + * @brief Return the PLL3Q frequency. + * @retval PLL3Q frequency in Hz + */ +uint32_t HAL_RCC_GetPLL3QFreq(void) +{ + uint32_t pllq; + + /* PLL3Q divider */ + pllq = ((RCC->PLL3DIVR1 & RCC_PLL3DIVR1_DIVQ) >> RCC_PLL3DIVR1_DIVQ_Pos) + 1U; + + /* Compute VCO output frequency and return PLL3Q one */ + return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / pllq); +} + +/** + * @brief Return the PLL3R frequency. + * @retval PLL3R frequency in Hz + */ +uint32_t HAL_RCC_GetPLL3RFreq(void) +{ + uint32_t pllr; + + /* PLL3R divider */ + pllr = ((RCC->PLL3DIVR1 & RCC_PLL3DIVR1_DIVR) >> RCC_PLL3DIVR1_DIVR_Pos) + 1U; + + /* Compute VCO output frequency and return PLL3R one */ + return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / pllr); +} + +/** + * @brief Return the PLL3S frequency. + * @retval PLL3S frequency in Hz + */ +uint32_t HAL_RCC_GetPLL3SFreq(void) +{ + uint32_t plls; + + /* PLL3S divider */ + plls = ((RCC->PLL3DIVR2 & RCC_PLL3DIVR2_DIVS) >> RCC_PLL3DIVR2_DIVS_Pos) + 1U; + + /* Compute VCO output frequency and return PLL3S one */ + return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / plls); +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + + uint32_t regvalue; + uint32_t mask; + + /* Check the parameters */ + assert_param(RCC_OscInitStruct != (void *)NULL); + + /* Set all possible values for the Oscillator type parameter ---------------*/ + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_CSI | \ + RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48; + + /* Get Backup Domain register */ + regvalue = RCC->BDCR; + + /* Get the LSE configuration -----------------------------------------------*/ + mask = (RCC_BDCR_LSEBYP | RCC_BDCR_LSEEXT | RCC_BDCR_LSEON); + RCC_OscInitStruct->LSEState = (regvalue & mask); + + /* Get RCC clock control and status register */ + regvalue = RCC->CSR; + + /* Get the LSI configuration -----------------------------------------------*/ + mask = RCC_CSR_LSION; + RCC_OscInitStruct->LSIState = (regvalue & mask); + + /* Get Control register */ + regvalue = RCC->CR; + + /* Get the HSE configuration -----------------------------------------------*/ + mask = (RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSEON); + RCC_OscInitStruct->HSEState = (regvalue & mask); + + /* Get the HSI configuration -----------------------------------------------*/ + mask = RCC_CR_HSION; + RCC_OscInitStruct->HSIState = (regvalue & mask); + RCC_OscInitStruct->HSIDiv = (regvalue & RCC_CR_HSIDIV); + RCC_OscInitStruct->HSICalibrationValue = ((RCC->HSICFGR & RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos); + + /* Get the HSI48 configuration ---------------------------------------------*/ + mask = RCC_CR_HSI48ON; + RCC_OscInitStruct->HSI48State = (regvalue & mask); + + /* Get the CSI configuration -----------------------------------------------*/ + mask = RCC_CR_CSION; + RCC_OscInitStruct->CSIState = (regvalue & mask); + + /* Get the PLL1 configuration -----------------------------------------------*/ + if ((regvalue & RCC_CR_PLL1ON) == RCC_CR_PLL1ON) + { + RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_OFF; + } + + /* Get PLL1 configuration register */ + regvalue = RCC->PLLCKSELR; + RCC_OscInitStruct->PLL1.PLLSource = (regvalue & RCC_PLLCKSELR_PLLSRC); + RCC_OscInitStruct->PLL1.PLLM = ((regvalue & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos); + + /* Check if fractional part is enable */ + regvalue = RCC->PLLCFGR; + if ((regvalue & RCC_PLLCFGR_PLL1FRACEN) != 0x00u) + { + regvalue = (((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> RCC_PLL1FRACR_FRACN_Pos)); + } + else + { + regvalue = 0; + } + RCC_OscInitStruct->PLL1.PLLFractional = regvalue; + + /* Get PLL1 dividers register */ + regvalue = RCC->PLL1DIVR1; + RCC_OscInitStruct->PLL1.PLLN = ((regvalue & RCC_PLL1DIVR1_DIVN) + 1U); + RCC_OscInitStruct->PLL1.PLLR = (((regvalue & RCC_PLL1DIVR1_DIVR) >> RCC_PLL1DIVR1_DIVR_Pos) + 1U); + RCC_OscInitStruct->PLL1.PLLP = (((regvalue & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U); + RCC_OscInitStruct->PLL1.PLLQ = (((regvalue & RCC_PLL1DIVR1_DIVQ) >> RCC_PLL1DIVR1_DIVQ_Pos) + 1U); + regvalue = RCC->PLL1DIVR2; + RCC_OscInitStruct->PLL1.PLLS = (((regvalue & RCC_PLL1DIVR2_DIVS) >> RCC_PLL1DIVR2_DIVS_Pos) + 1U); + RCC_OscInitStruct->PLL1.PLLT = 0; + + /* Get the PLL2 configuration -----------------------------------------------*/ + /* Get Control register */ + regvalue = RCC->CR; + if ((regvalue & RCC_CR_PLL2ON) == RCC_CR_PLL2ON) + { + RCC_OscInitStruct->PLL2.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL2.PLLState = RCC_PLL_OFF; + } + + /* Get PLL2 configuration register */ + regvalue = RCC->PLLCKSELR; + RCC_OscInitStruct->PLL2.PLLSource = (regvalue & RCC_PLLCKSELR_PLLSRC); + RCC_OscInitStruct->PLL2.PLLM = ((regvalue & RCC_PLLCKSELR_DIVM2) >> RCC_PLLCKSELR_DIVM2_Pos); + + /* Check if fractional part is enable */ + regvalue = RCC->PLLCFGR; + if ((regvalue & RCC_PLLCFGR_PLL2FRACEN) != 0x00u) + { + regvalue = (((RCC->PLL2FRACR & RCC_PLL2FRACR_FRACN) >> RCC_PLL2FRACR_FRACN_Pos)); + } + else + { + regvalue = 0; + } + RCC_OscInitStruct->PLL2.PLLFractional = regvalue; + + /* Get PLL2 dividers register */ + regvalue = RCC->PLL2DIVR1; + RCC_OscInitStruct->PLL2.PLLN = ((regvalue & RCC_PLL2DIVR1_DIVN) + 1U); + RCC_OscInitStruct->PLL2.PLLR = (((regvalue & RCC_PLL2DIVR1_DIVR) >> RCC_PLL2DIVR1_DIVR_Pos) + 1U); + RCC_OscInitStruct->PLL2.PLLP = (((regvalue & RCC_PLL2DIVR1_DIVP) >> RCC_PLL2DIVR1_DIVP_Pos) + 1U); + RCC_OscInitStruct->PLL2.PLLQ = (((regvalue & RCC_PLL2DIVR1_DIVQ) >> RCC_PLL2DIVR1_DIVQ_Pos) + 1U); + regvalue = RCC->PLL2DIVR2; + RCC_OscInitStruct->PLL2.PLLS = (((regvalue & RCC_PLL2DIVR2_DIVS) >> RCC_PLL2DIVR2_DIVS_Pos) + 1U); + RCC_OscInitStruct->PLL2.PLLT = (((regvalue & RCC_PLL2DIVR2_DIVT) >> RCC_PLL2DIVR2_DIVT_Pos) + 1U); + + /* Get the PLL3 configuration -----------------------------------------------*/ + /* Get Control register */ + regvalue = RCC->CR; + if ((regvalue & RCC_CR_PLL3ON) == RCC_CR_PLL3ON) + { + RCC_OscInitStruct->PLL3.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL3.PLLState = RCC_PLL_OFF; + } + + /* Get PLL3 configuration register */ + regvalue = RCC->PLLCKSELR; + RCC_OscInitStruct->PLL3.PLLSource = (regvalue & RCC_PLLCKSELR_PLLSRC); + RCC_OscInitStruct->PLL3.PLLM = ((regvalue & RCC_PLLCKSELR_DIVM3) >> RCC_PLLCKSELR_DIVM3_Pos); + + + /* Check if fractional part is enable */ + regvalue = RCC->PLLCFGR; + if ((regvalue & RCC_PLLCFGR_PLL3FRACEN) != 0x00u) + { + regvalue = (((RCC->PLL3FRACR & RCC_PLL3FRACR_FRACN) >> RCC_PLL3FRACR_FRACN_Pos)); + } + else + { + regvalue = 0; + } + RCC_OscInitStruct->PLL3.PLLFractional = regvalue; + + /* Get PLL3 dividers register */ + regvalue = RCC->PLL3DIVR1; + RCC_OscInitStruct->PLL3.PLLN = ((regvalue & RCC_PLL3DIVR1_DIVN) + 1U); + RCC_OscInitStruct->PLL3.PLLR = (((regvalue & RCC_PLL3DIVR1_DIVR) >> RCC_PLL3DIVR1_DIVR_Pos) + 1U); + RCC_OscInitStruct->PLL3.PLLP = (((regvalue & RCC_PLL3DIVR1_DIVP) >> RCC_PLL3DIVR1_DIVP_Pos) + 1U); + RCC_OscInitStruct->PLL3.PLLQ = (((regvalue & RCC_PLL3DIVR1_DIVQ) >> RCC_PLL3DIVR1_DIVQ_Pos) + 1U); + regvalue = RCC->PLL3DIVR2; + RCC_OscInitStruct->PLL3.PLLS = (((regvalue & RCC_PLL3DIVR2_DIVS) >> RCC_PLL3DIVR2_DIVS_Pos) + 1U); + RCC_OscInitStruct->PLL3.PLLT = 0; + +} + +/** + * @brief Configures the RCC_ClkInitStruct according to the internal + * RCC configuration registers. + * @param RCC_ClkInitStruct: 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 *RCC_ClkInitStruct, uint32_t *pFLatency) +{ + /* Set all possible values for the Clock type parameter --------------------*/ + RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \ + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \ + RCC_CLOCKTYPE_PCLK4 | RCC_CLOCKTYPE_PCLK5; + + /* Get the SYSCLK source ---------------------------------------------------*/ + RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW); + + /* Get the SYSCLK configuration---------------------------------------------*/ + RCC_ClkInitStruct->SYSCLKDivider = READ_BIT(RCC->CDCFGR, RCC_CDCFGR_CPRE); + + /* Get the HCLK configuration ----------------------------------------------*/ + RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->BMCFGR, RCC_BMCFGR_BMPRE); + + /* Get the APB1 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE1); + + /* Get the APB2 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB2CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE2); + + /* Get the APB4 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB4CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE4); + + /* Get the APB5 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB5CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE5); + + /* Get the Flash Wait State (Latency) configuration ------------------------*/ + *pFLatency = __HAL_FLASH_GET_LATENCY(); +} + +/** + * @brief This function handles the RCC HSE CSS interrupt request. + * @note This API should be called under the NMI_Handler(). + * @retval None + */ +void HAL_RCC_NMI_IRQHandler(void) +{ + /* Check RCC HSECSSF interrupt flag */ + if (__HAL_RCC_GET_IT(RCC_IT_HSECSS)) + { + /* Clear RCC HSE CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS); + + /* RCC HSE Clock Security System interrupt user callback */ + HAL_RCC_HSECSSCallback(); + } +} + +/** + * @brief RCC HSE Clock Security System interrupt callback + * @retval none + */ +__weak void HAL_RCC_HSECSSCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RCC_HSECSSCallback could be implemented in the user file + */ +} + +/** + * @brief RCC LSE Clock Security System interrupt callback + * @retval none + */ +__weak void HAL_RCC_LSECSSCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RCC_LSECSSCallback could be implemented in the user file + */ +} + +/** + * @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; +} + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup RCC_Private_Functions + * @{ + */ + +/** + * @brief Configure the requested PLL + * @param PLLnumber PLL number to configure + * @param pPLLInit Pointer to an RCC_PLLInitTypeDef structure that + * contains the configuration parameters. + * @note PLL is temporary disabled to apply new parameters + * + * @retval HAL status + */ +static HAL_StatusTypeDef RCC_PLL_Config(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit) +{ + __IO uint32_t *p_rcc_pll_divr1_reg; + __IO uint32_t *p_rcc_pll_divr2_reg; + __IO uint32_t *p_rcc_pll_fracr_reg; + HAL_StatusTypeDef ret = HAL_OK; + uint32_t tickstart; + uint32_t pllsrc; + uint32_t pllvco; + + p_rcc_pll_divr1_reg = &(RCC->PLL1DIVR1) + (((uint32_t)0x02) * PLLnumber); + p_rcc_pll_divr2_reg = &(RCC->PLL1DIVR2) + (((uint32_t)0x01) * PLLnumber); + + /* Disable the post-dividers */ + CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLL1PEN | RCC_PLLCFGR_PLL1QEN | RCC_PLLCFGR_PLL1REN | RCC_PLLCFGR_PLL1SEN | + 0x00000200U) /* Hardcoded because no definition in CMSIS */ + << ((RCC_PLLCFGR_PLL2PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos)*PLLnumber)); + + /* Ensure PLLx is disabled */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON << ((RCC_CR_PLL2ON_Pos - RCC_CR_PLL1ON_Pos)*PLLnumber)); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLLx is disabled */ + while (READ_BIT(RCC->CR, (RCC_CR_PLL1RDY << ((RCC_CR_PLL2RDY_Pos - RCC_CR_PLL1RDY_Pos)*PLLnumber))) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + if (pPLLInit->PLLState == RCC_PLL_ON) + { + /* Check the parameters */ + assert_param(IS_RCC_PLLSOURCE(pPLLInit->PLLSource)); + assert_param(IS_RCC_PLLM_VALUE(pPLLInit->PLLM)); + assert_param(IS_RCC_PLLN_VALUE(pPLLInit->PLLN)); + assert_param(IS_RCC_PLLP_VALUE(pPLLInit->PLLP)); + assert_param(IS_RCC_PLLQ_VALUE(pPLLInit->PLLQ)); + assert_param(IS_RCC_PLLR_VALUE(pPLLInit->PLLR)); + assert_param(IS_RCC_PLLS_VALUE(pPLLInit->PLLS)); + assert_param(IS_RCC_PLLT_VALUE(pPLLInit->PLLT)); + + pllsrc = pPLLInit->PLLSource; + + /* Compute VCO input frequency and define range accordingly. First check clock source frequency */ + if (pllsrc == RCC_PLLSOURCE_HSI) + { + /* Clock source is HSI or HSI/HSIDIV */ + pllvco = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos); + } + else if (pllsrc == RCC_PLLSOURCE_HSE) + { + /* Clock source is HSE */ + pllvco = HSE_VALUE; + } + else + { + /* Clock source is CSI */ + pllvco = CSI_VALUE; + } + + /* Compute VCO input frequency depending on M divider */ + pllvco = (pllvco / pPLLInit->PLLM); + assert_param(IS_RCC_PLL_VCOINPUTFREQ(pllvco)); + + if (pllvco >= RCC_PLL_INPUTRANGE2_FREQMAX) + { + pllvco = RCC_PLL_VCOINPUT_RANGE3 | RCC_PLL_VCO_HIGH; + } + else if (pllvco >= RCC_PLL_INPUTRANGE1_FREQMAX) + { + pllvco = RCC_PLL_VCOINPUT_RANGE2 | RCC_PLL_VCO_HIGH; + } + else if (pllvco >= RCC_PLL_INPUTRANGE0_FREQMAX) + { + pllvco = RCC_PLL_VCOINPUT_RANGE1 | RCC_PLL_VCO_HIGH; + } + else + { + pllvco = RCC_PLL_VCOINPUT_RANGE0 | RCC_PLL_VCO_LOW; + } + + pllvco = (pllvco << ((RCC_PLLCFGR_PLL2RGE_Pos - RCC_PLLCFGR_PLL1RGE_Pos) * PLLnumber)); + + /* Configure PLL source and PLLM divider */ + MODIFY_REG(RCC->PLLCKSELR, (RCC_PLLCKSELR_PLLSRC | (RCC_PLLCKSELR_DIVM1 << ((RCC_PLLCKSELR_DIVM2_Pos - RCC_PLLCKSELR_DIVM1_Pos)*PLLnumber))), \ + pllsrc | (pPLLInit->PLLM << (RCC_PLLCKSELR_DIVM1_Pos + ((RCC_PLLCKSELR_DIVM2_Pos - RCC_PLLCKSELR_DIVM1_Pos)*PLLnumber)))); + + if ((RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC) != pllsrc) + { + /* There is another PLL activated with another source */ + return HAL_ERROR; + } + + /* Configure VCO input range, VCO selection and clear FRACEN */ + MODIFY_REG(RCC->PLLCFGR, (RCC_PLLCFGR_PLL1RGE | RCC_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN) << (((RCC_PLLCFGR_PLL2RGE_Pos - RCC_PLLCFGR_PLL1RGE_Pos)*PLLnumber)), \ + pllvco); + + /* Configure PLLN, PLLP, PLLQ, PLLR, PLLS and PLLT dividers */ + WRITE_REG(*p_rcc_pll_divr1_reg, ((pPLLInit->PLLN - 1U) | + ((pPLLInit->PLLP - 1U) << RCC_PLL1DIVR1_DIVP_Pos) | + ((pPLLInit->PLLQ - 1U) << RCC_PLL1DIVR1_DIVQ_Pos) | + ((pPLLInit->PLLR - 1U) << RCC_PLL1DIVR1_DIVR_Pos))); + WRITE_REG(*p_rcc_pll_divr2_reg, ((pPLLInit->PLLS - 1U) | + ((pPLLInit->PLLT - 1U) << RCC_PLL2DIVR2_DIVT_Pos))); + + if (PLLnumber == RCC_PLL1_CONFIG) + { + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1PEN); + } + + if (pPLLInit->PLLFractional != 0U) + { + assert_param(IS_RCC_PLLFRACN_VALUE(pPLLInit->PLLFractional)); + + p_rcc_pll_fracr_reg = &(RCC->PLL1FRACR) + (((uint32_t)0x02) * PLLnumber); + + /* Configure PLLFRACN */ + MODIFY_REG(*p_rcc_pll_fracr_reg, RCC_PLL1FRACR_FRACN, pPLLInit->PLLFractional << RCC_PLL1FRACR_FRACN_Pos); + + /* Enable PLLFRACLE */ + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN << ((RCC_PLLCFGR_PLL2FRACEN_Pos - RCC_PLLCFGR_PLL1FRACEN_Pos)*PLLnumber)); + } + + /* Enable the PLLx */ + SET_BIT(RCC->CR, RCC_CR_PLL1ON << ((RCC_CR_PLL2ON_Pos - RCC_CR_PLL1ON_Pos)*PLLnumber)); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLLx is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY << ((RCC_CR_PLL2RDY_Pos - RCC_CR_PLL1RDY_Pos)*PLLnumber)) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable outputs to save power when PLLx is off */ + MODIFY_REG(RCC->PLLCKSELR, ((RCC_PLLCKSELR_DIVM1 << (RCC_PLLCKSELR_DIVM1_Pos + ((RCC_PLLCKSELR_DIVM2_Pos - RCC_PLLCKSELR_DIVM1_Pos)*PLLnumber))) + | RCC_PLLCKSELR_PLLSRC), RCC_PLLSOURCE_NONE); + } + + return ret; +} + +/** + * @brief Compute PLL1 VCO output frequency + * @retval Value of PLL1 VCO output frequency + */ +static uint32_t RCC_PLL1_GetVCOOutputFreq(void) +{ + uint32_t tmpreg1; + uint32_t tmpreg2; + uint32_t pllsrc; + uint32_t pllm; + uint32_t plln; + uint32_t pllfracn; + float_t frequency; + + /* Get PLL1 CKSELR and DIVR register values */ + tmpreg1 = RCC->PLLCKSELR; + tmpreg2 = RCC->PLL1DIVR1; + + /* Retrieve PLL1 multiplication factor and divider */ + pllm = (tmpreg1 & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos; + plln = (tmpreg2 & RCC_PLL1DIVR1_DIVN) + 1U; + + if (pllm == 0U) + { + /* Prescaler disabled */ + return 0U; + } + + /* Check if fractional part is enable */ + if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U) + { + pllfracn = (RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> RCC_PLL1FRACR_FRACN_Pos; + } + else + { + pllfracn = 0U; + } + + /* determine PLL source */ + switch (tmpreg1 & RCC_PLLCKSELR_PLLSRC) + { + /* HSI used as PLL1 clock source */ + case RCC_PLLSOURCE_HSI: + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + pllsrc = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos); + } + else + { + /* Can't retrieve HSIDIV value */ + pllsrc = 0U; + } + break; + + /* HSE used as PLL1 clock source */ + case RCC_PLLSOURCE_HSE: + pllsrc = HSE_VALUE; + break; + + /* CSI used as PLL1 clock source */ + case RCC_PLLSOURCE_CSI: + pllsrc = CSI_VALUE; + break; + + default: + pllsrc = 0U; + break; + } + + /* Compute VCO output frequency */ + frequency = ((float_t)pllsrc / (float_t)pllm) * ((float_t)plln + ((float_t)pllfracn / (float_t)0x2000U)); + + return (uint32_t)frequency; +} + +/** + * @brief Compute PLL2 VCO output frequency + * @retval Value of PLL2 VCO output frequency + */ +static uint32_t RCC_PLL2_GetVCOOutputFreq(void) +{ + uint32_t tmpreg1; + uint32_t tmpreg2; + uint32_t pllsrc; + uint32_t pllm; + uint32_t plln; + uint32_t pllfracn; + float_t frequency; + + /* Get PLL2 CKSELR and DIVR register values */ + tmpreg1 = RCC->PLLCKSELR; + tmpreg2 = RCC->PLL2DIVR1; + + /* Retrieve PLL2 multiplication factor and divider */ + pllm = (tmpreg1 & RCC_PLLCKSELR_DIVM2) >> RCC_PLLCKSELR_DIVM2_Pos; + plln = (tmpreg2 & RCC_PLL2DIVR1_DIVN) + 1U; + + if (pllm == 0U) + { + /* Prescaler disabled */ + return 0U; + } + + /* Check if fractional part is enable */ + if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL2FRACEN) != 0U) + { + pllfracn = (RCC->PLL2FRACR & RCC_PLL2FRACR_FRACN) >> RCC_PLL2FRACR_FRACN_Pos; + } + else + { + pllfracn = 0U; + } + + /* determine PLL source */ + switch (tmpreg1 & RCC_PLLCKSELR_PLLSRC) + { + /* HSI used as PLL2 clock source */ + case RCC_PLLSOURCE_HSI: + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + pllsrc = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos); + } + else + { + /* Can't retrieve HSIDIV value */ + pllsrc = 0U; + } + break; + + /* HSE used as PLL2 clock source */ + case RCC_PLLSOURCE_HSE: + pllsrc = HSE_VALUE; + break; + + /* CSI used as PLL2 clock source */ + case RCC_PLLSOURCE_CSI: + pllsrc = CSI_VALUE; + break; + + default: + pllsrc = 0U; + break; + } + + /* Compute VCO output frequency */ + frequency = ((float_t)pllsrc / (float_t)pllm) * ((float_t)plln + ((float_t)pllfracn / (float_t)0x2000U)); + + return (uint32_t)frequency; +} + +/** + * @brief Compute PLL3 VCO output frequency + * @retval Value of PLL3 VCO output frequency + */ +static uint32_t RCC_PLL3_GetVCOOutputFreq(void) +{ + uint32_t tmpreg1; + uint32_t tmpreg2; + uint32_t pllsrc; + uint32_t pllm; + uint32_t plln; + uint32_t pllfracn; + float_t frequency; + + /* Get PLL3 CKSELR and DIVR register values */ + tmpreg1 = RCC->PLLCKSELR; + tmpreg2 = RCC->PLL3DIVR1; + + /* Retrieve PLL3 multiplication factor and divider */ + pllm = (tmpreg1 & RCC_PLLCKSELR_DIVM3) >> RCC_PLLCKSELR_DIVM3_Pos; + plln = (tmpreg2 & RCC_PLL3DIVR1_DIVN) + 1U; + + if (pllm == 0U) + { + /* Prescaler disabled */ + return 0U; + } + + /* Check if fractional part is enable */ + if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL3FRACEN) != 0U) + { + pllfracn = (RCC->PLL3FRACR & RCC_PLL3FRACR_FRACN) >> RCC_PLL3FRACR_FRACN_Pos; + } + else + { + pllfracn = 0U; + } + + /* determine PLL source */ + switch (tmpreg1 & RCC_PLLCKSELR_PLLSRC) + { + /* HSI used as PLL3 clock source */ + case RCC_PLLSOURCE_HSI: + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + pllsrc = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos); + } + else + { + /* Can't retrieve HSIDIV value */ + pllsrc = 0U; + } + break; + + /* HSE used as PLL3 clock source */ + case RCC_PLLSOURCE_HSE: + pllsrc = HSE_VALUE; + break; + + /* CSI used as PLL3 clock source */ + case RCC_PLLSOURCE_CSI: + pllsrc = CSI_VALUE; + break; + + default: + pllsrc = 0U; + break; + } + + /* Compute VCO output frequency */ + frequency = ((float_t)pllsrc / (float_t)pllm) * ((float_t)plln + ((float_t)pllfracn / (float_t)0x2000U)); + + return (uint32_t)frequency; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* HAL_RCC_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c new file mode 100644 index 0000000..c2d4398 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c @@ -0,0 +1,3242 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 extension peripheral: + * + Extended Peripheral Control 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup RCCEx RCCEx + * @brief RCC HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup RCCEx_Private_defines RCCEx Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Macros RCCEx Private Macros + * @{ + */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup RCCEx_Private_Functions RCCEx Private Functions + * @{ + */ +static uint32_t RCC_GetCLKPFreq(void); +/** + * @} + */ + +/* 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) and RCC_BDCR register are set to their reset values. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the RCC extended peripherals clocks according to the specified + * parameters in the RCC_PeriphCLKInitTypeDef. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * contains the configuration information for the Extended Peripherals + * clocks (SDMMC12, CKPER, FMC, XSPI1, XSPI2, ADC, ADF1, CEC, FDCAN, I2C1/I3C1, + * I2C2, LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5, LPUART1, SAI1, + * SAI2, SPDIF, SPI1, SPI2, SPI3, SPI4, SPI5, SPI6, SAI1, USART1, USART2, + * USART3, UART4, UART5, UART7, UART8, ETH1, USB and RTC). + * @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. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tmpreg; + 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(PeriphClkInit->PeriphClockSelection)); + + /*---------------------------- RTC configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) + { + /* check for RTC Parameters used to output RTCCLK */ + assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); + + /* As the RTC clock source selection can be changed only if the Backup Domain is reset */ + /* reset the Backup domain only if the RTC Clock source selection is modified from default reset value */ + tmpreg = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL); + + if ((tmpreg != RCC_RTCCLKSOURCE_DISABLE) && (tmpreg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR1, PWR_CR1_DBP); + + /* Read back to check Backup domain enabled */ + if (READ_BIT(PWR->CR1, PWR_CR1_DBP) == 0U) + { + ret = HAL_ERROR; + } + else + { + /* Store the content of BDCR register before the reset of Backup Domain */ + /* excepted the RTC clock source selection that will be changed */ + tmpreg = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + /* Restore the content of BDCR register */ + WRITE_REG(RCC->BDCR, tmpreg); + } + } + + if (ret == HAL_OK) + { + /* If LSE is selected as RTC clock source (and enabled prior to Backup Domain reset), wait for LSE reactivation */ + if (PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE) + { + /* 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) + { + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + __HAL_RCC_RTC_ENABLE(); + } + else + { + /* set overall return value */ + status = ret; + } + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- FMC configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_FMC) == RCC_PERIPHCLK_FMC) + { + /* Check the parameters */ + assert_param(IS_RCC_FMCCLKSOURCE(PeriphClkInit->FmcClockSelection)); + + switch (PeriphClkInit->FmcClockSelection) + { + case RCC_FMCCLKSOURCE_HCLK: /* HCLK clock selected as FMC kernel peripheral clock */ + break; + + case RCC_FMCCLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for FMC kernel */ + /* Enable FMC kernel clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* FMC kernel clock source configuration done later after clock selection check */ + break; + + case RCC_FMCCLKSOURCE_PLL2R: /* PLL2_R is used as clock source for FMC kernel */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_RCLK); + /* FMC kernel clock source configuration done later after clock selection check */ + break; + + case RCC_FMCCLKSOURCE_HSI: /* HSI oscillator is used as clock source for FMC kernel */ + /* FMC kernel clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of FMC kernel clock*/ + __HAL_RCC_FMC_CONFIG(PeriphClkInit->FmcClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- XSPI1 clock source configuration ----------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_XSPI1) == RCC_PERIPHCLK_XSPI1) + { + /* Check the parameters */ + assert_param(IS_RCC_XSPI1CLKSOURCE(PeriphClkInit->Xspi1ClockSelection)); + + switch (PeriphClkInit->Xspi1ClockSelection) + { + case RCC_XSPI1CLKSOURCE_HCLK: /* HCLK is used as clock source for Xspi1 */ + /* Nothing to do */ + break; + + case RCC_XSPI1CLKSOURCE_PLL2S: /* PLL2_S is used as clock source for Xspi1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_SCLK); + /* XSPI1 clock source configuration done later after clock selection check */ + break; + + case RCC_XSPI1CLKSOURCE_PLL2T: /* PLL2_T is used as clock source for Xspi1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_TCLK); + /* XSPI1 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the XSPI1 clock source */ + __HAL_RCC_XSPI1_CONFIG(PeriphClkInit->Xspi1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- XSPI2 clock source configuration ----------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_XSPI2) == RCC_PERIPHCLK_XSPI2) + { + /* Check the parameters */ + assert_param(IS_RCC_XSPI2CLKSOURCE(PeriphClkInit->Xspi2ClockSelection)); + + switch (PeriphClkInit->Xspi2ClockSelection) + { + case RCC_XSPI2CLKSOURCE_HCLK: /* HCLK is used as clock source for Xspi2 */ + /* Nothing to do */ + break; + + case RCC_XSPI2CLKSOURCE_PLL2S: /* PLL2_S is used as clock source for Xspi2 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_SCLK); + /* XSPI2 clock source configuration done later after clock selection check */ + break; + + case RCC_XSPI2CLKSOURCE_PLL2T: /* PLL2_T is used as clock source for Xspi2 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_TCLK); + /* XSPI2 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the XSPI2 clock source */ + __HAL_RCC_XSPI2_CONFIG(PeriphClkInit->Xspi2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------------ CKPER configuration --------------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_CKPER) == RCC_PERIPHCLK_CKPER) + { + /* Check the parameters */ + assert_param(IS_RCC_CKPERCLKSOURCE(PeriphClkInit->CkperClockSelection)); + + /* Configure the CKPER clock source */ + __HAL_RCC_CLKP_CONFIG(PeriphClkInit->CkperClockSelection); + } + + /*------------------------------------- SDMMC12 Configuration ------------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SDMMC12) == RCC_PERIPHCLK_SDMMC12) + { + /* Check the parameters */ + assert_param(IS_RCC_SDMMC12CLKSOURCE(PeriphClkInit->Sdmmc12ClockSelection)); + + switch (PeriphClkInit->Sdmmc12ClockSelection) + { + case RCC_SDMMC12CLKSOURCE_PLL2S: /* PLL2_S is used as clock source for SDMMC12 kernel */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_SCLK); + /* SDMMC12 kernel clock source configuration done later after clock selection check */ + break; + + case RCC_SDMMC12CLKSOURCE_PLL2T: /* PLL2_T is used as clock source for SDMMC12 kernel */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_TCLK); + /* SDMMC12 kernel clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SDMMC12 clock*/ + __HAL_RCC_SDMMC12_CONFIG(PeriphClkInit->Sdmmc12ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- ADC configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC) + { + /* Check the parameters */ + assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection)); + + switch (PeriphClkInit->AdcClockSelection) + { + + case RCC_ADCCLKSOURCE_PLL2P: /* PLL2_P is used as clock source for ADC */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* ADC clock source configuration done later after clock selection check */ + break; + + case RCC_ADCCLKSOURCE_PLL3R: /* PLL3_R is used as clock source for ADC */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* ADC clock source configuration done later after clock selection check */ + break; + + case RCC_ADCCLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of ADC clock */ + /* ADC clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of ADC clock*/ + __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- ADF1 configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_ADF1) == RCC_PERIPHCLK_ADF1) + { + /* Check the parameters */ + assert_param(IS_RCC_ADF1CLKSOURCE(PeriphClkInit->Adf1ClockSelection)); + + switch (PeriphClkInit->Adf1ClockSelection) + { + case RCC_ADF1CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for ADF1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* ADF1 clock source configuration done later after clock selection check */ + break; + + case RCC_ADF1CLKSOURCE_PLL3P: /* PLL3_P is used as clock source for ADF1 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_PCLK); + /* ADF1 clock source configuration done later after clock selection check */ + break; + + case RCC_ADF1CLKSOURCE_HCLK: /* HCLK is used as clock source for ADF1 */ + case RCC_ADF1CLKSOURCE_PIN: /* External I2S_CKIN is used as clock source for ADF1 */ + case RCC_ADF1CLKSOURCE_CSI: /* CSI is used as clock source for ADF1 */ + case RCC_ADF1CLKSOURCE_HSI: /* HSI is used as clock source for ADF1 */ + /* ADF1 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of ADF1 clock*/ + __HAL_RCC_ADF1_CONFIG(PeriphClkInit->Adf1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------- CEC configuration ---------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) + { + /* Check the parameters */ + assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); + + /* Configure the CEC clock source */ + __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); + } + + /*---------------------- ETH1 REF configuration --------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_ETH1REF) == RCC_PERIPHCLK_ETH1REF) + { + /* Check the parameters */ + assert_param(IS_RCC_ETH1REFCLKSOURCE(PeriphClkInit->Eth1RefClockSelection)); + + /* Configure the ETH1 REF clock source */ + __HAL_RCC_ETH1REF_CONFIG(PeriphClkInit->Eth1RefClockSelection); + } + + /*---------------------- ETH1PHY configuration --------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_ETH1PHY) == RCC_PERIPHCLK_ETH1PHY) + { + /* Check the parameters */ + assert_param(IS_RCC_ETH1PHYCLKSOURCE(PeriphClkInit->Eth1PhyClockSelection)); + + switch (PeriphClkInit->Eth1PhyClockSelection) + { + case RCC_ETH1PHYCLKSOURCE_HSE: /* HSE is used as clock source for ETH PHY */ + /* ETH PHY clock source configuration done later after clock selection check */ + break; + + case RCC_ETH1PHYCLKSOURCE_PLL3S: /* PLL3_S is used as clock source for ETH PHY */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_SCLK); + /* ETH PHY clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of ETH PHY clock*/ + __HAL_RCC_ETH1PHY_CONFIG(PeriphClkInit->Eth1PhyClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------- FDCAN configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_FDCAN) == RCC_PERIPHCLK_FDCAN) + { + /* Check the parameters */ + assert_param(IS_RCC_FDCANCLKSOURCE(PeriphClkInit->FdcanClockSelection)); + + switch (PeriphClkInit->FdcanClockSelection) + { + case RCC_FDCANCLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for FDCAN kernel */ + /* Enable FDCAN Clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* FDCAN clock source configuration done later after clock selection check */ + break; + + case RCC_FDCANCLKSOURCE_PLL2P: /* PLL2_P is used as clock source for FDCAN kernel */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* FDCAN clock source configuration done later after clock selection check */ + break; + + case RCC_FDCANCLKSOURCE_HSE: /* HSE is used as clock source for FDCAN kernel */ + /* FDCAN clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of FDCAN clock*/ + __HAL_RCC_FDCAN_CONFIG(PeriphClkInit->FdcanClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------ I2C1/I3C1 Configuration ------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_I2C1_I3C1) == RCC_PERIPHCLK_I2C1_I3C1) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C1_I3C1CLKSOURCE(PeriphClkInit->I2c1_I3c1ClockSelection)); + + switch (PeriphClkInit->I2c1_I3c1ClockSelection) + { + case RCC_I2C1_I3C1CLKSOURCE_PLL3R: /* PLL3_R is used as clock source for I2C1/I3C1*/ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* I2C1/I3C1 clock source configuration done later after clock selection check */ + break; + + case RCC_I2C1_I3C1CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for I2C1/I3C1*/ + case RCC_I2C1_I3C1CLKSOURCE_HSI: /* HSI is used as clock source for I2C1/I3C1*/ + case RCC_I2C1_I3C1CLKSOURCE_CSI: /* CSI is used as clock source for I2C1/I3C1*/ + /* I2C1/I3C1 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I2C1/I3C1 clock*/ + __HAL_RCC_I2C1_I3C1_CONFIG(PeriphClkInit->I2c1_I3c1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------ I2C2/I2C3 Configuration -------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_I2C23) == RCC_PERIPHCLK_I2C23) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C23CLKSOURCE(PeriphClkInit->I2c23ClockSelection)); + + switch (PeriphClkInit->I2c23ClockSelection) + { + case RCC_I2C23CLKSOURCE_PLL3R: /* PLL3_R is used as clock source for I2C2/I2C3 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* I2C2/I2C3 clock source configuration done later after clock selection check */ + break; + + case RCC_I2C23CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for I2C2/I2C3 */ + case RCC_I2C23CLKSOURCE_HSI: /* HSI is used as clock source for I2C2/I2C3 */ + case RCC_I2C23CLKSOURCE_CSI: /* CSI is used as clock source for I2C2/I2C3 */ + /* I2C2/I2C3 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I2C2/I2C3 clock*/ + __HAL_RCC_I2C23_CONFIG(PeriphClkInit->I2c23ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- LPTIM1 configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection)); + + switch (PeriphClkInit->Lptim1ClockSelection) + { + case RCC_LPTIM1CLKSOURCE_PCLK1: /* PCLK1 as clock source for LPTIM1 */ + /* LPTIM1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for LPTIM1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* LPTIM1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_PLL3R: /* PLL3_R is used as clock source for LPTIM1 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* LPTIM1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_LSE: + /* External low speed OSC clock is used as clock source for LPTIM1 */ + /* LPTIM1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_LSI: + /* Internal low speed OSC clock is used as clock source for LPTIM1 */ + /* LPTIM1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as clock source for LPTIM1 */ + /* LPTIM1 clock source configuration done 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(PeriphClkInit->Lptim1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- LPTIM2/LPTIM3 configuration -----------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_LPTIM23) == RCC_PERIPHCLK_LPTIM23) + { + switch (PeriphClkInit->Lptim23ClockSelection) + { + case RCC_LPTIM23CLKSOURCE_PCLK4: /* PCLK4 as clock source for LPTIM2/LPTIM3 */ + /* LPTIM2/LPTIM3 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM23CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for LPTIM2/LPTIM3 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* LPTIM2/LPTIM3 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM23CLKSOURCE_PLL3R: /* PLL3_R is used as clock source for LPTIM2/LPTIM3 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* LPTIM2/LPTIM3 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM23CLKSOURCE_LSE: + /* External low speed OSC clock is used as clock source for LPTIM2/LPTIM3 */ + /* LPTIM2/LPTIM3 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM23CLKSOURCE_LSI: + /* Internal low speed OSC clock is used as clock source for LPTIM2/LPTIM3 */ + /* LPTIM2/LPTIM3 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM23CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of LPTIM2 clock */ + /* LPTIM2/LPTIM3 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM2/LPTIM3 clock*/ + __HAL_RCC_LPTIM23_CONFIG(PeriphClkInit->Lptim23ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- LPTIM4/LPTIM5 configuration -----------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_LPTIM45) == RCC_PERIPHCLK_LPTIM45) + { + switch (PeriphClkInit->Lptim45ClockSelection) + { + case RCC_LPTIM45CLKSOURCE_PCLK4: /* PCLK4 as clock source for LPTIM4/LPTIM5 */ + /* LPTIM4/LPTIM5 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM45CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM4/LPTIM5 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* LPTIM4/LPTIM5 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM45CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM4/LPTIM5 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* LPTIM4/LPTIM5 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM45CLKSOURCE_LSE: + /* External low speed OSC clock is used as source of LPTIM4/LPTIM5 clock */ + /* LPTIM4/LPTIM5 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM45CLKSOURCE_LSI: + /* Internal low speed OSC clock is used as source of LPTIM4/LPTIM5 clock */ + /* LPTIM4/LPTIM5 clock source configuration done later after clock selection check */ + break; + + case RCC_LPTIM45CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of LPTIM4/LPTIM5 clock */ + /* LPTIM4/LPTIM5 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM4/LPTIM5 clock */ + __HAL_RCC_LPTIM45_CONFIG(PeriphClkInit->Lptim45ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- LPUART1 Configuration -------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1) + { + /* Check the parameters */ + assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection)); + + switch (PeriphClkInit->Lpuart1ClockSelection) + { + case RCC_LPUART1CLKSOURCE_PCLK4: /* PCLK4 selected as clock source for LPUART1 */ + /* LPUART1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_PLL2Q: /* PLL2_Q is used as clock source for LPUART1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_QCLK); + /* LPUART1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for LPUART1 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* LPUART1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_HSI: + /* HSI oscillator clock is used as source of LPUART1 clock */ + /* LPUART1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_CSI: + /* CSI oscillator clock is used as source of LPUART1 clock */ + /* LPUART1 clock source configuration done later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_LSE: + /* LSE, oscillator is used as source of LPUART1 clock */ + /* LPUART1 clock source configuration done 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(PeriphClkInit->Lpuart1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- LTDC Configuration ----------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) + { + /* LTDC internally connected to PLL3_R output clock */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + } + + /*---------------------------- PSSI configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PSSI) == RCC_PERIPHCLK_PSSI) + { + /* Check the parameters */ + assert_param(IS_RCC_PSSICLKSOURCE(PeriphClkInit->PssiClockSelection)); + + switch (PeriphClkInit->PssiClockSelection) + { + case RCC_PSSICLKSOURCE_PLL3R: /* PLL3_R is used as clock source for PSSI */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* PSSI clock source configuration done later after clock selection check */ + break; + + case RCC_PSSICLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of PSSI clock */ + /* PSSI clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of PSSI clock*/ + __HAL_RCC_PSSI_CONFIG(PeriphClkInit->PssiClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SAI1 configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) + { + /* Check the parameters */ + assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection)); + + switch (PeriphClkInit->Sai1ClockSelection) + { + case RCC_SAI1CLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for SAI1 */ + /* Enable SAI Clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SAI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for SAI1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SAI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_PLL3P: /* PLL3_P is used as clock source for SAI1 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SAI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock */ + /* SAI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of SAI1 clock */ + /* SAI1 clock source configuration done 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(PeriphClkInit->Sai1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SAI2 configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) + { + /* Check the parameters */ + assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection)); + + switch (PeriphClkInit->Sai2ClockSelection) + { + case RCC_SAI2CLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for SAI2 */ + /* Enable SAI Clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SAI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for SAI2 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SAI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_PLL3P: /* PLL3_P is used as clock source for SAI2 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SAI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_PIN: /* External clock is used as source of SAI2 clock */ + /* SAI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of SAI2 clock */ + /* SAI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_SPDIF: /* SPDIF clock is used as source of SAI2 clock */ + /* SAI2 clock source configuration done 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(PeriphClkInit->Sai2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SPDIFRX configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) + { + /* Check the parameters */ + assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifrxClockSelection)); + + switch (PeriphClkInit->SpdifrxClockSelection) + { + case RCC_SPDIFRXCLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for SPDIFRX */ + /* Enable PLL1Q Clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPDIFRX clock source configuration done later after clock selection check */ + break; + + case RCC_SPDIFRXCLKSOURCE_PLL2R: /* PLL2_R is used as clock source for SPDIFRX */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_RCLK); + /* SPDIFRX clock source configuration done later after clock selection check */ + break; + + case RCC_SPDIFRXCLKSOURCE_PLL3R: /* PLL3_R is used as clock source for SPDIFRX */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_RCLK); + /* SPDIFRX clock source configuration done later after clock selection check */ + break; + + case RCC_SPDIFRXCLKSOURCE_HSI: + /* Internal OSC clock is used as source of SPDIFRX clock*/ + /* SPDIFRX clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SPDIFRX clock */ + __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifrxClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SPI1 configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SPI1) == RCC_PERIPHCLK_SPI1) + { + /* Check the parameters */ + assert_param(IS_RCC_SPI1CLKSOURCE(PeriphClkInit->Spi1ClockSelection)); + + switch (PeriphClkInit->Spi1ClockSelection) + { + case RCC_SPI1CLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for SPI1 */ + /* Enable SPI Clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI1CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for SPI1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SPI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI1CLKSOURCE_PLL3P: /* PLL3_P is used as clock source for SPI1 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SPI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI1CLKSOURCE_PIN: /* External I2S_CKIN is used as clock source for SPI1 */ + /* 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) + { + /* Set the source of SPI1 clock*/ + __HAL_RCC_SPI1_CONFIG(PeriphClkInit->Spi1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SPI2/SPI3 configuration ---------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SPI23) == RCC_PERIPHCLK_SPI23) + { + /* Check the parameters */ + assert_param(IS_RCC_SPI23CLKSOURCE(PeriphClkInit->Spi23ClockSelection)); + + switch (PeriphClkInit->Spi23ClockSelection) + { + case RCC_SPI23CLKSOURCE_PLL1Q: /* PLL1_Q is used as clock source for SPI2/SPI3 */ + /* Enable SPI Clock output generated form System PLL . */ + __HAL_RCC_PLL1CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPI2/SPI3 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI23CLKSOURCE_PLL2P: /* PLL2_P is used as clock source for SPI2/SPI3 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SPI2/SPI3 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI23CLKSOURCE_PLL3P: /* PLL3_P is used as clock source for SPI2/SPI3 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_PCLK); + /* SPI2/SPI3 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI23CLKSOURCE_PIN: /* External clock I2S_CKIN is used as clock source for SPI2/SPI3 */ + /* SPI2/SPI3 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI23CLKSOURCE_CLKP: /* HSI, HSE, or CSI oscillator is used as source of SPI2/SPI3 clock */ + /* SPI2/SPI3 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SPI2/SPI3 clock*/ + __HAL_RCC_SPI23_CONFIG(PeriphClkInit->Spi23ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SPI4/5 configuration -------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SPI45) == RCC_PERIPHCLK_SPI45) + { + /* Check the parameters */ + assert_param(IS_RCC_SPI45CLKSOURCE(PeriphClkInit->Spi45ClockSelection)); + + switch (PeriphClkInit->Spi45ClockSelection) + { + case RCC_SPI45CLKSOURCE_PCLK2: /* PCLK2 as clock source for SPI4/SPI5 */ + /* SPI4/SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI45CLKSOURCE_PLL2Q: /* PLL2_Q is used as clock source for SPI4/SPI5 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPI4/SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI45CLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for SPI4/SPI5 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPI4/SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI45CLKSOURCE_HSI: /* HSI oscillator clock is used as source of SPI4/SPI5 */ + /* SPI4/SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI45CLKSOURCE_CSI: /* CSI oscillator clock is used as source of SPI4/SPI5 */ + /* SPI4/SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI45CLKSOURCE_HSE: /* HSE oscillator clock is used as source of SPI4/SPI5 */ + /* SPI4/SPI5 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SPI4/SPI5 clock */ + __HAL_RCC_SPI45_CONFIG(PeriphClkInit->Spi45ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*---------------------------- SPI6 configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_SPI6) == RCC_PERIPHCLK_SPI6) + { + /* Check the parameters */ + assert_param(IS_RCC_SPI6CLKSOURCE(PeriphClkInit->Spi6ClockSelection)); + + switch (PeriphClkInit->Spi6ClockSelection) + { + case RCC_SPI6CLKSOURCE_PCLK4: /* PCLK4 as clock source for SPI6 */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_PLL2Q: /* PLL2_Q is used as clock source for SPI6 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for SPI6 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_HSI: /* HSI oscillator clock is used as source for SPI6 */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_CSI: /* CSI oscillator clock is used as source for SPI6 */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_HSE: /* HSE oscillator is used as source for SPI6 */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SPI6 clock*/ + __HAL_RCC_SPI6_CONFIG(PeriphClkInit->Spi6ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- USART1 configuration --------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + { + /* Check the parameters */ + assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection)); + + switch (PeriphClkInit->Usart1ClockSelection) + { + case RCC_USART1CLKSOURCE_PCLK2: /* PCLK2 as clock source for USART1 */ + /* USART1 clock source configuration done later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_PLL2Q: /* PLL2_Q is used as clock source for USART1 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_QCLK); + /* USART1 clock source configuration done later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for USART1 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* USART1 clock source configuration done later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_HSI: /* HSI oscillator clock is used as source for USART1 */ + /* USART1 clock source configuration done later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_CSI: /* CSI oscillator clock is used as source for USART1 */ + /* USART1 clock source configuration done later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_LSE: /* LSE oscillator is used as source for USART1 */ + /* USART1 clock source configuration done 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(PeriphClkInit->Usart1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------- USART2/USART3/UART4/UART5/UART7/UART8 Configuration --------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_USART234578) == RCC_PERIPHCLK_USART234578) + { + /* Check the parameters */ + assert_param(IS_RCC_USART234578CLKSOURCE(PeriphClkInit->Usart234578ClockSelection)); + + switch (PeriphClkInit->Usart234578ClockSelection) + { + case RCC_USART234578CLKSOURCE_PCLK1: /* PCLK1 as clock source for USART2/USART3/UART4/UART5/UART7/UART8 */ + /* USART2/USART3/UART4/UART5/UART7/UART8 clock source configuration done later after clock selection check */ + break; + + case RCC_USART234578CLKSOURCE_PLL2Q: /* PLL2_Q is used as clock source for USART2/USART3/UART4/UART5/UART7/UART8 */ + __HAL_RCC_PLL2CLKOUT_ENABLE(RCC_PLL_QCLK); + /* USART2/USART3/UART4/UART5/UART7/UART8 clock source configuration done later after clock selection check */ + break; + + case RCC_USART234578CLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for USART2/USART3/UART4/UART5/UART7/UART8 */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* USART2/USART3/UART4/UART5/UART7/UART8 clock source configuration done later after clock selection check */ + break; + + case RCC_USART234578CLKSOURCE_HSI: + /* HSI oscillator clock is used as source of USART2/USART3/UART4/UART5/UART7/UART8 clock */ + /* USART2/USART3/UART4/UART5/UART7/UART8 clock source configuration done later after clock selection check */ + break; + + case RCC_USART234578CLKSOURCE_CSI: + /* CSI oscillator clock is used as source of USART2/USART3/UART4/UART5/UART7/UART8 clock */ + /* USART2/USART3/UART4/UART5/UART7/UART8 clock source configuration done later after clock selection check */ + break; + + case RCC_USART234578CLKSOURCE_LSE: + /* LSE, oscillator is used as source of USART2/USART3/UART4/UART5/UART7/UART8 clock */ + /* USART2/USART3/UART4/UART5/UART7/UART8 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART2/USART3/UART4/UART5/UART7/UART8 clock */ + __HAL_RCC_USART234578_CONFIG(PeriphClkInit->Usart234578ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------ USBPHYC Configuration ---------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_USBPHYC) == RCC_PERIPHCLK_USBPHYC) + { + /* Check the parameters */ + assert_param(IS_RCC_USBPHYCCLKSOURCE(PeriphClkInit->UsbPhycClockSelection)); + + switch (PeriphClkInit->UsbPhycClockSelection) + { + case RCC_USBPHYCCLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for USBPHYC */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* USBPHYC clock source configuration done later after clock selection check */ + break; + + case RCC_USBPHYCCLKSOURCE_HSE: /* HSE is used as clock source for USBPHYC */ + case RCC_USBPHYCCLKSOURCE_HSE_DIV2: /* HSE divided by 2 is used as clock source for USBPHYC */ + /* USBPHYC clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USBPHYC clock*/ + __HAL_RCC_USBPHYC_CONFIG(PeriphClkInit->UsbPhycClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------ USBOTGFS Configuration ---------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_USBOTGFS) == RCC_PERIPHCLK_USBOTGFS) + { + /* Check the parameters */ + assert_param(IS_RCC_USBOTGFSCLKSOURCE(PeriphClkInit->UsbOtgFsClockSelection)); + + switch (PeriphClkInit->UsbOtgFsClockSelection) + { + case RCC_USBOTGFSCLKSOURCE_PLL3Q: /* PLL3_Q is used as clock source for USB OTG FS */ + __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL_QCLK); + /* USB OTG FS clock source configuration done later after clock selection check */ + break; + + case RCC_USBOTGFSCLKSOURCE_HSI48: /* HSI48 is used as clock source for USB OTG FS */ + case RCC_USBOTGFSCLKSOURCE_HSE: /* HSE is used as clock source for USB OTG FS */ + case RCC_USBOTGFSCLKSOURCE_CLK48: /* USBPHYC CLK48 is used as clock source for USB OTG FS */ + /* USB OTG FS clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USBPHYC clock*/ + __HAL_RCC_USBOTGFS_CONFIG(PeriphClkInit->UsbOtgFsClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------------ TIM configuration --------------------------------------*/ + if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_TIM) == RCC_PERIPHCLK_TIM) + { + /* Check the parameters */ + assert_param(IS_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection)); + + /* Configure Timer Prescaler */ + __HAL_RCC_TIMCLKPRESCALER_CONFIG(PeriphClkInit->TIMPresSelection); + } + + if (status == HAL_OK) + { + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * returns the configuration information for the Extended Peripherals clocks : + * (SDMMC12, CKPER, FMC, ADC, ADF1, CEC, FDCAN, I2C2/I2C3, I3C1, LPTIM1, + * LPTIM2/LPTIM3, LPTIM4/LPTIM5, LTDC, LPUART1, XSPI1, XSPI2, PSSI, RTC, SAI1, SAI2, + * SPDIF, SPI1, SPI2/SPI3, SPI4/SPI5, SPI6, TIM, USART1, USART2/USART3/UART4/UART5/UART7/UART8 + * USBPHYC, USB OTGFS). + * @retval None + */ +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + /* Set all possible values for the extended clock type parameter------------*/ + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_ADF1 | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_CKPER | RCC_PERIPHCLK_ETH1REF | RCC_PERIPHCLK_ETH1PHY | \ + RCC_PERIPHCLK_FDCAN | RCC_PERIPHCLK_FMC | RCC_PERIPHCLK_I2C1_I3C1 | \ + RCC_PERIPHCLK_I2C23 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM23 | \ + RCC_PERIPHCLK_LPTIM45 | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_LPUART1 | \ + RCC_PERIPHCLK_XSPI1 | RCC_PERIPHCLK_XSPI2 | RCC_PERIPHCLK_PSSI | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \ + RCC_PERIPHCLK_SDMMC12 | RCC_PERIPHCLK_SPDIFRX | RCC_PERIPHCLK_SPI1 | \ + RCC_PERIPHCLK_SPI23 | RCC_PERIPHCLK_SPI45 | RCC_PERIPHCLK_SPI6 | \ + RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART234578 | \ + RCC_PERIPHCLK_USBPHYC | RCC_PERIPHCLK_USBOTGFS; + + /* Get the ADC clock source ------------------------------------------------*/ + PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE(); + /* Get the ADF1 clock source -----------------------------------------------*/ + PeriphClkInit->Adf1ClockSelection = __HAL_RCC_GET_ADF1_SOURCE(); + /* Get the CEC clock source ------------------------------------------------*/ + PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE(); + /* Get the CKPER clock source ----------------------------------------------*/ + PeriphClkInit->CkperClockSelection = __HAL_RCC_GET_CLKP_SOURCE(); + /* Get the ETH1 clock source ----------------------------------------------*/ + PeriphClkInit->Eth1RefClockSelection = __HAL_RCC_GET_ETH1REF_SOURCE(); + /* Get the ETH1PHY clock source ----------------------------------------------*/ + PeriphClkInit->Eth1PhyClockSelection = __HAL_RCC_GET_ETH1PHY_SOURCE(); + /* Get the FDCAN kernel clock source ---------------------------------------*/ + PeriphClkInit->FdcanClockSelection = __HAL_RCC_GET_FDCAN_SOURCE(); + /* Get the FMC kernel clock source -----------------------------------------*/ + PeriphClkInit->FmcClockSelection = __HAL_RCC_GET_FMC_SOURCE(); + /* Get the I2C1 clock source -----------------------------------------------*/ + PeriphClkInit->I2c1_I3c1ClockSelection = __HAL_RCC_GET_I2C1_I3C1_SOURCE(); + /* Get the I2C2/I2C3 clock source ------------------------------------------*/ + PeriphClkInit->I2c23ClockSelection = __HAL_RCC_GET_I2C23_SOURCE(); + /* Get the LPTIM1 clock source ---------------------------------------------*/ + PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); + /* Get the LPTIM2/LPTIM3 clock source --------------------------------------*/ + PeriphClkInit->Lptim23ClockSelection = __HAL_RCC_GET_LPTIM23_SOURCE(); + /* Get the LPTIM4/LPTIM5 clock source --------------------------------------*/ + PeriphClkInit->Lptim45ClockSelection = __HAL_RCC_GET_LPTIM45_SOURCE(); + /* Get the LPUART1 clock source --------------------------------------------*/ + PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE(); + /* Get the LTDC clock source -----------------------------------------------*/ + PeriphClkInit->LtdcClockSelection = __HAL_RCC_GET_LTDC_SOURCE(); + /* Get the XSPI1 clock source -----------------------------------------------*/ + PeriphClkInit->Xspi1ClockSelection = __HAL_RCC_GET_XSPI1_SOURCE(); + /* Get the XSPI2 clock source -----------------------------------------------*/ + PeriphClkInit->Xspi2ClockSelection = __HAL_RCC_GET_XSPI2_SOURCE(); + /* Get the PSSI clock source -----------------------------------------------*/ + PeriphClkInit->PssiClockSelection = __HAL_RCC_GET_PSSI_SOURCE(); + /* Get the RTC clock source -----------------------------------------------*/ + PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); + /* Get the SAI1 clock source -----------------------------------------------*/ + PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); + /* Get the SAI2 clock source -----------------------------------------------*/ + PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); + /* Get the SDMMC clock source ----------------------------------------------*/ + PeriphClkInit->Sdmmc12ClockSelection = __HAL_RCC_GET_SDMMC12_SOURCE(); + /* Get the SPDIFRX clock source --------------------------------------------*/ + PeriphClkInit->SpdifrxClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE(); + /* Get the SPI1 clock source -----------------------------------------------*/ + PeriphClkInit->Spi1ClockSelection = __HAL_RCC_GET_SPI1_SOURCE(); + /* Get the SPI2/SPI3 clock source ------------------------------------------*/ + PeriphClkInit->Spi23ClockSelection = __HAL_RCC_GET_SPI23_SOURCE(); + /* Get the SPI4/SPI5 clock source ------------------------------------------*/ + PeriphClkInit->Spi45ClockSelection = __HAL_RCC_GET_SPI45_SOURCE(); + /* Get the SPI6 clock source -----------------------------------------------*/ + PeriphClkInit->Spi6ClockSelection = __HAL_RCC_GET_SPI6_SOURCE(); + /* Get the TIM Prescaler configuration -------------------------------------*/ + if ((RCC->CFGR & RCC_CFGR_TIMPRE) == 0U) + { + PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DISABLE; + } + else + { + PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ENABLE; + } + /* Get the USART1 configuration --------------------------------------------*/ + PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); + /* Get the USART2/USART3/UART4/UART5/UART7/UART8 clock source --------------*/ + PeriphClkInit->Usart234578ClockSelection = __HAL_RCC_GET_USART234578_SOURCE(); + /* Get the USBPHYC clock source --------------------------------------------*/ + PeriphClkInit->UsbPhycClockSelection = __HAL_RCC_GET_USBPHYC_SOURCE(); + /* Get the USB OTG FS clock source -----------------------------------------*/ + PeriphClkInit->UsbOtgFsClockSelection = __HAL_RCC_GET_USBOTGFS_SOURCE(); +} + +/** + * @brief Return the peripheral clock frequency for a given peripheral (SAI..) + * @note Return 0 if peripheral clock identifier not managed by this API or + * if the selected clock source is not enabled (HSI, PLLs clock output..) + * @param PeriphClk: Peripheral clock identifier + * This parameter can be one of the following values: + * @arg RCC_PERIPHCLK_FMC : FMC peripheral clock + * @arg RCC_PERIPHCLK_XSPI1 : Xspi1 peripheral clock + * @arg RCC_PERIPHCLK_XSPI2 : Xspi2 peripheral clock + * @arg RCC_PERIPHCLK_CKPER : CKPER peripheral clock + * @arg RCC_PERIPHCLK_ADC : ADC peripheral clock + * @arg RCC_PERIPHCLK_ADF1 : ADF1 peripheral clock + * @arg RCC_PERIPHCLK_CEC : CEC peripheral clock + * @arg RCC_PERIPHCLK_ETH1REF : ETH1REF peripheral clock + * @arg RCC_PERIPHCLK_ETH1PHY : ETH1PHY peripheral clock + * @arg RCC_PERIPHCLK_FDCAN : FDCAN peripheral clock + * @arg RCC_PERIPHCLK_I2C23 : I2C2/I2C3 peripheral clock + * @arg RCC_PERIPHCLK_I2C1_I3C1 : I2C1/I3C1 peripheral clock + * @arg RCC_PERIPHCLK_LPTIM1 : LPTIM1 peripheral clock + * @arg RCC_PERIPHCLK_LPTIM23 : LPTIM23 peripheral clock + * @arg RCC_PERIPHCLK_LPTIM45 : LPTIM45 peripheral clock + * @arg RCC_PERIPHCLK_LPUART1 : LPUART1 peripheral clock + * @arg RCC_PERIPHCLK_LTDC : LTDC peripheral clock + * @arg RCC_PERIPHCLK_PSSI : PSSI peripheral clock + * @arg RCC_PERIPHCLK_RTC : RTC peripheral clock + * @arg RCC_PERIPHCLK_SAI1 : SAI1 peripheral clock + * @arg RCC_PERIPHCLK_SAI2 : SAI2 peripheral clock + * @arg RCC_PERIPHCLK_SDMMC12 : SDMMC12 peripheral clock + * @arg RCC_PERIPHCLK_SPDIFRX : SPDIFRX peripheral clock + * @arg RCC_PERIPHCLK_SPI1 : SPI1 peripheral clock + * @arg RCC_PERIPHCLK_SPI23 : SPI2/SPI3 peripheral clock + * @arg RCC_PERIPHCLK_SPI45 : SPI4/SPI5 peripheral clock + * @arg RCC_PERIPHCLK_SPI6 : SPI6 peripheral clock + * @arg RCC_PERIPHCLK_USART1 : USART1 peripheral clock + * @arg RCC_PERIPHCLK_USART234578 : USART2/3/5/7/8 peripheral clock + * @arg RCC_PERIPHCLK_USBOTGFS : USBOTGFS peripheral clock + * @retval Frequency in KHz + */ +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) +{ + uint32_t frequency = 0; /* Set to 0 for returned value if no source clock */ + uint32_t clocksource; + uint32_t ethclocksource; + uint32_t prescaler; + + switch (PeriphClk) + { + case RCC_PERIPHCLK_FMC: + clocksource = __HAL_RCC_GET_FMC_SOURCE(); + + switch (clocksource) + { + case RCC_FMCCLKSOURCE_HCLK: /* HCLK is the clock source for FMC kernel peripheral clock */ + frequency = HAL_RCC_GetHCLKFreq(); + break; + case RCC_FMCCLKSOURCE_PLL1Q: /* PLL1 'Q' is the clock source for FMC kernel peripheral clock */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_FMCCLKSOURCE_PLL2R: /* PLL2 'R' is the clock source for FMC kernel peripheral clock */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2RFreq(); + } + break; + case RCC_FMCCLKSOURCE_HSI: /* HSI is the clock source for FMC kernel peripheral clock */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_FMCCLKSOURCE_HCLK_DIV4: /* HCLK/4 is the clock source for FMC kernel peripheral clock */ + frequency = (HAL_RCC_GetHCLKFreq() / 4U); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_XSPI1: + clocksource = __HAL_RCC_GET_XSPI1_SOURCE(); + + switch (clocksource) + { + case RCC_XSPI1CLKSOURCE_HCLK: /* HCLK is the clock source for XSPI1 kernel peripheral clock */ + frequency = HAL_RCC_GetHCLKFreq(); + break; + case RCC_XSPI1CLKSOURCE_PLL2S: /* PLL2 'S' is the clock source for XSPI1 kernel peripheral clock */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_SCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2SFreq(); + } + break; + case RCC_XSPI1CLKSOURCE_PLL2T: /* PLL2 'T' is the clock source for XSPI1 kernel peripheral clock */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_TCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2TFreq(); + } + break; + case RCC_XSPI1CLKSOURCE_HCLK_DIV4: /* HCLK/4 is the clock source for XSPI1 kernel peripheral clock */ + frequency = (HAL_RCC_GetHCLKFreq() / 4U); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_XSPI2: + clocksource = __HAL_RCC_GET_XSPI2_SOURCE(); + + switch (clocksource) + { + case RCC_XSPI2CLKSOURCE_HCLK: /* HCLK is the clock source for XSPI2 kernel peripheral clock */ + frequency = HAL_RCC_GetHCLKFreq(); + break; + case RCC_XSPI2CLKSOURCE_PLL2S: /* PLL2 'S' is the clock source for XSPI2 kernel peripheral clock */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_SCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2SFreq(); + } + break; + case RCC_XSPI2CLKSOURCE_PLL2T: /* PLL2 'T' is the clock source for XSPI2 kernel peripheral clock */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_TCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2TFreq(); + } + break; + case RCC_XSPI2CLKSOURCE_HCLK_DIV4: /* HCLK/4 is the clock source for XSPI2 kernel peripheral clock */ + frequency = (HAL_RCC_GetHCLKFreq() / 4U); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_CKPER: + clocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + switch (clocksource) + { + case RCC_CLKPSOURCE_HSI: /* HSI is the clock source for CKPER */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_CLKPSOURCE_CSI: /* CSI is the clock source for CKPER */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_CLKPSOURCE_HSE: /* HSE is the clock source for CKPER */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_ADC: + clocksource = __HAL_RCC_GET_ADC_SOURCE(); + + switch (clocksource) + { + case RCC_ADCCLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for ADC */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_ADCCLKSOURCE_PLL3R: /* PLL3 'R' is the clock source for ADC */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_ADCCLKSOURCE_CLKP: /* CKPER is the clock source for ADC */ + frequency = RCC_GetCLKPFreq(); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_ADF1: + clocksource = __HAL_RCC_GET_ADF1_SOURCE(); + + switch (clocksource) + { + case RCC_ADF1CLKSOURCE_HCLK: /* HCLK is the clock source for ADF1 */ + frequency = HAL_RCC_GetHCLKFreq(); + break; + case RCC_ADF1CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for ADF1 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_ADF1CLKSOURCE_PLL3P: /* PLL3 'P' is the clock source for ADF1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3PFreq(); + } + break; + case RCC_ADF1CLKSOURCE_PIN: /* External I2S_CKIN is used as clock source for ADF1 */ + frequency = EXTERNAL_CLOCK_VALUE; + break; + case RCC_ADF1CLKSOURCE_CSI: /* CSI is the clock source for ADF1 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_ADF1CLKSOURCE_HSI: /* HSI is the clock source for ADF1 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_CEC: + clocksource = __HAL_RCC_GET_CEC_SOURCE(); + + switch (clocksource) + { + case RCC_CECCLKSOURCE_LSE: /* LSE is the clock source for CEC */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + case RCC_CECCLKSOURCE_LSI: /* LSI is the clock source for CEC */ + if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + { + frequency = LSI_VALUE; + } + break; + case RCC_CECCLKSOURCE_CSI: /* CSI is the clock source for CEC */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_ETH1REF: + clocksource = __HAL_RCC_GET_ETH1REF_SOURCE(); + + switch (clocksource) + { + case RCC_ETH1REFCLKSOURCE_PHY: /* PHY is the clock source for ETH1REF */ + /* Can't retrieve this source's frequency, it is by default set to 0 */ + break; + case RCC_ETH1REFCLKSOURCE_HSE: /* HSE is the clock source for ETH1REF */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + case RCC_ETH1REFCLKSOURCE_ETH: /* ETH is the clock source for ETH1REF */ + ethclocksource = __HAL_RCC_GET_ETH1PHY_SOURCE(); + + switch (ethclocksource) + { + case RCC_ETH1PHYCLKSOURCE_HSE: + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + case RCC_ETH1PHYCLKSOURCE_PLL3S: + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_SCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3SFreq(); + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_ETH1PHY: + clocksource = __HAL_RCC_GET_ETH1PHY_SOURCE(); + + switch (clocksource) + { + case RCC_ETH1PHYCLKSOURCE_HSE: + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + case RCC_ETH1PHYCLKSOURCE_PLL3S: + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_SCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3SFreq(); + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_FDCAN: + clocksource = __HAL_RCC_GET_FDCAN_SOURCE(); + + switch (clocksource) + { + case RCC_FDCANCLKSOURCE_HSE: /*!< HSE is the clock source for FDCAN */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + case RCC_FDCANCLKSOURCE_PLL1Q: /*!< PLL1 'Q' ois the clock source for FDCAN */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_FDCANCLKSOURCE_PLL2P: /*!< PLL2 'P' is the clock source for FDCAN */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_I2C23: + clocksource = __HAL_RCC_GET_I2C23_SOURCE(); + + switch (clocksource) + { + case RCC_I2C23CLKSOURCE_PCLK1: /*!< PCLK1 is the clock source for I2C23 */ + frequency = HAL_RCC_GetPCLK1Freq(); + break; + case RCC_I2C23CLKSOURCE_PLL3R: /*!< PLL3R is the clock source for I2C23 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_I2C23CLKSOURCE_HSI: /*!< HSI is the clock source for I2C23 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_I2C23CLKSOURCE_CSI: /*!< CSI is the clock source for I2C23 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_I2C1_I3C1: + clocksource = __HAL_RCC_GET_I2C1_I3C1_SOURCE(); + + switch (clocksource) + { + case RCC_I2C1_I3C1CLKSOURCE_PCLK1: /*!< PCLK1 is the clock source for I2C1/I3C1 */ + frequency = HAL_RCC_GetPCLK1Freq(); + break; + case RCC_I2C1_I3C1CLKSOURCE_PLL3R: /*!< PLL3 'R' is the clock source for I2C1/I3C1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_I2C1_I3C1CLKSOURCE_HSI: /*!< HSI is the clock source for I2C1/I3C1 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_I2C1_I3C1CLKSOURCE_CSI: /*!< CSI is the clock source for I2C1/I3C1 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_LPTIM1: + clocksource = __HAL_RCC_GET_LPTIM1_SOURCE(); + + switch (clocksource) + { + case RCC_LPTIM1CLKSOURCE_PCLK1: /* PCLK1 is the clock source for LPTIM1 */ + frequency = HAL_RCC_GetPCLK1Freq(); + break; + case RCC_LPTIM1CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for LPTIM1 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_LPTIM1CLKSOURCE_PLL3R: /* PLL3 'R' is the clock source for LPTIM1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_LPTIM1CLKSOURCE_LSE: /* LSE is the clock source for LPTIM1 */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + case RCC_LPTIM1CLKSOURCE_LSI: /* LSI is the clock source for LPTIM1 */ + if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + { + frequency = LSI_VALUE; + } + break; + case RCC_LPTIM1CLKSOURCE_CLKP: /* CKPER is the clock source for LPTIM1 */ + frequency = RCC_GetCLKPFreq(); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_LPTIM23: + clocksource = __HAL_RCC_GET_LPTIM23_SOURCE(); + + switch (clocksource) + { + case RCC_LPTIM23CLKSOURCE_PCLK4: /* PCLK4 is the clock source for LPTIM2/LPTIM3 */ + frequency = HAL_RCC_GetPCLK4Freq(); + break; + case RCC_LPTIM23CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for LPTIM2/LPTIM3 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_LPTIM23CLKSOURCE_PLL3R: /* PLL3 'R' is the clock source for LPTIM2/LPTIM3 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_LPTIM23CLKSOURCE_LSE: /* LSE is the clock source for LPTIM2/LPTIM3 */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + case RCC_LPTIM23CLKSOURCE_LSI: /* LSI is the clock source for LPTIM2/LPTIM3 */ + if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + { + frequency = LSI_VALUE; + } + break; + case RCC_LPTIM23CLKSOURCE_CLKP: /* CKPER is the clock source for LPTIM2/LPTIM3 */ + frequency = RCC_GetCLKPFreq(); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_LPTIM45: + clocksource = __HAL_RCC_GET_LPTIM45_SOURCE(); + + switch (clocksource) + { + case RCC_LPTIM45CLKSOURCE_PCLK4: /* PCLK4 is the clock source for LPTIM4/LPTIM5 */ + frequency = HAL_RCC_GetPCLK4Freq(); + break; + case RCC_LPTIM45CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for LPTIM4/LPTIM5 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_LPTIM45CLKSOURCE_PLL3R: /* PLL3 'R' is the clock source for LPTIM4/LPTIM5 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_LPTIM45CLKSOURCE_LSE: /* LSE is the clock source for LPTIM4/LPTIM5 */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + case RCC_LPTIM45CLKSOURCE_LSI: /* LSI is the clock source for LPTIM4/LPTIM5 */ + if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + { + frequency = LSI_VALUE; + } + break; + case RCC_LPTIM45CLKSOURCE_CLKP: /* CKPER is the clock source for LPTIM4/LPTIM5 */ + frequency = RCC_GetCLKPFreq(); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_LPUART1: + clocksource = __HAL_RCC_GET_LPUART1_SOURCE(); + + switch (clocksource) + { + case RCC_LPUART1CLKSOURCE_PCLK4: /*!< PCLK4 is the clock source for LPUART1 */ + frequency = HAL_RCC_GetPCLK4Freq(); + break; + case RCC_LPUART1CLKSOURCE_PLL2Q: /*!< PLL2 'Q' is the clock source for LPUART1 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2QFreq(); + } + break; + case RCC_LPUART1CLKSOURCE_PLL3Q: /*!< PLL3 'Q' is the clock source for LPUART1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + case RCC_LPUART1CLKSOURCE_HSI: /*!< HSI is the clock source for LPUART1 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_LPUART1CLKSOURCE_CSI: /*!< CSI is the clock source for LPUART1 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_LPUART1CLKSOURCE_LSE: /*!< LSE is the clock source for LPUART1 */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_LTDC: + /* Unique PLL3 'R' clock source */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + + case RCC_PERIPHCLK_PSSI: + clocksource = __HAL_RCC_GET_PSSI_SOURCE(); + + switch (clocksource) + { + case RCC_PSSICLKSOURCE_PLL3R: /*!< PLL3 'R' is the clock source for PSSI */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_PSSICLKSOURCE_CLKP: /*!< CLKP is the clock source for PSSI */ + frequency = RCC_GetCLKPFreq(); + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_RTC: + clocksource = __HAL_RCC_GET_RTC_SOURCE(); + + switch (clocksource) + { + case RCC_RTCCLKSOURCE_DISABLE: + /* Nothing to do, frequency is by default set to 0 */ + break; + case RCC_RTCCLKSOURCE_LSE: /*!< LSE is the clock source for RTC */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + case RCC_RTCCLKSOURCE_LSI: /*!< LSI is the clock source for RTC */ + if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + { + frequency = LSI_VALUE; + } + break; + default: + if (READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL) == RCC_BDCR_RTCSEL) /*!< HSE is the clock source for RTC */ + { + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + prescaler = READ_BIT(RCC->CFGR, RCC_CFGR_RTCPRE) >> RCC_CFGR_RTCPRE_Pos; + if (prescaler > 1U) + { + frequency = HSE_VALUE / prescaler; + } + } + } + else + { + /* Nothing to do, frequency is by default set to 0 */ + } + break; + } + break; + + case RCC_PERIPHCLK_SAI1: + clocksource = __HAL_RCC_GET_SAI1_SOURCE(); + + switch (clocksource) + { + case RCC_SAI1CLKSOURCE_PLL1Q: /* PLL1 'Q' is the clock source for SAI1 */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_SAI1CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for SAI1 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_SAI1CLKSOURCE_PLL3P: /* PLL3 'P' is the clock source for SAI1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3PFreq(); + } + break; + case RCC_SAI1CLKSOURCE_CLKP: /* CKPER is the clock source for SAI1 */ + frequency = RCC_GetCLKPFreq(); + break; + case RCC_SAI1CLKSOURCE_PIN: /* External clock is the clock source for SAI1 */ + frequency = EXTERNAL_CLOCK_VALUE; + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_SAI2: + clocksource = __HAL_RCC_GET_SAI2_SOURCE(); + + switch (clocksource) + { + case RCC_SAI2CLKSOURCE_PLL1Q: /* PLL1 'Q' is the clock source for SAI2 */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_SAI2CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for SAI2 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_SAI2CLKSOURCE_PLL3P: /* PLL3 'P' is the clock source for SAI2 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3PFreq(); + } + break; + case RCC_SAI2CLKSOURCE_CLKP: /* CKPER is the clock source for SAI2 */ + frequency = RCC_GetCLKPFreq(); + break; + case RCC_SAI2CLKSOURCE_SPDIF: + /* Can't retrieve this source's frequency, it is by default set to 0 */ + break; + case RCC_SAI2CLKSOURCE_PIN: /* External clock is the clock source for SAI2 */ + frequency = EXTERNAL_CLOCK_VALUE; + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_SDMMC12: /* SDMMC1 and SDMMC2 */ + + clocksource = __HAL_RCC_GET_SDMMC12_SOURCE(); + + if (clocksource == + RCC_SDMMC12CLKSOURCE_PLL2S) /* PLL2 'S' is the clock source for SDMMC1 and SDMMC2 kernel peripheral clock */ + { + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_SCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2SFreq(); + } + } + else /* PLL2 'T' is the clock source for SDMMC1 and SDMMC2 kernel peripheral clock */ + { + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_TCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2TFreq(); + } + } + break; + + case RCC_PERIPHCLK_SPDIFRX: + clocksource = __HAL_RCC_GET_SPDIFRX_SOURCE(); + + switch (clocksource) + { + case RCC_SPDIFRXCLKSOURCE_PLL1Q: /* PLL1 'Q' is the clock source for SPDIFRX */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_SPDIFRXCLKSOURCE_PLL2R: /* PLL2 'R' is the clock source for SPDIFRX */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2RFreq(); + } + break; + case RCC_SPDIFRXCLKSOURCE_PLL3R: /* PLL3 'R' is the clock source for SPDIFRX */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_RCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3RFreq(); + } + break; + case RCC_SPDIFRXCLKSOURCE_HSI: /* HSI is the clock source for SPDIFRX */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_SPI1: + clocksource = __HAL_RCC_GET_SPI1_SOURCE(); + + switch (clocksource) + { + case RCC_SPI1CLKSOURCE_PLL1Q: /* PLL1 'Q' is the clock source for SPI1 */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_SPI1CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for SPI1 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_SPI1CLKSOURCE_PLL3P: /* PLL3 'P' is the clock source for SPI1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3PFreq(); + } + break; + case RCC_SPI1CLKSOURCE_CLKP: /* CKPER is the clock source for SPI1 */ + frequency = RCC_GetCLKPFreq(); + break; + case RCC_SPI1CLKSOURCE_PIN: /* External I2S_CKIN is used as clock source for SPI1 */ + frequency = EXTERNAL_CLOCK_VALUE; + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_SPI23: + clocksource = __HAL_RCC_GET_SPI23_SOURCE(); + + switch (clocksource) + { + case RCC_SPI23CLKSOURCE_PLL1Q: /* PLL1 'Q' is the clock source for SPI2/SPI3 */ + if (__HAL_RCC_GET_PLL1CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL1QFreq(); + } + break; + case RCC_SPI23CLKSOURCE_PLL2P: /* PLL2 'P' is the clock source for SPI2/SPI3 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2PFreq(); + } + break; + case RCC_SPI23CLKSOURCE_PLL3P: /* PLL3 'P' is the clock source for SPI2/SPI3 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_PCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3PFreq(); + } + break; + case RCC_SPI23CLKSOURCE_CLKP: /* CKPER is the clock source for SPI2/SPI3 */ + frequency = RCC_GetCLKPFreq(); + break; + case RCC_SPI23CLKSOURCE_PIN: /* External I2S_CKIN is used as clock source for SPI2/SPI3 */ + frequency = EXTERNAL_CLOCK_VALUE; + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_SPI45: + clocksource = __HAL_RCC_GET_SPI45_SOURCE(); + + switch (clocksource) + { + case RCC_SPI45CLKSOURCE_PCLK2: /* PCLK2 is the clock source for SPI4/SPI5 */ + frequency = HAL_RCC_GetPCLK2Freq(); + break; + case RCC_SPI45CLKSOURCE_PLL2Q: /* PLL2 'Q' is the clock source for SPI4/SPI5 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2QFreq(); + } + break; + case RCC_SPI45CLKSOURCE_PLL3Q: /* PLL3 'Q' is the clock source for SPI4/SPI5 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + case RCC_SPI45CLKSOURCE_HSI: /* HSI is the clock source for SPI4/SPI5 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_SPI45CLKSOURCE_CSI: /* CSI is the clock source for SPI4/SPI5 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_SPI45CLKSOURCE_HSE: /* HSE is the clock source for SPI4/SPI5 */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_SPI6: + clocksource = __HAL_RCC_GET_SPI6_SOURCE(); + + switch (clocksource) + { + case RCC_SPI6CLKSOURCE_PCLK4: /* PCLK4 is the clock source for SPI6 */ + frequency = HAL_RCC_GetPCLK4Freq(); + break; + case RCC_SPI6CLKSOURCE_PLL2Q: /* PLL2 'Q' is the clock source for SPI6 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2QFreq(); + } + break; + case RCC_SPI6CLKSOURCE_PLL3Q: /* PLL3 'Q' is the clock source for SPI6 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + case RCC_SPI6CLKSOURCE_HSI: /* HSI is the clock source for SPI6 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_SPI6CLKSOURCE_CSI: /* CSI is the clock source for SPI6 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_SPI6CLKSOURCE_HSE: /* HSE is the clock source for SPI6 */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_USART1: + clocksource = __HAL_RCC_GET_USART1_SOURCE(); + + switch (clocksource) + { + case RCC_USART1CLKSOURCE_PCLK2: /*!< PCLK2 is the clock source for USART1 */ + frequency = HAL_RCC_GetPCLK2Freq(); + break; + case RCC_USART1CLKSOURCE_PLL2Q: /*!< PLL2 'Q' is the clock source for USART1 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2QFreq(); + } + break; + case RCC_USART1CLKSOURCE_PLL3Q: /*!< PLL3 'Q' is the clock source for USART1 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + case RCC_USART1CLKSOURCE_HSI: /*!< HSI is the clock source for USART1 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_USART1CLKSOURCE_CSI: /*!< CSI is the clock source for USART1 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_USART1CLKSOURCE_LSE: /*!< LSE is the clock source for USART1 */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_USART234578: + clocksource = __HAL_RCC_GET_USART234578_SOURCE(); + + switch (clocksource) + { + case RCC_USART234578CLKSOURCE_PCLK1: /*!< PCLK2 is the clock source for USART234578 */ + frequency = HAL_RCC_GetPCLK1Freq(); + break; + case RCC_USART234578CLKSOURCE_PLL2Q: /*!< PLL2 'Q' is the clock source for USART234578 */ + if (__HAL_RCC_GET_PLL2CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL2QFreq(); + } + break; + case RCC_USART234578CLKSOURCE_PLL3Q: /*!< PLL3 'Q' is the clock source for USART234578 */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + case RCC_USART234578CLKSOURCE_HSI: /*!< HSI is the clock source for USART234578 */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + break; + case RCC_USART234578CLKSOURCE_CSI: /*!< CSI is the clock source for USART234578 */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + break; + case RCC_USART234578CLKSOURCE_LSE: /*!< LSE is the clock source for USART234578 */ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + frequency = LSE_VALUE; + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_USBPHYC: + clocksource = __HAL_RCC_GET_USBPHYC_SOURCE(); + + switch (clocksource) + { + case RCC_USBPHYCCLKSOURCE_HSE: /*!< HSE is the clock source for USBPHYC */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + case RCC_USBPHYCCLKSOURCE_HSE_DIV2: /*!< HSE/2 is the clock source for USBPHYC */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = (HSE_VALUE >> 1UL); + } + break; + case RCC_USBPHYCCLKSOURCE_PLL3Q: /*!< PLL3Q is the clock source for USBPHYC */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + case RCC_PERIPHCLK_USBOTGFS: + clocksource = __HAL_RCC_GET_USBOTGFS_SOURCE(); + + switch (clocksource) + { + case RCC_USBOTGFSCLKSOURCE_HSI48: /*!< HSI48 is the clock source for USBOTGFS */ + if (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U) + { + frequency = HSI48_VALUE; + } + break; + case RCC_USBOTGFSCLKSOURCE_PLL3Q: /*!< PLL3Q is the clock source for USBOTGFS */ + if (__HAL_RCC_GET_PLL3CLKOUT_CONFIG(RCC_PLL_QCLK) != 0U) + { + frequency = HAL_RCC_GetPLL3QFreq(); + } + break; + case RCC_USBOTGFSCLKSOURCE_HSE: /*!< HSE is the clock source for USBOTGFS */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + break; + case RCC_USBOTGFSCLKSOURCE_CLK48: /*!< CLK48 is the clock source for USBOTGFS */ + /* Can't retrieve this source's frequency, it is by default set to 0 */ + break; + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + break; + + default: + /* Nothing to do, frequency is by default set to 0 */ + break; + } + + return frequency; +} + +/** + * @brief Enable clock protection. + * @note When set, this prevents disabling accidentally clock related data. + * @param ProtectClk Clock(s) to enable protection on + * This parameter can be one or a combination of the following + * @arg RCC_CLOCKPROTECT_FMC FMC clock protection + * @arg RCC_CLOCKPROTECT_XSPI XSPIs clock protection + * @retval None + */ +void HAL_RCCEx_EnableClockProtection(uint32_t ProtectClk) +{ + /* Check the parameter */ + assert_param(IS_RCC_CLOCKPROTECTION(ProtectClk)); + + SET_BIT(RCC->CKPROTR, ProtectClk); +} + +/** + * @brief Disable clock protection. + * @param ProtectClk Clock(s) to disable protection on + * This parameter can be one or a combination of the following + * @arg RCC_CLOCKPROTECT_FMC FMC clock protection + * @arg RCC_CLOCKPROTECT_XSPI XSPIs clock protection + * @retval None + */ +void HAL_RCCEx_DisableClockProtection(uint32_t ProtectClk) +{ + /* Check the parameter */ + assert_param(IS_RCC_CLOCKPROTECTION(ProtectClk)); + + CLEAR_BIT(RCC->CKPROTR, ProtectClk); +} + +/** + * @} + */ + +/** @defgroup RCCEx_Exported_Functions_Group2 Extended System Control functions + * @brief Extended Peripheral Control functions + * @{ + */ +/** + * @brief Enables 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(). + * @note Backup domain access should be enabled + * @retval None + */ +void HAL_RCCEx_EnableLSECSS(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; +} + +/** + * @brief Disables the LSE Clock Security System. + * @note LSE Clock Security System can only be disabled after a LSE failure detection. + * @note Backup domain access should be enabled + * @retval None + */ +void HAL_RCCEx_DisableLSECSS(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; + /* Disable LSE CSS IT if any */ + __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS); +} + +/** + * @brief Enable the LSE Clock Security System Interrupt & corresponding EXTI line. + * @note LSE Clock Security System Interrupt is mapped on EXTI line 18 + * @retval None + */ +void HAL_RCCEx_EnableLSECSS_IT(void) +{ + /* Enable LSE CSS */ + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; + + /* Enable LSE CSS IT */ + __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS); + + /* Enable IT on EXTI Line 18 */ + __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE(); + __HAL_RCC_LSECSS_EXTI_ENABLE_IT(); +} + +/** + * @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock + * @param WakeUpClk: Wakeup clock + * This parameter can be one of the following values: + * @arg RCC_STOP_WAKEUPCLOCK_CSI: CSI oscillator selection + * @arg RCC_STOP_WAKEUPCLOCK_HSI: HSI 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_CSI: CSI oscillator selection + * @arg RCC_STOP_KERWAKEUPCLOCK_HSI: HSI 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 Handle the RCC LSE Clock Security System interrupt request. + * @retval None + */ +void HAL_RCCEx_LSECSS_IRQHandler(void) +{ + /* Check RCC LSE CSSF flag */ + if (__HAL_RCC_GET_IT(RCC_IT_LSECSS)) + { + /* Clear RCC LSE CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS); + + /* 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 + */ +} + +/** + * @} + */ + +/** @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 + + (#) 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 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 + */ +} + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup RCC_Private_Functions + * @{ + */ + +/** + * @brief Compute PLL2 VCO output frequency + * @retval Value of PLL2 VCO output frequency + */ +static uint32_t RCC_GetCLKPFreq(void) +{ + uint32_t frequency = 0U; + uint32_t ckpclocksource; + + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (ckpclocksource == RCC_CLKPSOURCE_HSI) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + /* Can't retrieve HSIDIV value */ + } + } + } + else if (ckpclocksource == RCC_CLKPSOURCE_CSI) + { + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + frequency = CSI_VALUE; + } + } + else if (ckpclocksource == RCC_CLKPSOURCE_HSE) + { + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + frequency = HSE_VALUE; + } + } + else + { + /* Nothing to do, case the CKPER is disabled */ + /* frequency is by default set to 0 */ + } + + return frequency; +} +/** + * @} + */ + +/** + * @} + */ +#endif /* HAL_RCC_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c new file mode 100644 index 0000000..491ef2f --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c @@ -0,0 +1,2771 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + ============================================================================== + [..] + 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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) + { + /* A non acknowledge appear during STOP Flag waiting process, a new trial must be performed */ + /* Clear STOP Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + + /* Reset the error code for next trial */ + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + } + else + { + /* A acknowledge appear during STOP Flag waiting process, this mean that device respond to its address */ + + /* 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 + { + /* A non acknowledge is detected, this mean that device not respond to its address, + a new trial must be performed */ + + /* Clear NACK Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); + + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) == HAL_OK) + { + /* Clear STOP Flag, auto generated with autoend*/ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + } + } + + /* Increment Trials */ + SMBUS_Trials++; + } while (SMBUS_Trials < Trials); + + /* Update SMBUS 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; + } + 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); + } + + if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE) + { + /* 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c new file mode 100644 index 0000000..a158cb3 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c @@ -0,0 +1,245 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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 + * + WakeUp Mode Functions + * + FastModePlus 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 + ============================================================================== + ##### SMBUS peripheral Extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the SMBUS interface for STM32H7RSxx + 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c new file mode 100644 index 0000000..d3074fa --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c @@ -0,0 +1,8297 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_HAL_Driver + * @{ + */ + +/** @defgroup TIM TIM + * @brief TIM HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* 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_FLAG(htim, TIM_FLAG_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_FLAG(htim, TIM_FLAG_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_FLAG(htim, TIM_FLAG_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_FLAG(htim, TIM_FLAG_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_FLAG(htim, TIM_FLAG_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)) || \ + ((itflag & (TIM_FLAG_SYSTEM_BREAK)) == (TIM_FLAG_SYSTEM_BREAK))) + { + if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_BREAK | TIM_FLAG_SYSTEM_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_FLAG(htim, TIM_FLAG_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_FLAG(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_FLAG(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_FLAG(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_FLAG(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_FLAG(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_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP)); + 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); + 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_ITR13: + case TIM_CLOCKSOURCE_ITR14: + { + /* 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; + } + 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_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; + } + 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_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 (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 (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); + + /* 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; + } + + /* Disable Update Event (UEV) with Update Generation (UG) + by changing Update Request Source (URS) to avoid Update flag (UIF) */ + SET_BIT(TIMx->CR1, TIM_CR1_URS); + + /* Generate an update event to reload the Prescaler + and the repetition counter (only for advanced timer) value immediately */ + TIMx->EGR = TIM_EGR_UG; + + TIMx->CR1 = tmpcr1; +} + +/** + * @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)); + + /* Disable the Channel 1N: Reset the CC1NE Bit */ + TIMx->CCER &= ~TIM_CCER_CC1NE; + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= OC_Config->OCNPolarity; + } + + 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)); + + /* Disable the Channel 2N: Reset the CC2NE Bit */ + TIMx->CCER &= ~TIM_CCER_CC2NE; + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 4U); + } + + 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)); + + /* Disable the Channel 3N: Reset the CC3NE Bit */ + TIMx->CCER &= ~TIM_CCER_CC3NE; + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 8U); + } + + 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)); + + /* Disable the Channel 4N: Reset the CC4NE Bit */ + TIMx->CCER &= ~TIM_CCER_CC4NE; + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC4NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 12U); + } + + 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_ITR13: + case TIM_TS_ITR14: + { + /* 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; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + /* Disable the Channel 1N: Reset the CC1NE Bit */ + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1)) + { + TIMx->CCER &= ~TIM_CCER_CC1NE; + } + + /* Get the TIMx CCMR1 register value */ + 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; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + /* Disable the Channel 1N: Reset the CC1NE Bit */ + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1)) + { + TIMx->CCER &= ~TIM_CCER_CC1NE; + } + + /* Get the TIMx CCMR1 register value */ + 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; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + /* Disable the Channel 2N: Reset the CC2NE Bit */ + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2)) + { + TIMx->CCER &= ~TIM_CCER_CC2NE; + } + + /* Get the TIMx CCMR1 register value */ + 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; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + /* Disable the Channel 2N: Reset the CC2NE Bit */ + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2)) + { + TIMx->CCER &= ~TIM_CCER_CC2NE; + } + + /* Get the TIMx CCMR1 register value */ + 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; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + /* Disable the Channel 3N: Reset the CC3NE Bit */ + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3)) + { + TIMx->CCER &= ~TIM_CCER_CC3NE; + } + + /* Get the TIMx CCMR2 register value */ + 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; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + /* Disable the Channel 4N: Reset the CC4NE Bit */ + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_4)) + { + TIMx->CCER &= ~TIM_CCER_CC4NE; + } + + /* Get the TIMx CCMR2 register value */ + 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_ITR13: Internal Trigger 13 + * @arg TIM_TS_ITR14: Internal Trigger 14 + * @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 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 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c new file mode 100644 index 0000000..6cc632b --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c @@ -0,0 +1,3351 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) + * + Timer remapping capabilities configuration + * + Timer encoder index configuration + ****************************************************************************** + * @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 + ============================================================================== + ##### 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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_CCxNE_MASK) == (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. +@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_CCxNE_MASK) == (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_ITR13: Internal trigger 13 selected + * @arg TIM_TS_ITR14: Internal trigger 14 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_ITR13: Internal trigger 13 selected + * @arg TIM_TS_ITR14: Internal trigger 14 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_ITR13: Internal trigger 13 selected + * @arg TIM_TS_ITR14: Internal trigger 14 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)); + assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode)); + + /* 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)); + 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)); + assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode)); + + /* 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); + 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 = TIM_AF1_BKINE; + bkin_enable_bitpos = TIM_AF1_BKINE_Pos; + bkin_polarity_mask = TIM_AF1_BKINP; + bkin_polarity_bitpos = TIM_AF1_BKINP_Pos; + break; + } + + 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_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 + * @arg TIM_TIM1_ETR_ADC2_AWD1 TIM1 ETR is connected to ADC2 AWD1 + * @arg TIM_TIM1_ETR_ADC2_AWD2 TIM1 ETR is connected to ADC2 AWD2 + * @arg TIM_TIM1_ETR_ADC2_AWD3 TIM1 ETR is connected to ADC2 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_DCMIPP_HSYNC TIM2 ETR is connected to DCMIPP HSYNC pin + * @arg TIM_TIM2_ETR_LTDC_HSYNC TIM2 ETR is connected to LTDC HSYNC pin + * @arg TIM_TIM2_ETR_SAI1_FSA TIM2_ETR is connected to SAI1 FS_A + * @arg TIM_TIM2_ETR_SAI1_FSB TIM2_ETR is connected to SAI1 FS_B + * @arg TIM_TIM2_ETR_GFXTIM_TE TIM2_ETR is connected to GFXTIM TE + * @arg TIM_TIM2_ETR_DCMIPP_HSYNC TIM2 ETR is connected to DCMIPP HSYNC pin + * @arg TIM_TIM2_ETR_LTDC_HSYNC TIM2 ETR is connected to LTDC HSYNC pin + * @arg TIM_TIM3_ETR_TIM3_ETR TIM3_ETR is connected to TIM3 ETR + * @arg TIM_TIM3_ETR_TIM4_ETR TIM3_ETR is connected to TIM4 ETR + * @arg TIM_TIM3_ETR_TIM5_ETR TIM3_ETR is connected to TIM5 ETR + * @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 not connected to I/O + * @arg TIM_TIM3_ETR_DCMIPP_HSYNC TIM3_ETR is connected to DCMIPP HSYNC + * @arg TIM_TIM3_ETR_LTDC_HSYNC TIM3_ETR is connected to LTDC HSYNC + * @arg TIM_TIM3_ETR_GFXTIM_TE TIM3_ETR is connected to GFXTIM TE + * @arg TIM_TIM3_ETR_DCMIPP_HSYNC TIM3_ETR is connected to DCMIPP VSYNC + * @arg TIM_TIM3_ETR_LTDC_VSYNC TIM3_ETR is connected to LTDC VSYNC + * @arg TIM_TIM3_ETR_TIM2_ETR TIM3_ETR is connected to TIM2 ETR + * @arg TIM_TIM3_ETR_TIM4_ETR TIM3_ETR is connected to TIM4 ETR + * @arg TIM_TIM3_ETR_TIM5_ETR TIM3_ETR is connected to TIM5 ETR + * @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_DCMIPP_HSYNC TIM4_ETR is connected to DCMIPP HSYNC + * @arg TIM_TIM4_ETR_LTDC_HSYNC TIM4_ETR is connected to LTDC HSYNC + * @arg TIM_TIM4_ETR_GFXTIM_TE TIM4_ETR is connected to GFXTIM TE + * @arg TIM_TIM4_ETR_DCMIPP_HSYNC TIM4_ETR is connected to DCMIPP VSYNC + * @arg TIM_TIM4_ETR_LTDC_VSYNC TIM4_ETR is connected to LTDC VSYNC + * @arg TIM_TIM4_ETR_TIM2_ETR TIM4_ETR is connected to TIM2 ETR + * @arg TIM_TIM4_ETR_TIM3_ETR TIM4_ETR is connected to TIM3 ETR + * @arg TIM_TIM4_ETR_TIM5_ETR TIM4_ETR is connected to TIM5 ETR + * @arg TIM_TIM4_ETR_ETH1_PPS TIM4_ETR is connected to ETH1 PPS + * + * For TIM5, the parameter can take one of the following values: + * @arg TIM_TIM5_ETR_GPIO TIM5 ETR is connected to GPIO + * @arg TIM_TIM5_ETR_SAI2_FSA TIM5_ETR is connected to SAI2 FS_A + * @arg TIM_TIM5_ETR_SAI2_FSB TIM5_ETR is connected to SAI2 FS_B + * @arg TIM_TIM5_ETR_DCMIPP_HSYNC TIM5_ETR is connected to DCMIPP HSYNC + * @arg TIM_TIM5_ETR_LTDC_HSYNC TIM5_ETR is connected to LTDC HSYNC + * @arg TIM_TIM5_ETR_GFXTIM_TE TIM5_ETR is connected to GFXTIM TE + * @arg TIM_TIM5_ETR_DCMIPP_HSYNC TIM5_ETR is connected to DCMIPP VSYNC + * @arg TIM_TIM5_ETR_LTDC_VSYNC TIM5_ETR is connected to LTDC VSYNC + * @arg TIM_TIM5_ETR_TIM2_ETR TIM5_ETR is connected to TIM2 ETR + * @arg TIM_TIM5_ETR_TIM3_ETR TIM5_ETR is connected to TIM3 ETR + * @arg TIM_TIM5_ETR_TIM3_ETR TIM5_ETR is connected to TIM4 ETR + * + * @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(htim->Instance, Remap)); + + __HAL_LOCK(htim); + + MODIFY_REG(htim->Instance->AF1, TIM_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 + * @param TISelection parameter of the TIM_TISelectionStruct structure is detailed as follows: + * 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_ETH_PPS: TIM2 TI1 is connected to ETH PPS + * + * 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_ETH_PPS: TIM3 TI1 is connected to ETH PPS + * + * For TIM9, the parameter is one of the following values: + * @arg TIM_TIM9_TI1_GPIO: TIM9 TI1 is connected to GPIO + * @arg TIM_TIM9_TI1_MCO1: TIM9 TI1 is connected to MCO1 + * @arg TIM_TIM9_TI1_MCO2: TIM9 TI1 is connected to MCO2 + * + * 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_SPDIF_FS: TIM12 TI1 is connected to SPDIF FS + * @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 + * @arg TIM_TIM12_TI1_MCO1: TIM12 TI1 is connected to MCO1 + * @arg TIM_TIM12_TI1_MCO2: TIM12 TI1 is connected to MCO2 + * + * For TIM15, the parameter is one of the following values: + * @arg TIM_TIM15_TI1_GPIO: TIM15 TI1 is connected to GPIO + * @arg TIM_TIM15_TI1_TIM2_CH1: TIM15 TI1 is connected to TIM2 CH1 + * @arg TIM_TIM15_TI1_TIM3_CH1: TIM15 TI1 is connected to TIM3 CH1 + * @arg TIM_TIM15_TI1_TIM4_CH1: TIM15 TI1 is connected to TIM4 CH1 + * @arg TIM_TIM15_TI1_MCO1: TIM15 TI1 is connected to MCO1 + * @arg TIM_TIM15_TI1_MCO2: TIM15 TI1 is connected to MCO2 + * @arg TIM_TIM15_TI2_GPIO: TIM15 TI2 is connected to GPIO + * @arg TIM_TIM15_TI2_TIM2_CH2: TIM15 TI2 is connected to TIM2 CH2 + * @arg TIM_TIM15_TI2_TIM3_CH2: TIM15 TI2 is connected to TIM3 CH2 + * @arg TIM_TIM15_TI2_TIM4_CH2: TIM15 TI2 is connected to TIM4 CH2 + * + * 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_RTC_WKUP: TIM16 TI1 is connected to RTC wakeup interrupt + * + * For TIM17, the parameter is one of the following values: + * @arg TIM_TIM17_TI1_GPIO: TIM17 TI1 is connected to GPIO + * @arg TIM_TIM17_TI1_SPDIF_FS: TIM17 TI1 is connected to SPDIF FS + * @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_TIX_INSTANCE(htim->Instance, Channel)); + 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; + 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_BREAK_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_BREAK_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 Commutation 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 Commutation 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 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 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 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 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; + } + 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_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 if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + 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->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 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 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 & 0xFU); /* 0xFU = 15 bits max shift */ + + /* Reset the CCxNE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0xFU)); /* 0xFU = 15 bits max shift */ +} +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart.c new file mode 100644 index 0000000..0882fce --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart.c @@ -0,0 +1,4886 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 ##### + =============================================================================== + [..] + 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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; + } + + if (huart->RxState == HAL_UART_STATE_READY) + { + huart->RxEventCallback = pCallback; + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + 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; + + if (huart->RxState == 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; + } + + 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 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 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() + + (#) Wakeup from Stop mode Callback: + (++) HAL_UARTEx_WakeupCallback() + + (#) 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; + } + + 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++; + } + if ((huart->gState & HAL_UART_STATE_BUSY_TX) == HAL_UART_STATE_BUSY_TX) + { + huart->TxXferCount--; + } + else + { + /* Process was aborted during the transmission */ + return HAL_ERROR; + } + } + + 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; + } + + 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++; + } + if (huart->RxState == HAL_UART_STATE_BUSY_RX) + { + huart->RxXferCount--; + } + else + { + /* Process was aborted during the reception */ + return HAL_ERROR; + } + } + + /* 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; + } + + 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; + + 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)) + { + /* Disable the UART DMA Tx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* 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)) + { + /* Disable the UART DMA Tx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* 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)) + { + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* 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)) + { + /* Disable DMA Tx at UART level */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmatx != NULL) + { + /* UART Tx DMA Abort callback has already been initialised : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) + { + huart->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0U; + } + } + } + + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmarx != NULL) + { + /* UART Rx DMA Abort callback has already been initialised : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + huart->hdmarx->XferAbortCallback = NULL; + abortcplt = 1U; + } + else + { + abortcplt = 0U; + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1U) + { + /* 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)) + { + /* Disable the UART DMA Tx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) + { + /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ + huart->hdmatx->XferAbortCallback(huart->hdmatx); + } + } + else + { + + /* 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 */ + { + /* 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)) + { + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* 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 */ + { + /* 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)) + { + /* Disable the UART DMA Rx request if enabled */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* Call user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + + } + } + else +#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); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the UART CR3 register */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + /* Last bytes received, so no need as the abort is immediate */ + (void)HAL_DMA_Abort(huart->hdmarx); + } + + /* 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) */ + } + else + { + /* If DMA is in Circular mode, Idle event is to be reported to user + even if occurring after a Transfer Complete event from DMA */ + if (nb_remaining_rx_data == huart->RxXferSize) + { + if (huart->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) + { + /* 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); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#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; + UART_ClockSourceTypeDef 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 */ + switch (clocksource) + { + case UART_CLOCKSOURCE_PLL2Q: + pclk = HAL_RCC_GetPLL2QFreq(); + break; + case UART_CLOCKSOURCE_PLL3Q: + pclk = HAL_RCC_GetPLL3QFreq(); + break; + case UART_CLOCKSOURCE_PCLK4: + pclk = HAL_RCC_GetPCLK4Freq(); + break; + case UART_CLOCKSOURCE_HSI: + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) + { + pclk = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)); + } + else + { + pclk = (uint32_t) HSI_VALUE; + } + break; + case UART_CLOCKSOURCE_CSI: + pclk = (uint32_t) CSI_VALUE; + break; + case UART_CLOCKSOURCE_LSE: + pclk = (uint32_t) LSE_VALUE; + break; + default: + pclk = 0U; + ret = HAL_ERROR; + break; + } + + /* If proper clock source reported */ + if (pclk != 0U) + { + /* 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) + { + switch (clocksource) + { + case UART_CLOCKSOURCE_PCLK1: + pclk = HAL_RCC_GetPCLK1Freq(); + break; + case UART_CLOCKSOURCE_PCLK2: + pclk = HAL_RCC_GetPCLK2Freq(); + break; + case UART_CLOCKSOURCE_PLL2Q: + pclk = HAL_RCC_GetPLL2QFreq(); + break; + case UART_CLOCKSOURCE_PLL3Q: + pclk = HAL_RCC_GetPLL3QFreq(); + break; + case UART_CLOCKSOURCE_HSI: + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) + { + pclk = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)); + } + else + { + pclk = (uint32_t) HSI_VALUE; + } + break; + case UART_CLOCKSOURCE_CSI: + pclk = (uint32_t) CSI_VALUE; + break; + case UART_CLOCKSOURCE_LSE: + pclk = (uint32_t) LSE_VALUE; + break; + default: + pclk = 0U; + ret = HAL_ERROR; + break; + } + + /* USARTDIV must be greater than or equal to 0d16 */ + if (pclk != 0U) + { + 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 + { + switch (clocksource) + { + case UART_CLOCKSOURCE_PCLK1: + pclk = HAL_RCC_GetPCLK1Freq(); + break; + case UART_CLOCKSOURCE_PCLK2: + pclk = HAL_RCC_GetPCLK2Freq(); + break; + case UART_CLOCKSOURCE_PLL2Q: + pclk = HAL_RCC_GetPLL2QFreq(); + break; + case UART_CLOCKSOURCE_PLL3Q: + pclk = HAL_RCC_GetPLL3QFreq(); + break; + case UART_CLOCKSOURCE_HSI: + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIV) != 0U) + { + pclk = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> 3U)); + } + else + { + pclk = (uint32_t) HSI_VALUE; + } + break; + case UART_CLOCKSOURCE_CSI: + pclk = (uint32_t) CSI_VALUE; + break; + case UART_CLOCKSOURCE_LSE: + pclk = (uint32_t) LSE_VALUE; + break; + default: + pclk = 0U; + ret = HAL_ERROR; + break; + } + + if (pclk != 0U) + { + /* USARTDIV must be greater than or equal to 0d16 */ + 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) && (Flag != UART_FLAG_TXE) && (Flag != UART_FLAG_TC)) + { + 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) + { + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the UART CR3 register */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Enable the UART Transmit Complete Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + } + /* DMA Circular mode */ + else + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Tx complete callback*/ + huart->TxCpltCallback(huart); +#else + /*Call legacy weak Tx complete callback*/ + HAL_UART_TxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA UART transmit process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Tx Half complete callback*/ + huart->TxHalfCpltCallback(huart); +#else + /*Call legacy weak Tx Half complete callback*/ + HAL_UART_TxHalfCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA UART receive process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + /* Check if DMA in circular mode */ + if (hdma->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); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the UART CR3 register */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } + } + + /* 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) + { + /* Check current nb of data still to be received on DMA side. + DMA Normal mode, remaining nb of data will be 0 + DMA Circular mode, remaining nb of data is reset to RxXferSize */ + uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(hdma); + if (nb_remaining_rx_data < huart->RxXferSize) + { + /* Update nb of remaining data */ + huart->RxXferCount = nb_remaining_rx_data; + } + +#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 */ + } + 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) + { + huart->RxXferCount = huart->RxXferSize / 2U; + + /* Check current nb of data still to be received on DMA side. */ + uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(hdma); + if (nb_remaining_rx_data <= huart->RxXferSize) + { + /* Update nb of remaining data */ + huart->RxXferCount = nb_remaining_rx_data; + } + +#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 */ + } + 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)) + { + 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)) + { + 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); + +#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; + } + } + + /* 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; + } + } + + /* 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); + + /* 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; + + /* 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 */ + } + break; + } + } + + /* 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 */ + } + break; + } + } + + /* 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart_ex.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart_ex.c new file mode 100644 index 0000000..99f4fa8 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart_ex.c @@ -0,0 +1,1040 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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) 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 + ============================================================================== + ##### 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 "stm32h7rsxx_hal.h" + +/** @addtogroup STM32H7RSxx_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 16U + +/* UART TX FIFO depth */ +#define TX_FIFO_DEPTH 16U +/** + * @} + */ + +/* 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 modes 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); + + /* Disable 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. + * @note 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. + * @note 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. + * @note 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/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c new file mode 100644 index 0000000..9c207a1 --- /dev/null +++ b/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c @@ -0,0 +1,3473 @@ +/** + ****************************************************************************** + * @file stm32h7rsxx_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/HSPI 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 + + IO manager configuration + + HIGH-SPEED INTERFACE configuration + ****************************************************************************** + * @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 ##### + =============================================================================== + [..] + *** Initialization *** + ====================== + [..] + As prerequisite, fill in the HAL_XSPI_MspInit() : + (+) Enable OctoSPI/HSPI clocks interface with __HAL_RCC_XSPI_CLK_ENABLE(). + (+) Reset OctoSPI/HSPI Peripheral with __HAL_RCC_XSPI_FORCE_RESET() and __HAL_RCC_XSPI_RELEASE_RESET(). + (+) Enable the clocks for the OctoSPI/HSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE(). + (+) Configure these OctoSPI/HSPI pins in alternate mode using HAL_GPIO_Init(). + (+) If interrupt or DMA mode is used, enable and configure OctoSPI/HSPI global + interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). + (+) If DMA mode is used, enable the clocks for the OctoSPI/HSPI DMA channel + with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(), + link it with OctoSPI/HSPI 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 + (+) 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/HSPI 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. + HAL_XSPI_IsMemoryMapped() can be used to verify whether memory-mapped mode is configured or not. + + *** 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/HSPI 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/HSPI Peripheral. + [..] + HAL_XSPI_GetFifoThreshold() function gives the current of the Fifo's threshold + + *** IO manager configuration functions *** + ========================================== + [..] + HAL_XSPIM_Config() function configures the IO manager for the XSPI instance. + + *** High-speed interface and calibration functions *** + ========================================== + [..] + The purpose of High-speed interface is primary to shift data or data strobe by one quarter of octal + bus clock period, with a correct timing accuracy. DLL must be calibrated versus this clock period. + The calibration process is automatically enabled when one of the three conditions below is met: + (+) The XSPI exits Reset state. + (+) The Prescaler is set. + (+) The configuration of communication is set. + [..] + HAL_XSPI_GetDelayValue() function Get the delay values of the high-speed interface DLLs.. + [..] + HAL_XSPI_SetDelayValue() function Set the delay values of the high-speed interface DLLs.. + + *** 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 "stm32h7rsxx_hal.h" + +#if defined(XSPI) || defined(XSPI1) || defined(XSPI2) + +/** @addtogroup STM32H7RSxx_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 + +#define XSPI_NB_INSTANCE 2U +#define XSPI_IOM_NB_PORTS 2U +#define XSPI_IOM_PORT_MASK 0x1U + +/* 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, const XSPI_RegularCmdTypeDef *pCmd); +static void XSPIM_GetConfig(uint8_t instance_nb, XSPIM_CfgTypeDef *pCfg); +/** + @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_CS_BOUND(hxspi->Init.ChipSelectBoundary)); + assert_param(IS_XSPI_FIFO_THRESHOLD_BYTE(hxspi->Init.FifoThresholdByte)); + assert_param(IS_XSPI_MAXTRAN(hxspi->Init.MaxTran)); + assert_param(IS_XSPI_CSSEL(hxspi->Init.MemorySelect)); + /* 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 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 maximum transfer */ + MODIFY_REG(hxspi->Instance->DCR3, XSPI_DCR3_MAXTRAN, \ + (hxspi->Init.MaxTran << XSPI_DCR3_MAXTRAN_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)); + + if (IS_XSPI_ALL_INSTANCE(hxspi->Instance)) + { + /* The configuration of clock prescaler trigger automatically a calibration process. + So it is necessary to wait the calibration is complete */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout); + if (status != HAL_OK) + { + return status; + } + } + /* Configure Dual Memory mode and CS Selection */ + MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_DMM | XSPI_CR_CSSEL), + (hxspi->Init.MemoryMode | hxspi->Init.MemorySelect)); + + /* Configure sample shifting */ + MODIFY_REG(hxspi->Instance->TCR, (XSPI_TCR_SSHIFT), hxspi->Init.SampleShifting); + + /* 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, const XSPI_RegularCmdTypeDef *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(hxspi->Init.MemoryType, 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)); + + /* 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 BUSY flag is reset to go back in idle state. */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout); + + /* Clear TC flag */ + 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, const XSPI_RegularCmdTypeDef *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(hxspi->Init.MemoryType, 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)); + + /* 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, const XSPI_HyperbusCfgTypeDef *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, const XSPI_HyperbusCmdTypeDef *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)); + assert_param(IS_XSPI_DATA_MODE(hxspi->Init.MemoryType, pCmd->DataMode)); + + /* 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 or 16 lines */ + WRITE_REG(hxspi->Instance->CCR, (pCmd->DQSMode | XSPI_CCR_DDTR | pCmd->DataMode | + pCmd->AddressWidth | XSPI_CCR_ADDTR | XSPI_CCR_ADMODE_2)); + WRITE_REG(hxspi->Instance->WCCR, (pCmd->DQSMode | XSPI_WCCR_DDTR | pCmd->DataMode | + 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, const uint8_t *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 = (uint8_t *)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 *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, const uint8_t *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 = (uint8_t *)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 *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, const uint8_t *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 = (uint8_t *)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 *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, const XSPI_AutoPollingTypeDef *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, const XSPI_AutoPollingTypeDef *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, const XSPI_MemoryMappedTypeDef *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 Check whether the XSPI is configured in Memory-mapped mode or not. + * @param hxspi : XSPI handle + * @retval Status (0: Memory-mapped disabled or XSPI not initialized, 1: Memory-mapped enabled) + */ +uint32_t HAL_XSPI_IsMemoryMapped(XSPI_HandleTypeDef *hxspi) +{ + /* Check the XSPI handle allocation */ + if (hxspi == NULL) + { + return (0UL); + } + /* Check if driver is in Reset state */ + else if (hxspi->State == HAL_XSPI_STATE_RESET) + { + return (0UL); + } + else + { + return ((READ_BIT(hxspi->Instance->CR, XSPI_CR_FMODE) == XSPI_CR_FMODE) ? 1UL : 0UL); + } +} + +/** + * @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 operation, return to the indirect mode. + * @param hxspi : XSPI handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Abort(XSPI_HandleTypeDef *hxspi) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart = HAL_GetTick(); + + /* Check if the state is not in reset state */ + if (hxspi->State != HAL_XSPI_STATE_RESET) + { + /* 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) + { + /* Return to indirect mode */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE); + + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + else + { + /* Return to indirect mode */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE); + + hxspi->State = HAL_XSPI_STATE_READY; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Abort the current operation, return to the indirect mode. (non-blocking function) + * @param hxspi : XSPI handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Abort_IT(XSPI_HandleTypeDef *hxspi) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check if the state is not in reset state */ + if (hxspi->State != HAL_XSPI_STATE_RESET) + { + /* 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); + + /* Return to indirect mode */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE); + } + else + { + /* Return to indirect mode */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_FMODE); + + 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 IO Manager configuration function + * @brief XSPI IO Manager configuration function + * +@verbatim + =============================================================================== + ##### IO Manager configuration function ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Configure the IO manager. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the XSPI IO manager. + * @param hxspi : XSPI handle + * @param pCfg : Pointer to Configuration of the IO Manager for the instance + * @param Timeout : Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPIM_Config(XSPI_HandleTypeDef *hxspi, const XSPIM_CfgTypeDef *pCfg, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + uint8_t index; + uint8_t xspi_enabled = 0U; + + XSPIM_CfgTypeDef IOM_cfg[XSPI_NB_INSTANCE] = {0}; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(Timeout); + + /* Check the parameters of the XSPI IO Manager configuration structure */ + assert_param(IS_XSPIM_NCS_OVR(pCfg->nCSOverride)); + assert_param(IS_XSPIM_IO_PORT(pCfg->IOPort)); + assert_param(IS_XSPIM_REQ2ACKTIME(pCfg->Req2AckTime)); + + /**************** Get current configuration of the instances ****************/ + for (index = 0U; index < XSPI_NB_INSTANCE; index++) + { + XSPIM_GetConfig(index + 1U, &(IOM_cfg[index])); + } + + /********** Disable both XSPI to configure XSPI IO Manager **********/ + if ((XSPI1->CR & XSPI_CR_EN) != 0U) + { + CLEAR_BIT(XSPI1->CR, XSPI_CR_EN); + xspi_enabled |= 0x1U; + } + if ((XSPI2->CR & XSPI_CR_EN) != 0U) + { + CLEAR_BIT(XSPI2->CR, XSPI_CR_EN); + xspi_enabled |= 0x2U; + } + + /***************** Deactivation of previous configuration *****************/ + CLEAR_REG(XSPIM->CR); + + /******************** Activation of new configuration *********************/ + MODIFY_REG(XSPIM->CR, XSPIM_CR_REQ2ACK_TIME, ((pCfg->Req2AckTime - 1U) << XSPIM_CR_REQ2ACK_TIME_Pos)); + + if (hxspi->Instance == XSPI1) + { + IOM_cfg[0].IOPort = pCfg->IOPort ; + if (pCfg->nCSOverride != HAL_XSPI_CSSEL_OVR_DISABLED) + { + MODIFY_REG(XSPIM->CR, (XSPIM_CR_CSSEL_OVR_O1 | XSPIM_CR_CSSEL_OVR_EN), (pCfg->nCSOverride)); + } + else + { + /* Nothing to do */ + } + } + else if (hxspi->Instance == XSPI2) + { + IOM_cfg[1].IOPort = pCfg->IOPort ; + if (pCfg->nCSOverride != HAL_XSPI_CSSEL_OVR_DISABLED) + { + MODIFY_REG(XSPIM->CR, (XSPIM_CR_CSSEL_OVR_O2 | XSPIM_CR_CSSEL_OVR_EN), (pCfg->nCSOverride)); + } + else + { + /* Nothing to do */ + } + } + else + { + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + for (index = 0U; index < (XSPI_NB_INSTANCE - 1U); index++) + { + if (IOM_cfg[index].IOPort == IOM_cfg[index + 1U].IOPort) + { + /*Mux*/ + SET_BIT(XSPIM->CR, XSPIM_CR_MUXEN); + } + else + { + /* Nothing to do */ + } + if (IOM_cfg[0].IOPort == HAL_XSPIM_IOPORT_2) + { + /*Mode*/ + SET_BIT(XSPIM->CR, XSPIM_CR_MODE); + } + else + { + /* Nothing to do */ + } + } + + /******* Re-enable both XSPI after configure XSPI IO Manager ********/ + if ((xspi_enabled & 0x1U) != 0U) + { + SET_BIT(XSPI1->CR, XSPI_CR_EN); + } + if ((xspi_enabled & 0x2U) != 0U) + { + SET_BIT(XSPI2->CR, XSPI_CR_EN); + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup XSPI_Exported_Functions_Group6 High-speed interface and calibration functions + * @brief XSPI high-speed interface and calibration functions + * +@verbatim + =============================================================================== + ##### High-speed interface and calibration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Get the delay values of the high-speed interface DLLs. + (+) Set a delay value for the high-speed interface DLLs. + +@endverbatim + * @{ + */ + +/** + * @brief Get the delay values of the high-speed interface DLLs. + * @param hxspi : XSPI handle + * @param pCfg : Current delay values corresponding to the DelayValueType field. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_GetDelayValue(XSPI_HandleTypeDef *hxspi, XSPI_HSCalTypeDef *pCfg) +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t reg = 0; + + if (IS_XSPI_ALL_INSTANCE(hxspi->Instance)) + { + /* Check the parameter specified in the structure */ + assert_param(IS_XSPI_DELAY_TYPE(pCfg->DelayValueType)); + + switch (pCfg->DelayValueType) + { + case HAL_XSPI_CAL_FULL_CYCLE_DELAY: + reg = hxspi->Instance->CALFCR; + pCfg->MaxCalibration = (reg & XSPI_CALFCR_CALMAX); + break; + case HAL_XSPI_CAL_FEEDBACK_CLK_DELAY: + reg = hxspi->Instance->CALMR; + break; + case HAL_XSPI_CAL_DATA_OUTPUT_DELAY: + reg = hxspi->Instance->CALSOR; + break; + case HAL_XSPI_CAL_DQS_INPUT_DELAY: + reg = hxspi->Instance->CALSIR; + break; + default: + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + break; + } + + if (status == HAL_OK) + { + pCfg->FineCalibrationUnit = (reg & XSPI_CALFCR_FINE); + pCfg->CoarseCalibrationUnit = ((reg & XSPI_CALFCR_COARSE) >> XSPI_CALFCR_COARSE_Pos); + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + + return status; +} + +/** + * @brief Set a delay value for the high-speed interface DLLs. + * @param hxspi : XSPI handle + * @param pCfg : Configuration of delay value specified in DelayValueType field. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_SetDelayValue(XSPI_HandleTypeDef *hxspi, const XSPI_HSCalTypeDef *pCfg) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (IS_XSPI_ALL_INSTANCE(hxspi->Instance)) + { + /* Check the parameter specified in the structure */ + assert_param(IS_XSPI_DELAY_TYPE(pCfg->DelayValueType)); + assert_param(IS_XSPI_FINECAL_VALUE(pCfg->FineCalibrationUnit)); + assert_param(IS_XSPI_COARSECAL_VALUE(pCfg->CoarseCalibrationUnit)); + + /* Check if the state isn't in one of the busy states */ + if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U) + { + switch (pCfg->DelayValueType) + { + case HAL_XSPI_CAL_FEEDBACK_CLK_DELAY: + MODIFY_REG(hxspi->Instance->CALMR, (XSPI_CALMR_COARSE | XSPI_CALMR_FINE), + (pCfg->FineCalibrationUnit | (pCfg->CoarseCalibrationUnit << XSPI_CALMR_COARSE_Pos))); + break; + case HAL_XSPI_CAL_DATA_OUTPUT_DELAY: + MODIFY_REG(hxspi->Instance->CALSOR, (XSPI_CALSOR_COARSE | XSPI_CALSOR_FINE), + (pCfg->FineCalibrationUnit | (pCfg->CoarseCalibrationUnit << XSPI_CALSOR_COARSE_Pos))); + break; + case HAL_XSPI_CAL_DQS_INPUT_DELAY: + MODIFY_REG(hxspi->Instance->CALSIR, (XSPI_CALSIR_COARSE | XSPI_CALSIR_FINE), + (pCfg->FineCalibrationUnit | (pCfg->CoarseCalibrationUnit << XSPI_CALSIR_COARSE_Pos))); + break; + default: + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + break; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + + 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); + + /* 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_READY; + 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, const 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 mode */ + *ccr_reg = pCmd->DQSMode; + + 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); + } + } + + /* Configure SSHIFT register to handle SDR/DTR data transfer */ + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + if (pCmd->DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE) + { + /* Deactivate sample shifting when receiving data in DTR mode (DDTR=1) */ + CLEAR_BIT(hxspi->Instance->TCR, XSPI_TCR_SSHIFT); + } + else if (hxspi->Init.SampleShifting == HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE) + { + /* Configure sample shifting */ + SET_BIT(hxspi->Instance->TCR, XSPI_TCR_SSHIFT); + } + else + { + /* Do nothing */ + } + } + + 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)); + } + /* 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; + + if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) + { + /* Verify if programmed address fit with requirement of Reference Manual 28.5 chapter */ + assert_param(IS_XSPI_PROG_ADDR(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)); + } + + /* 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; + + if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) + { + /* Verify if programmed address fit with requirement of Reference Manual 28.5 chapter */ + assert_param(IS_XSPI_PROG_ADDR(hxspi->Instance->AR, pCmd->Address)); + } + } + else + { + /* ---- Invalid command configuration (no instruction, no address) ---- */ + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + } + + 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); + + /* Verify if programmed data fit with requirement of Reference Manual 28.5 chapter */ + assert_param(IS_XSPI_PROG_DATA(hxspi->Instance->DLR, (pCmd->DataLength - 1U))); + } + } + + return status; +} + +/** + * @brief Get the current IOM configuration for an XSPI instance. + * @param instance_nb : number of the instance + * @param pCfg : configuration of the IO Manager for the instance + * @retval HAL status + */ +static void XSPIM_GetConfig(uint8_t instance_nb, XSPIM_CfgTypeDef *pCfg) +{ + uint32_t mux; + uint32_t mode; + + if (instance_nb == 1U) + { + if ((XSPIM->CR & XSPIM_CR_MODE) == 0U) + { + pCfg->IOPort = HAL_XSPIM_IOPORT_1; + } + else + { + pCfg->IOPort = HAL_XSPIM_IOPORT_2; + } + + if ((XSPIM->CR & XSPIM_CR_CSSEL_OVR_EN) != XSPIM_CR_CSSEL_OVR_EN) + { + pCfg->nCSOverride = HAL_XSPI_CSSEL_OVR_DISABLED; + } + else if ((XSPIM->CR & XSPIM_CR_CSSEL_OVR_O1) == XSPIM_CR_CSSEL_OVR_O1) + { + pCfg->nCSOverride = HAL_XSPI_CSSEL_OVR_NCS2; + } + else + { + pCfg->nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1; + } + } + else + { + mux = (XSPIM->CR & XSPIM_CR_MUXEN); + mode = ((XSPIM->CR & XSPIM_CR_MODE) >> XSPIM_CR_MODE_Pos); + if (mux != mode) + { + pCfg->IOPort = HAL_XSPIM_IOPORT_1; + } + else + { + pCfg->IOPort = HAL_XSPIM_IOPORT_2; + } + if ((XSPIM->CR & XSPIM_CR_CSSEL_OVR_EN) != XSPIM_CR_CSSEL_OVR_EN) + { + pCfg->nCSOverride = HAL_XSPI_CSSEL_OVR_DISABLED; + } + else if ((XSPIM->CR & XSPIM_CR_CSSEL_OVR_O2) == XSPIM_CR_CSSEL_OVR_O2) + { + pCfg->nCSOverride = HAL_XSPI_CSSEL_OVR_NCS2; + } + else + { + pCfg->nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1; + } + } +} +/** + @endcond + */ + +/** + * @} + */ + +#endif /* HAL_XSPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* XSPI || XSPI1 || XSPI2 */ diff --git a/EWARM/Appli/STM32H7S78-DK_Appli.ewd b/EWARM/Appli/STM32H7S78-DK_Appli.ewd new file mode 100644 index 0000000..11fdfd4 --- /dev/null +++ b/EWARM/Appli/STM32H7S78-DK_Appli.ewd @@ -0,0 +1,1534 @@ + + + 3 + + STM32H7S78-DK_Appli + + ARM + + 1 + + C-SPY + 2 + + 32 + 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 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 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\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/EWARM/Appli/STM32H7S78-DK_Appli.ewp b/EWARM/Appli/STM32H7S78-DK_Appli.ewp new file mode 100644 index 0000000..16186a9 --- /dev/null +++ b/EWARM/Appli/STM32H7S78-DK_Appli.ewp @@ -0,0 +1,1307 @@ + + + 3 + + STM32H7S78-DK_Appli + + ARM + + 1 + + General + 3 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 26 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + EWARM + + $PROJ_DIR$\..\startup_stm32h7s7xx.s + + + + User + + Appli + + Core + + $PROJ_DIR$\..\..\Appli\Core\Src\main.c + + + $PROJ_DIR$\..\..\Appli\Core\Src\freertos.c + + + $PROJ_DIR$\..\..\Appli\Core\Src\stm32h7rsxx_it.c + + + $PROJ_DIR$\..\..\Appli\Core\Src\stm32h7rsxx_hal_msp.c + + + $PROJ_DIR$\..\..\Appli\Core\Src\stm32h7rsxx_hal_timebase_tim.c + + + + TouchGFX + + App + + $PROJ_DIR$\..\..\Appli\TouchGFX\App\app_touchgfx.c + + + + target + + generated + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\generated\TouchGFXConfiguration.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\generated\TouchGFXGeneratedHAL.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\generated\STM32DMA.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\generated\OSWrappers.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\generated\HardwareMJPEGDecoder.cpp + + + $PROJ_DIR$/../../Appli/TouchGFX/target/generated/nema_hal.c + + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\CortexMMCUInstrumentation.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\TouchGFXHAL.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\STM32TouchController.cpp + + + $PROJ_DIR$\..\..\Appli\TouchGFX\target\TouchGFXGPIO.cpp + + + + + + + + Drivers + + CMSIS + + $PROJ_DIR$\..\..\Appli\Core\Src\system_stm32h7rsxx.c + + + + STM32H7RSxx_HAL_Driver + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c + + + + + Middlewares + + FreeRTOS + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/croutine.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/list.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/queue.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/tasks.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/timers.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/portable/IAR/ARM_CM4F/port.c + + + $PROJ_DIR$/../../Middlewares/Third_Party/FreeRTOS/Source/portable/IAR/ARM_CM4F/portasm.s + + + + + diff --git a/EWARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.icf b/EWARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.icf new file mode 100644 index 0000000..14f1361 --- /dev/null +++ b/EWARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.icf @@ -0,0 +1,69 @@ +/*###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__ = 0x70000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x70000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x701FFFFF; // 2048 Kbytes for TouchGFX App +define symbol __ICFEDIT_region_RAM_start__ = 0x24000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2406BFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x1000; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_ITCM_start__ = 0x00000000; +define symbol __region_ITCM_end__ = 0x0000FFFF; +define symbol __region_DTCM_start__ = 0x20000000; +define symbol __region_DTCM_end__ = 0x2000FFFF; +define symbol __region_SRAMAHB_start__ = 0x30000000; +define symbol __region_SRAMAHB_end__ = 0x30007FFF; +define symbol __region_BKPSRAM_start__ = 0x38800000; +define symbol __region_BKPSRAM_end__ = 0x38800FFF; +define symbol __region_EXTRAM_start__ = 0x90000000; +define symbol __region_EXTRAM_end__ = 0x91FFFFFF; +define symbol __region_RAM_CMD_start__ = 0x2406C000; +define symbol __region_RAM_CMD_end__ = 0x24071FFF; +define symbol __region_EXTROM_start__ = 0x70200000; +define symbol __region_EXTROM_end__ = 0x77FFFFFF; // 126 Mbytes for TouchGFX demo + +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 region EXTRAM_region = mem:[from __region_EXTRAM_start__ to __region_EXTRAM_end__]; +define region ITCM_region = mem:[from __region_ITCM_start__ to __region_ITCM_end__]; +define region DTCM_region = mem:[from __region_DTCM_start__ to __region_DTCM_end__]; +define region SRAMAHB_region = mem:[from __region_SRAMAHB_start__ to __region_SRAMAHB_end__]; +define region BKPSRAM_region = mem:[from __region_BKPSRAM_start__ to __region_BKPSRAM_end__]; +define region RAM_CMD_region = mem:[from __region_RAM_CMD_start__ to __region_RAM_CMD_end__]; +define region EXTROM_region = mem:[from __region_EXTROM_start__ to __region_EXTROM_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 } + except { + section .Bootloader /* Don't copy Bootloader code */}; + +do not initialize { section .noinit, section TouchGFX_Framebuffer, section Video_RGB_Buffer, section Nemagfx_Stencil_Buffer }; + +define symbol __bootloader_start__ = 0x08000000; + +place at address mem:__bootloader_start__ { section .Bootloader }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite }; +place in DTCM_region { block CSTACK, block HEAP, readwrite object heap_4.o }; +place in RAM_CMD_region { section Nemagfx_Memory_Pool_Buffer }; // This region is set as uncached in MPU Config + +place in EXTRAM_region { first section TouchGFX_Framebuffer + , section Video_RGB_Buffer + , section Nemagfx_Stencil_Buffer }; + +place in EXTROM_region { section TextFlashSection + , section FontFlashSection + , section FontSearchFlashSection + , section ExtFlashSection }; diff --git a/EWARM/Boot/STM32H7S78-DK_Boot.ewd b/EWARM/Boot/STM32H7S78-DK_Boot.ewd new file mode 100644 index 0000000..c0c4b45 --- /dev/null +++ b/EWARM/Boot/STM32H7S78-DK_Boot.ewd @@ -0,0 +1,1534 @@ + + + 3 + + STM32H7S78-DK_Boot + + ARM + + 1 + + C-SPY + 2 + + 32 + 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 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 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\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/EWARM/Boot/STM32H7S78-DK_Boot.ewp b/EWARM/Boot/STM32H7S78-DK_Boot.ewp new file mode 100644 index 0000000..3094249 --- /dev/null +++ b/EWARM/Boot/STM32H7S78-DK_Boot.ewp @@ -0,0 +1,1207 @@ + + + 3 + + STM32H7S78-DK_Boot + + ARM + + 1 + + General + 3 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 26 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + Coder + 0 + + + + + Application + + EWARM + + $PROJ_DIR$\..\startup_stm32h7s7xx.s + + + + User + + Boot + + Core + + $PROJ_DIR$\..\..\Boot\Core\Src\main.c + + + $PROJ_DIR$\..\..\Boot\Core\Src\extmem_manager.c + + + $PROJ_DIR$\..\..\Boot\Core\Src\stm32h7rsxx_it.c + + + $PROJ_DIR$\..\..\Boot\Core\Src\stm32h7rsxx_hal_msp.c + + + + + + + Drivers + + CMSIS + + $PROJ_DIR$\..\..\Boot\Core\Src\system_stm32h7rsxx.c + + + + STM32H7RSxx_HAL_Driver + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + $PROJ_DIR$/../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c + + + + + Middlewares + + STM32_ExtMem_Manager + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c + + + $PROJ_DIR$/../../Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c + + + + + diff --git a/EWARM/Boot/stm32h7s7xx_flash.icf b/EWARM/Boot/stm32h7s7xx_flash.icf new file mode 100644 index 0000000..ab73a5f --- /dev/null +++ b/EWARM/Boot/stm32h7s7xx_flash.icf @@ -0,0 +1,44 @@ +/*###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__ = 0x0800FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x24000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x24071FFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x1000; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_ITCM_start__ = 0x00000000; +define symbol __region_ITCM_end__ = 0x0000FFFF; +define symbol __region_DTCM_start__ = 0x20000000; +define symbol __region_DTCM_end__ = 0x2000FFFF; +define symbol __region_SRAMAHB_start__ = 0x30000000; +define symbol __region_SRAMAHB_end__ = 0x30007FFF; +define symbol __region_BKPSRAM_start__ = 0x38800000; +define symbol __region_BKPSRAM_end__ = 0x38800FFF; + +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 region ITCM_region = mem:[from __region_ITCM_start__ to __region_ITCM_end__]; +define region DTCM_region = mem:[from __region_DTCM_start__ to __region_DTCM_end__]; +define region SRAMAHB_region = mem:[from __region_SRAMAHB_start__ to __region_SRAMAHB_end__]; +define region BKPSRAM_region = mem:[from __region_BKPSRAM_start__ to __region_BKPSRAM_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 }; +place in DTCM_region { block CSTACK, block HEAP }; diff --git a/EWARM/Project.eww b/EWARM/Project.eww new file mode 100644 index 0000000..5de6b5c --- /dev/null +++ b/EWARM/Project.eww @@ -0,0 +1,9 @@ + + + + $WS_DIR$\Boot\STM32H7S78-DK_Boot.ewp + + $WS_DIR$\Appli\STM32H7S78-DK_Appli.ewp + + + diff --git a/EWARM/startup_stm32h7s7xx.s b/EWARM/startup_stm32h7s7xx.s new file mode 100644 index 0000000..ac6b3ad --- /dev/null +++ b/EWARM/startup_stm32h7s7xx.s @@ -0,0 +1,1031 @@ +;******************************************************************************** +;* File Name : startup_stm32h7s7xx.s +;* Author : MCD Application Team +;* Description : STM32H7S7xx 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-M7 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* @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. +;* +;******************************************************************************* +; +; +; 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 PVD_PVM_IRQHandler ; PVD/PVM through EXTI Line detection + DCD 0 ; Reserved + DCD DTS_IRQHandler ; Digital Temperature Sensor + DCD IWDG_IRQHandler ; Internal Watchdog + DCD WWDG_IRQHandler ; Window Watchdog + DCD RCC_IRQHandler ; RCC global interrupts through EXTI Line detection + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD FLASH_IRQHandler ; FLASH interrupts + DCD RAMECC_IRQHandler ; RAMECC interrupts + DCD FPU_IRQHandler ; FPU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TAMP_IRQHandler ; Tamper and TimeStamp interrupts through EXTI Line detection + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD EXTI5_IRQHandler ; EXTI Line5 + DCD EXTI6_IRQHandler ; EXTI Line6 + DCD EXTI7_IRQHandler ; EXTI Line7 + DCD EXTI8_IRQHandler ; EXTI Line8 + DCD EXTI9_IRQHandler ; EXTI Line9 + DCD EXTI10_IRQHandler ; EXTI Line10 + DCD EXTI11_IRQHandler ; EXTI Line11 + DCD EXTI12_IRQHandler ; EXTI Line12 + DCD EXTI13_IRQHandler ; EXTI Line13 + DCD EXTI14_IRQHandler ; EXTI Line14 + DCD EXTI15_IRQHandler ; EXTI Line15 + DCD RTC_IRQHandler ; RTC wakeup and alarm interrupts through EXTI Line detection + DCD SAES_IRQHandler ; SAES + DCD CRYP_IRQHandler ; CRYP + DCD PKA_IRQHandler ; PKA + DCD HASH_IRQHandler ; HASH + DCD RNG_IRQHandler ; RNG + DCD ADC1_2_IRQHandler ; ADC1 & ADC2 + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 + DCD TIM1_BRK_IRQHandler ; TIM1 Break + DCD TIM1_UP_IRQHandler ; TIM1 Update + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD TIM5_IRQHandler ; TIM5 + DCD TIM6_IRQHandler ; TIM6 + DCD TIM7_IRQHandler ; TIM7 + DCD TIM9_IRQHandler ; TIM9 + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD SPI3_IRQHandler ; SPI3 + DCD SPI4_IRQHandler ; SPI4 + DCD SPI5_IRQHandler ; SPI5 + DCD SPI6_IRQHandler ; SPI6 + DCD HPDMA1_Channel0_IRQHandler ; HPDMA1 Channel 0 + DCD HPDMA1_Channel1_IRQHandler ; HPDMA1 Channel 1 + DCD HPDMA1_Channel2_IRQHandler ; HPDMA1 Channel 2 + DCD HPDMA1_Channel3_IRQHandler ; HPDMA1 Channel 3 + DCD HPDMA1_Channel4_IRQHandler ; HPDMA1 Channel 4 + DCD HPDMA1_Channel5_IRQHandler ; HPDMA1 Channel 5 + DCD HPDMA1_Channel6_IRQHandler ; HPDMA1 Channel 6 + DCD HPDMA1_Channel7_IRQHandler ; HPDMA1 Channel 7 + DCD SAI1_A_IRQHandler ; Serial Audio Interface 1 block A + DCD SAI1_B_IRQHandler ; Serial Audio Interface 1 block B + DCD SAI2_A_IRQHandler ; Serial Audio Interface 2 block A + DCD SAI2_B_IRQHandler ; Serial Audio Interface 2 block B + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD I2C3_EV_IRQHandler ; I2C3 Event + DCD I2C3_ER_IRQHandler ; I2C3 Error + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD UART7_IRQHandler ; UART7 + DCD UART8_IRQHandler ; UART8 + DCD I3C1_EV_IRQHandler ; I3C1 Event + DCD I3C1_ER_IRQHandler ; I3C1 Error + DCD OTG_HS_IRQHandler ; USB OTG HS + DCD ETH_IRQHandler ; Ethernet + DCD CORDIC_IRQHandler ; CORDIC + DCD GFXTIM_IRQHandler ; GFXTIM + DCD DCMIPP_IRQHandler ; DCMIPP + DCD LTDC_IRQHandler ; LTDC + DCD LTDC_ER_IRQHandler ; LTDC error + DCD DMA2D_IRQHandler ; DMA2D + DCD JPEG_IRQHandler ; JPEG + DCD GFXMMU_IRQHandler ; GFXMMU + DCD I3C1_WKUP_IRQHandler ; I3C1 wakeup + DCD MCE1_IRQHandler ; MCE1 + DCD MCE2_IRQHandler ; MCE2 + DCD MCE3_IRQHandler ; MCE3 + DCD XSPI1_IRQHandler ; XSPI1 + DCD XSPI2_IRQHandler ; XSPI2 + DCD FMC_IRQHandler ; FMC + DCD SDMMC1_IRQHandler ; SDMMC1 + DCD SDMMC2_IRQHandler ; SDMMC2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD OTG_FS_IRQHandler ; USB OTG FS + DCD TIM12_IRQHandler ; TIM12 + DCD TIM13_IRQHandler ; TIM13 + DCD TIM14_IRQHandler ; TIM14 + DCD TIM15_IRQHandler ; TIM15 + DCD TIM16_IRQHandler ; TIM16 + DCD TIM17_IRQHandler ; TIM17 + DCD LPTIM1_IRQHandler ; LP TIM1 + DCD LPTIM2_IRQHandler ; LP TIM2 + DCD LPTIM3_IRQHandler ; LP TIM3 + DCD LPTIM4_IRQHandler ; LP TIM4 + DCD LPTIM5_IRQHandler ; LP TIM5 + DCD SPDIF_RX_IRQHandler ; SPDIF_RX + DCD MDIOS_IRQHandler ; MDIOS + DCD ADF1_FLT0_IRQHandler ; ADF1 Filter 0 + DCD CRS_IRQHandler ; CRS + DCD UCPD1_IRQHandler ; UCPD1 + DCD CEC_IRQHandler ; HDMI_CEC + DCD PSSI_IRQHandler ; PSSI + DCD LPUART1_IRQHandler ; LP UART1 + DCD WAKEUP_PIN_IRQHandler ; Wake-up pins interrupt + DCD GPDMA1_Channel8_IRQHandler ; GPDMA1 Channel 8 + DCD GPDMA1_Channel9_IRQHandler ; GPDMA1 Channel 9 + DCD GPDMA1_Channel10_IRQHandler ; GPDMA1 Channel 10 + DCD GPDMA1_Channel11_IRQHandler ; GPDMA1 Channel 11 + DCD GPDMA1_Channel12_IRQHandler ; GPDMA1 Channel 12 + DCD GPDMA1_Channel13_IRQHandler ; GPDMA1 Channel 13 + DCD GPDMA1_Channel14_IRQHandler ; GPDMA1 Channel 14 + DCD GPDMA1_Channel15_IRQHandler ; GPDMA1 Channel 15 + DCD HPDMA1_Channel8_IRQHandler ; HPDMA1 Channel 8 + DCD HPDMA1_Channel9_IRQHandler ; HPDMA1 Channel 9 + DCD HPDMA1_Channel10_IRQHandler ; HPDMA1 Channel 10 + DCD HPDMA1_Channel11_IRQHandler ; HPDMA1 Channel 11 + DCD HPDMA1_Channel12_IRQHandler ; HPDMA1 Channel 12 + DCD HPDMA1_Channel13_IRQHandler ; HPDMA1 Channel 13 + DCD HPDMA1_Channel14_IRQHandler ; HPDMA1 Channel 14 + DCD HPDMA1_Channel15_IRQHandler ; HPDMA1 Channel 15 + DCD GPU2D_IRQHandler ; GPU2D + DCD GPU2D_ER_IRQHandler ; GPU2D error + DCD ICACHE_IRQHandler ; ICACHE + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 Interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 Interrupt 1 + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 Interrupt 0 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 Interrupt 1 +__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 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 PVD_PVM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_PVM_IRQHandler + B PVD_PVM_IRQHandler + + PUBWEAK DTS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DTS_IRQHandler + B DTS_IRQHandler + + PUBWEAK IWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IWDG_IRQHandler + B IWDG_IRQHandler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK RAMECC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMECC_IRQHandler + B RAMECC_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK TAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_IRQHandler + B TAMP_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 RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK SAES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAES_IRQHandler + B SAES_IRQHandler + + PUBWEAK CRYP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CRYP_IRQHandler + B CRYP_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK HASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HASH_IRQHandler + B HASH_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK ADC1_2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC1_2_IRQHandler + B ADC1_2_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 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 TIM9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM9_IRQHandler + B TIM9_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 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 HPDMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel0_IRQHandler + B HPDMA1_Channel0_IRQHandler + + PUBWEAK HPDMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel1_IRQHandler + B HPDMA1_Channel1_IRQHandler + + PUBWEAK HPDMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel2_IRQHandler + B HPDMA1_Channel2_IRQHandler + + PUBWEAK HPDMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel3_IRQHandler + B HPDMA1_Channel3_IRQHandler + + PUBWEAK HPDMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel4_IRQHandler + B HPDMA1_Channel4_IRQHandler + + PUBWEAK HPDMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel5_IRQHandler + B HPDMA1_Channel5_IRQHandler + + PUBWEAK HPDMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel6_IRQHandler + B HPDMA1_Channel6_IRQHandler + + PUBWEAK HPDMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel7_IRQHandler + B HPDMA1_Channel7_IRQHandler + + PUBWEAK SAI1_A_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI1_A_IRQHandler + B SAI1_A_IRQHandler + + PUBWEAK SAI1_B_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI1_B_IRQHandler + B SAI1_A_IRQHandler + + PUBWEAK SAI2_A_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI2_A_IRQHandler + B SAI2_A_IRQHandler + + PUBWEAK SAI2_B_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI2_B_IRQHandler + B SAI2_B_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 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 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 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 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 OTG_HS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_HS_IRQHandler + B OTG_HS_IRQHandler + + PUBWEAK ETH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_IRQHandler + B ETH_IRQHandler + + PUBWEAK CORDIC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CORDIC_IRQHandler + B CORDIC_IRQHandler + + PUBWEAK GFXTIM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GFXTIM_IRQHandler + B GFXTIM_IRQHandler + + PUBWEAK DCMIPP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCMIPP_IRQHandler + B DCMIPP_IRQHandler + + PUBWEAK LTDC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LTDC_IRQHandler + B LTDC_IRQHandler + + PUBWEAK LTDC_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LTDC_ER_IRQHandler + B LTDC_ER_IRQHandler + + PUBWEAK DMA2D_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA2D_IRQHandler + B DMA2D_IRQHandler + + PUBWEAK JPEG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +JPEG_IRQHandler + B JPEG_IRQHandler + + PUBWEAK GFXMMU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GFXMMU_IRQHandler + B GFXMMU_IRQHandler + + PUBWEAK I3C1_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_WKUP_IRQHandler + B I3C1_WKUP_IRQHandler + + PUBWEAK MCE1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +MCE1_IRQHandler + B MCE1_IRQHandler + + PUBWEAK MCE2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +MCE2_IRQHandler + B MCE2_IRQHandler + + PUBWEAK MCE3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +MCE3_IRQHandler + B MCE3_IRQHandler + + PUBWEAK XSPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +XSPI1_IRQHandler + B XSPI1_IRQHandler + + PUBWEAK XSPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +XSPI2_IRQHandler + B XSPI2_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK SDMMC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC1_IRQHandler + B SDMMC1_IRQHandler + + PUBWEAK SDMMC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC2_IRQHandler + B SDMMC2_IRQHandler + + PUBWEAK OTG_FS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OTG_FS_IRQHandler + B OTG_FS_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 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 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 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 SPDIF_RX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPDIF_RX_IRQHandler + B SPDIF_RX_IRQHandler + + PUBWEAK MDIOS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +MDIOS_IRQHandler + B MDIOS_IRQHandler + + PUBWEAK ADF1_FLT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADF1_FLT0_IRQHandler + B ADF1_FLT0_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 CEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CEC_IRQHandler + B CEC_IRQHandler + + PUBWEAK PSSI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PSSI_IRQHandler + B PSSI_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK WAKEUP_PIN_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WAKEUP_PIN_IRQHandler + B WAKEUP_PIN_IRQHandler + + PUBWEAK GPDMA1_Channel8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel8_IRQHandler + B GPDMA1_Channel8_IRQHandler + + PUBWEAK GPDMA1_Channel9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel9_IRQHandler + B GPDMA1_Channel9_IRQHandler + + PUBWEAK GPDMA1_Channel10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel10_IRQHandler + B GPDMA1_Channel10_IRQHandler + + PUBWEAK GPDMA1_Channel11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel11_IRQHandler + B GPDMA1_Channel11_IRQHandler + + PUBWEAK GPDMA1_Channel12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel12_IRQHandler + B GPDMA1_Channel12_IRQHandler + + PUBWEAK GPDMA1_Channel13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel13_IRQHandler + B GPDMA1_Channel13_IRQHandler + + PUBWEAK GPDMA1_Channel14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel14_IRQHandler + B GPDMA1_Channel14_IRQHandler + + PUBWEAK GPDMA1_Channel15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel15_IRQHandler + B GPDMA1_Channel15_IRQHandler + + PUBWEAK HPDMA1_Channel8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel8_IRQHandler + B HPDMA1_Channel8_IRQHandler + + PUBWEAK HPDMA1_Channel9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel9_IRQHandler + B HPDMA1_Channel9_IRQHandler + + PUBWEAK HPDMA1_Channel10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel10_IRQHandler + B HPDMA1_Channel10_IRQHandler + + PUBWEAK HPDMA1_Channel11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel11_IRQHandler + B HPDMA1_Channel11_IRQHandler + + PUBWEAK HPDMA1_Channel12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel12_IRQHandler + B HPDMA1_Channel12_IRQHandler + + PUBWEAK HPDMA1_Channel13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel13_IRQHandler + B HPDMA1_Channel13_IRQHandler + + PUBWEAK HPDMA1_Channel14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel14_IRQHandler + B HPDMA1_Channel14_IRQHandler + + PUBWEAK HPDMA1_Channel15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDMA1_Channel15_IRQHandler + B HPDMA1_Channel15_IRQHandler + + PUBWEAK GPU2D_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPU2D_IRQHandler + B GPU2D_IRQHandler + + PUBWEAK GPU2D_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPU2D_ER_IRQHandler + B GPU2D_ER_IRQHandler + + PUBWEAK ICACHE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_IRQHandler + B ICACHE_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 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 + + END diff --git a/MDK-ARM/Appli/STM32H7S78-DK_Appli.uvoptx b/MDK-ARM/Appli/STM32H7S78-DK_Appli.uvoptx new file mode 100644 index 0000000..414cb6b --- /dev/null +++ b/MDK-ARM/Appli/STM32H7S78-DK_Appli.uvoptx @@ -0,0 +1,1281 @@ + + + + 1.0 + +

    ### uVision Project, (C) Keil Software
    + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32H7S78-DK_Appli + 0x4 + ARM-ADS + + 24000000 + + 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 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32H7Rx_64k -FS08000000 -FL010000 -FP0($$Device:STM32H7S7L8HxH$CMSIS\Flash\STM32H7Rx_64k.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O142 -O2254 -SF4000 -C0 -A1 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP") -D00(5BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC10000 -FN1 -FF0MX66UW1G45G_STM32H7S78-DK -FS070000000 -FL08000000 -FP0($$Device:STM32H7S7L8HxH$CMSIS\Flash\MX66UW1G45G_STM32H7S78-DK.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 + + + + + + + + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + ../startup_stm32h7s7xx.s + startup_stm32h7s7xx.s + 0 + 0 + + + + + Application/User/Appli/TouchGFX/target + 0 + 0 + 0 + 0 + + 2 + 2 + 8 + 0 + 0 + 0 + ..\..\Appli\TouchGFX\target\CortexMMCUInstrumentation.cpp + CortexMMCUInstrumentation.cpp + 0 + 0 + + + 2 + 3 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/TouchGFXHAL.cpp + TouchGFXHAL.cpp + 0 + 0 + + + 2 + 4 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/STM32TouchController.cpp + STM32TouchController.cpp + 0 + 0 + + + 2 + 5 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/TouchGFXGPIO.cpp + TouchGFXGPIO.cpp + 0 + 0 + + + + + Application/User/Appli/TouchGFX/target/generated + 0 + 0 + 0 + 0 + + 3 + 6 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp + TouchGFXConfiguration.cpp + 0 + 0 + + + 3 + 7 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp + TouchGFXGeneratedHAL.cpp + 0 + 0 + + + 3 + 8 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/generated/STM32DMA.cpp + STM32DMA.cpp + 0 + 0 + + + 3 + 9 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/generated/OSWrappers.cpp + OSWrappers.cpp + 0 + 0 + + + 3 + 10 + 8 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp + HardwareMJPEGDecoder.cpp + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ../../Appli/TouchGFX/target/generated/nema_hal.c + nema_hal.c + 0 + 0 + + + + + Application/User/Appli/TouchGFX/App + 0 + 0 + 0 + 0 + + 4 + 12 + 1 + 0 + 0 + 0 + ../../Appli/TouchGFX/App/app_touchgfx.c + app_touchgfx.c + 0 + 0 + + + + + Application/User/Appli/Core + 0 + 0 + 0 + 0 + + 5 + 13 + 1 + 0 + 0 + 0 + ../../Appli/Core/Src/main.c + main.c + 0 + 0 + + + 5 + 14 + 1 + 0 + 0 + 0 + ../../Appli/Core/Src/freertos.c + freertos.c + 0 + 0 + + + 5 + 15 + 1 + 0 + 0 + 0 + ../../Appli/Core/Src/stm32h7rsxx_it.c + stm32h7rsxx_it.c + 0 + 0 + + + 5 + 16 + 1 + 0 + 0 + 0 + ../../Appli/Core/Src/stm32h7rsxx_hal_msp.c + stm32h7rsxx_hal_msp.c + 0 + 0 + + + 5 + 17 + 1 + 0 + 0 + 0 + ../../Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c + stm32h7rsxx_hal_timebase_tim.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 6 + 18 + 1 + 0 + 0 + 0 + ../../Appli/Core/Src/system_stm32h7rsxx.c + system_stm32h7rsxx.c + 0 + 0 + + + + + gui + 0 + 0 + 0 + 0 + + 7 + 19 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/gui/src/common/frontendapplication.cpp + FrontendApplication.cpp + 0 + 0 + + + 7 + 20 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/gui/src/model/model.cpp + Model.cpp + 0 + 0 + + + 7 + 21 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/gui/src/screen1_screen/screen1presenter.cpp + Screen1Presenter.cpp + 0 + 0 + + + 7 + 22 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/gui/src/screen1_screen/screen1view.cpp + Screen1View.cpp + 0 + 0 + + + + + generated + 0 + 0 + 0 + 0 + + 8 + 23 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/applicationfontprovider.cpp + ApplicationFontProvider.cpp + 0 + 0 + + + 8 + 24 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/images/src/bitmapdatabase.cpp + BitmapDatabase.cpp + 0 + 0 + + + 8 + 25 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/cachedfont.cpp + CachedFont.cpp + 0 + 0 + + + 8 + 26 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/font_verdana_10_4bpp_0.cpp + Font_verdana_10_4bpp_0.cpp + 0 + 0 + + + 8 + 27 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/font_verdana_20_4bpp_0.cpp + Font_verdana_20_4bpp_0.cpp + 0 + 0 + + + 8 + 28 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/font_verdana_40_4bpp_0.cpp + Font_verdana_40_4bpp_0.cpp + 0 + 0 + + + 8 + 29 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/fontcache.cpp + FontCache.cpp + 0 + 0 + + + 8 + 30 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/gui_generated/src/common/frontendapplicationbase.cpp + FrontendApplicationBase.cpp + 0 + 0 + + + 8 + 31 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/generatedfont.cpp + GeneratedFont.cpp + 0 + 0 + + + 8 + 32 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/kerning_verdana_10_4bpp.cpp + Kerning_verdana_10_4bpp.cpp + 0 + 0 + + + 8 + 33 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/kerning_verdana_20_4bpp.cpp + Kerning_verdana_20_4bpp.cpp + 0 + 0 + + + 8 + 34 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/kerning_verdana_40_4bpp.cpp + Kerning_verdana_40_4bpp.cpp + 0 + 0 + + + 8 + 35 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/texts/src/languagegb.cpp + LanguageGb.cpp + 0 + 0 + + + 8 + 36 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/gui_generated/src/screen1_screen/screen1viewbase.cpp + Screen1ViewBase.cpp + 0 + 0 + + + 8 + 37 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/images/src/svgdatabase.cpp + SVGDatabase.cpp + 0 + 0 + + + 8 + 38 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/table_verdana_10_4bpp.cpp + Table_verdana_10_4bpp.cpp + 0 + 0 + + + 8 + 39 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/table_verdana_20_4bpp.cpp + Table_verdana_20_4bpp.cpp + 0 + 0 + + + 8 + 40 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/table_verdana_40_4bpp.cpp + Table_verdana_40_4bpp.cpp + 0 + 0 + + + 8 + 41 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/texts/src/texts.cpp + Texts.cpp + 0 + 0 + + + 8 + 42 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/texts/src/typedtextdatabase.cpp + TypedTextDatabase.cpp + 0 + 0 + + + 8 + 43 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/unmappeddatafont.cpp + UnmappedDataFont.cpp + 0 + 0 + + + 8 + 44 + 8 + 0 + 0 + 0 + ../../appli/touchgfx/generated/fonts/src/vectorfontrendererbuffers.cpp + VectorFontRendererBuffers.cpp + 0 + 0 + + + + + Lib + 0 + 0 + 0 + 0 + + 9 + 45 + 4 + 0 + 0 + 0 + ../../appli/middlewares/st/touchgfx/lib/core/cortex_m7/Keil6.x/touchgfx_core_wchar16.lib + touchgfx_core_wchar16.lib + 0 + 0 + + + 9 + 46 + 4 + 0 + 0 + 0 + ../../appli/middlewares/st/touchgfx_components/gpu2d/nemagfx/lib/core/cortex_m7/keil6.x/nemagfx_core_release-wchar16.lib + nemagfx_core_release-wchar16.lib + 0 + 0 + + + 9 + 47 + 4 + 0 + 0 + 0 + ../../appli/middlewares/st/touchgfx_components/gpu2d/touchgfxnema/lib/cortex_m7/keil6.x/touchgfxnema_release-wchar16.lib + touchgfxnema_release-wchar16.lib + 0 + 0 + + + + + Drivers/STM32H7RSxx_HAL_Driver + 0 + 0 + 0 + 0 + + 10 + 48 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + stm32h7rsxx_hal_cortex.c + 0 + 0 + + + 10 + 49 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + stm32h7rsxx_hal_rcc.c + 0 + 0 + + + 10 + 50 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + stm32h7rsxx_hal_rcc_ex.c + 0 + 0 + + + 10 + 51 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + stm32h7rsxx_hal_flash.c + 0 + 0 + + + 10 + 52 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + stm32h7rsxx_hal_flash_ex.c + 0 + 0 + + + 10 + 53 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + stm32h7rsxx_hal_gpio.c + 0 + 0 + + + 10 + 54 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + stm32h7rsxx_hal_dma.c + 0 + 0 + + + 10 + 55 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + stm32h7rsxx_hal_dma_ex.c + 0 + 0 + + + 10 + 56 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + stm32h7rsxx_hal_pwr.c + 0 + 0 + + + 10 + 57 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + stm32h7rsxx_hal_pwr_ex.c + 0 + 0 + + + 10 + 58 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + stm32h7rsxx_hal.c + 0 + 0 + + + 10 + 59 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + stm32h7rsxx_hal_exti.c + 0 + 0 + + + 10 + 60 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + stm32h7rsxx_hal_tim.c + 0 + 0 + + + 10 + 61 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + stm32h7rsxx_hal_tim_ex.c + 0 + 0 + + + 10 + 62 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c + stm32h7rsxx_hal_crc.c + 0 + 0 + + + 10 + 63 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c + stm32h7rsxx_hal_crc_ex.c + 0 + 0 + + + 10 + 64 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c + stm32h7rsxx_hal_dma2d.c + 0 + 0 + + + 10 + 65 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c + stm32h7rsxx_hal_gpu2d.c + 0 + 0 + + + 10 + 66 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c + stm32h7rsxx_hal_i2c.c + 0 + 0 + + + 10 + 67 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c + stm32h7rsxx_hal_i2c_ex.c + 0 + 0 + + + 10 + 68 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c + stm32h7rsxx_hal_smbus.c + 0 + 0 + + + 10 + 69 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c + stm32h7rsxx_hal_smbus_ex.c + 0 + 0 + + + 10 + 70 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c + stm32h7rsxx_hal_icache.c + 0 + 0 + + + 10 + 71 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c + stm32h7rsxx_hal_jpeg.c + 0 + 0 + + + 10 + 72 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c + stm32h7rsxx_hal_ltdc.c + 0 + 0 + + + 10 + 73 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c + stm32h7rsxx_hal_ltdc_ex.c + 0 + 0 + + + + + Middlewares/FreeRTOS + 0 + 0 + 0 + 0 + + 11 + 74 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/croutine.c + croutine.c + 0 + 0 + + + 11 + 75 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c + event_groups.c + 0 + 0 + + + 11 + 76 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/list.c + list.c + 0 + 0 + + + 11 + 77 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/queue.c + queue.c + 0 + 0 + + + 11 + 78 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c + stream_buffer.c + 0 + 0 + + + 11 + 79 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/tasks.c + tasks.c + 0 + 0 + + + 11 + 80 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/timers.c + timers.c + 0 + 0 + + + 11 + 81 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c + cmsis_os2.c + 0 + 0 + + + 11 + 82 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c + mpu_wrappers.c + 0 + 0 + + + 11 + 83 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c + heap_4.c + 0 + 0 + + + 11 + 84 + 1 + 0 + 0 + 0 + ../../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c + port.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + + diff --git a/MDK-ARM/Appli/STM32H7S78-DK_Appli.uvprojx b/MDK-ARM/Appli/STM32H7S78-DK_Appli.uvprojx new file mode 100644 index 0000000..e8e122c --- /dev/null +++ b/MDK-ARM/Appli/STM32H7S78-DK_Appli.uvprojx @@ -0,0 +1,2575 @@ + + + 2.1 +
    ### uVision Project, (C) Keil Software
    + + + STM32H7S78-DK_Appli + 0x4 + ARM-ADS + 6140001::V6.14.1::ARMCLANG + 1 + + + STM32H7S7L8HxH + STMicroelectronics + Keil.STM32H7RSxx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000-0x2000FFFF) IRAM2(0x24000000-0x24071BFF) IROM(0x8000000-0x800FFFF) CLOCK(12000000) FPU3(DFPU) CPUTYPE("Cortex-M7") ELITTLE TZ + + + + 0 + + + + + + + + + + + $$Device:STM32H7S7L8HxH$CMSIS\SVD\STM32H7S.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + STM32H7S78-DK_Appli\ + STM32H7S78-DK_Appli + 1 + 0 + 1 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 1 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM7 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM7 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 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-M7" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 3 + 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 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x24000000 + 0x71c00 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 1 + 0 + 5 + 3 + 1 + 1 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32H7S7xx + + ../../Appli/Core/Inc;../../Appli/TouchGFX/App;../../Appli/TouchGFX/target/generated;../../Appli/TouchGFX/target;../../Drivers/STM32H7RSxx_HAL_Driver/Inc;../../Drivers/STM32H7RSxx_HAL_Driver/Inc/Legacy;../../Middlewares/Third_Party/FreeRTOS/Source/include;../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F;../../Drivers/CMSIS/RTOS2/Include;../../Drivers/CMSIS/Device/ST/STM32H7RSxx/Include;../../Drivers/CMSIS/Include;../../appli/middlewares/st/touchgfx/framework/include;../../appli/touchgfx/generated/fonts/include;../../appli/touchgfx/generated/gui_generated/include;../../appli/touchgfx/generated/images/include;../../appli/touchgfx/generated/texts/include;../../appli/touchgfx/generated/videos/include;../../appli/touchgfx/gui/include;../../appli/middlewares/st/touchgfx_components/gpu2d/nemagfx/include;../../appli/middlewares/st/touchgfx_components/gpu2d/touchgfxnema/include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + + + ../Appli/Core/Inc + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + stm32h7rsxx_RAMxspi1_ROMxspi2.sct + + + --diag_suppress L6312,L6314 + + + + + + + + Application/MDK-ARM + + + startup_stm32h7s7xx.s + 2 + ../startup_stm32h7s7xx.s + + + + + Application/User/Appli/TouchGFX/target + + + CortexMMCUInstrumentation.cpp + 8 + ..\..\Appli\TouchGFX\target\CortexMMCUInstrumentation.cpp + + + TouchGFXHAL.cpp + 8 + ../../Appli/TouchGFX/target/TouchGFXHAL.cpp + + + STM32TouchController.cpp + 8 + ../../Appli/TouchGFX/target/STM32TouchController.cpp + + + TouchGFXGPIO.cpp + 8 + ../../Appli/TouchGFX/target/TouchGFXGPIO.cpp + + + + + Application/User/Appli/TouchGFX/target/generated + + + TouchGFXConfiguration.cpp + 8 + ../../Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp + + + TouchGFXGeneratedHAL.cpp + 8 + ../../Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp + + + STM32DMA.cpp + 8 + ../../Appli/TouchGFX/target/generated/STM32DMA.cpp + + + OSWrappers.cpp + 8 + ../../Appli/TouchGFX/target/generated/OSWrappers.cpp + + + HardwareMJPEGDecoder.cpp + 8 + ../../Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp + + + nema_hal.c + 1 + ../../Appli/TouchGFX/target/generated/nema_hal.c + + + + + Application/User/Appli/TouchGFX/App + + + app_touchgfx.c + 1 + ../../Appli/TouchGFX/App/app_touchgfx.c + + + + + Application/User/Appli/Core + + + main.c + 1 + ../../Appli/Core/Src/main.c + + + freertos.c + 1 + ../../Appli/Core/Src/freertos.c + + + stm32h7rsxx_it.c + 1 + ../../Appli/Core/Src/stm32h7rsxx_it.c + + + stm32h7rsxx_hal_msp.c + 1 + ../../Appli/Core/Src/stm32h7rsxx_hal_msp.c + + + stm32h7rsxx_hal_timebase_tim.c + 1 + ../../Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c + + + + + Drivers/CMSIS + + + system_stm32h7rsxx.c + 1 + ../../Appli/Core/Src/system_stm32h7rsxx.c + + + + + gui + + + FrontendApplication.cpp + 8 + ../../appli/touchgfx/gui/src/common/frontendapplication.cpp + + + Model.cpp + 8 + ../../appli/touchgfx/gui/src/model/model.cpp + + + Screen1Presenter.cpp + 8 + ../../appli/touchgfx/gui/src/screen1_screen/screen1presenter.cpp + + + Screen1View.cpp + 8 + ../../appli/touchgfx/gui/src/screen1_screen/screen1view.cpp + + + + + generated + + + ApplicationFontProvider.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/applicationfontprovider.cpp + + + BitmapDatabase.cpp + 8 + ../../appli/touchgfx/generated/images/src/bitmapdatabase.cpp + + + CachedFont.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/cachedfont.cpp + + + Font_verdana_10_4bpp_0.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/font_verdana_10_4bpp_0.cpp + + + Font_verdana_20_4bpp_0.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/font_verdana_20_4bpp_0.cpp + + + Font_verdana_40_4bpp_0.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/font_verdana_40_4bpp_0.cpp + + + FontCache.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/fontcache.cpp + + + FrontendApplicationBase.cpp + 8 + ../../appli/touchgfx/generated/gui_generated/src/common/frontendapplicationbase.cpp + + + GeneratedFont.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/generatedfont.cpp + + + Kerning_verdana_10_4bpp.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/kerning_verdana_10_4bpp.cpp + + + Kerning_verdana_20_4bpp.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/kerning_verdana_20_4bpp.cpp + + + Kerning_verdana_40_4bpp.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/kerning_verdana_40_4bpp.cpp + + + LanguageGb.cpp + 8 + ../../appli/touchgfx/generated/texts/src/languagegb.cpp + + + Screen1ViewBase.cpp + 8 + ../../appli/touchgfx/generated/gui_generated/src/screen1_screen/screen1viewbase.cpp + + + SVGDatabase.cpp + 8 + ../../appli/touchgfx/generated/images/src/svgdatabase.cpp + + + Table_verdana_10_4bpp.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/table_verdana_10_4bpp.cpp + + + Table_verdana_20_4bpp.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/table_verdana_20_4bpp.cpp + + + Table_verdana_40_4bpp.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/table_verdana_40_4bpp.cpp + + + Texts.cpp + 8 + ../../appli/touchgfx/generated/texts/src/texts.cpp + + + TypedTextDatabase.cpp + 8 + ../../appli/touchgfx/generated/texts/src/typedtextdatabase.cpp + + + UnmappedDataFont.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/unmappeddatafont.cpp + + + VectorFontRendererBuffers.cpp + 8 + ../../appli/touchgfx/generated/fonts/src/vectorfontrendererbuffers.cpp + + + + + Lib + + + touchgfx_core_wchar16.lib + 4 + ../../appli/middlewares/st/touchgfx/lib/core/cortex_m7/Keil6.x/touchgfx_core_wchar16.lib + + + nemagfx_core_release-wchar16.lib + 4 + ../../appli/middlewares/st/touchgfx_components/gpu2d/nemagfx/lib/core/cortex_m7/keil6.x/nemagfx_core_release-wchar16.lib + + + touchgfxnema_release-wchar16.lib + 4 + ../../appli/middlewares/st/touchgfx_components/gpu2d/touchgfxnema/lib/cortex_m7/keil6.x/touchgfxnema_release-wchar16.lib + + + + + Drivers/STM32H7RSxx_HAL_Driver + + + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + + + stm32h7rsxx_hal_cortex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_rcc.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_rcc_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_flash.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_flash_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_gpio.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_dma.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_dma_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_pwr.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_pwr_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_exti.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_tim.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_tim_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_crc.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_crc_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_dma2d.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_gpu2d.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_i2c.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_i2c_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_smbus.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_smbus_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_icache.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_jpeg.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_ltdc.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_ltdc_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + Middlewares/FreeRTOS + + + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + + + croutine.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/croutine.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + event_groups.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/event_groups.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + list.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/list.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + queue.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/queue.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stream_buffer.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + tasks.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/tasks.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + timers.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/timers.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + cmsis_os2.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + mpu_wrappers.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + heap_4.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + port.c + 1 + ../../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + ::CMSIS + + + + + + + + + + + + + + + + +
    + diff --git a/MDK-ARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.sct b/MDK-ARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.sct new file mode 100644 index 0000000..38c5f89 --- /dev/null +++ b/MDK-ARM/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.sct @@ -0,0 +1,48 @@ +; ************************************************************* +; *** Scatter-Loading Description File for STM32H7S78-DK *** +; ************************************************************* + +EXTERNAL_FLASH 0x70000000 0x04000000 ; start addr, size +{ + EROM_region 0x70000000 0x200000 + { + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + DTCMRAM_region 0x20000000 0x00010000 + { + *(STACK) + *(HEAP) + heap_4.o (+ZI +RW) + } + + RAM_region 0x24000000 0x0006C000 + { + .ANY (+RW +ZI) + } + + RAM_CMD 0x2406C000 UNINIT 0x00006000 + { + *.o(.bss.Nemagfx_Memory_Pool_Buffer) + } + + EXTRAM 0x90000000 UNINIT 0x02000000 + { + *.o (.bss.TouchGFX_Framebuffer) + *.o (.bss.Nemagfx_Stencil_Buffer) + } +} + +FLASH_GFX 0x70200000 0x07e00000 +{ + FLASH_GFX_Section 0x70200000 0x07e00000 + { + *.o (ExtFlashSection) + *.o (TextFlashSection) + *.o (FontFlashSection) + } +} + diff --git a/MDK-ARM/Appli/stm32h7rsxx_ROMxspi1.sct b/MDK-ARM/Appli/stm32h7rsxx_ROMxspi1.sct new file mode 100644 index 0000000..9531067 --- /dev/null +++ b/MDK-ARM/Appli/stm32h7rsxx_ROMxspi1.sct @@ -0,0 +1,34 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x90000000 0x08000000 { ; load region size_region + ER_ROM 0x90000000 0x08000000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 { ; + } + + RW_DTCM 0x20000000 0x00010000 { ; RW data + *(STACK) + *(HEAP) + } + + RW_SRAMAHB 0x30000000 0x8000 { + } + + RW_BKPSRAM 0x38800000 0x1000 { + } + + RW_RAM 0x24000000 0x00072000-0x400 { + .ANY (+RW +ZI) + } + + RW_NONCACHEABLEBUFFER 0x24072000-0x400 0x400 { + *(noncacheable_buffer) + } +} diff --git a/MDK-ARM/Appli/stm32h7rsxx_ROMxspi1_RAMxspi2.sct b/MDK-ARM/Appli/stm32h7rsxx_ROMxspi1_RAMxspi2.sct new file mode 100644 index 0000000..eb622d2 --- /dev/null +++ b/MDK-ARM/Appli/stm32h7rsxx_ROMxspi1_RAMxspi2.sct @@ -0,0 +1,37 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x90000000 0x08000000 { ; load region size_region + ER_ROM 0x90000000 0x08000000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 { ; + } + + RW_DTCM 0x20000000 0x00010000 { ; RW data + *(STACK) + *(HEAP) + } + + RW_SRAMAHB 0x30000000 0x8000 { + } + + RW_BKPSRAM 0x38800000 0x1000 { + } + + RW_EXTRAM 0x70000000 0x2000000 { + } + + RW_RAM 0x24000000 0x00072000-0x400 { + .ANY (+RW +ZI) + } + + RW_NONCACHEABLEBUFFER 0x24072000-0x400 0x400 { + *(noncacheable_buffer) + } +} diff --git a/MDK-ARM/Appli/stm32h7rsxx_ROMxspi2.sct b/MDK-ARM/Appli/stm32h7rsxx_ROMxspi2.sct new file mode 100644 index 0000000..13b3632 --- /dev/null +++ b/MDK-ARM/Appli/stm32h7rsxx_ROMxspi2.sct @@ -0,0 +1,34 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x70000000 0x08000000 { ; load region size_region + ER_ROM 0x70000000 0x08000000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 { ; + } + + RW_DTCM 0x20000000 0x00010000 { ; RW data + *(STACK) + *(HEAP) + } + + RW_SRAMAHB 0x30000000 0x8000 { + } + + RW_BKPSRAM 0x38800000 0x1000 { + } + + RW_RAM 0x24000000 0x00072000-0x400 { + .ANY (+RW +ZI) + } + + RW_NONCACHEABLEBUFFER 0x24072000-0x400 0x400 { + *(noncacheable_buffer) + } +} diff --git a/MDK-ARM/Appli/stm32h7s7xx_flash.sct b/MDK-ARM/Appli/stm32h7s7xx_flash.sct new file mode 100644 index 0000000..56fd1ae --- /dev/null +++ b/MDK-ARM/Appli/stm32h7s7xx_flash.sct @@ -0,0 +1,34 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x08000000 0x08010000 { ; load region size_region + ER_ROM 0x08000000 0x08010000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 { ; + } + + RW_DTCM 0x20000000 0x00010000 { ; RW data + *(STACK) + *(HEAP) + } + + RW_SRAMAHB 0x30000000 0x8000 { + } + + RW_BKPSRAM 0x38800000 0x1000 { + } + + RW_RAM 0x24000000 0x00072000-0x400 { + .ANY (+RW +ZI) + } + + RW_NONCACHEABLEBUFFER 0x24072000-0x400 0x400 { + *(noncacheable_buffer) + } +} diff --git a/MDK-ARM/Appli/stm32h7s7xx_sram.sct b/MDK-ARM/Appli/stm32h7s7xx_sram.sct new file mode 100644 index 0000000..b0e221c --- /dev/null +++ b/MDK-ARM/Appli/stm32h7s7xx_sram.sct @@ -0,0 +1,34 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x24050000 0x00022000 { ; load region size_region + ER_ROM 0x24050000 0x00022000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 { ; + } + + RW_DTCM 0x20000000 0x00010000 { ; RW data + *(STACK) + *(HEAP) + } + + RW_SRAMAHB 0x30000000 0x8000 { + } + + RW_BKPSRAM 0x38800000 0x1000 { + } + + RW_RAM 0x24000000 0x00050000-0x400 { + .ANY (+RW +ZI) + } + + RW_NONCACHEABLEBUFFER 0x24050000-0x400 0x400 { + *(noncacheable_buffer) + } +} diff --git a/MDK-ARM/Boot/STM32H7S78-DK_Boot.uvoptx b/MDK-ARM/Boot/STM32H7S78-DK_Boot.uvoptx new file mode 100644 index 0000000..3054a1a --- /dev/null +++ b/MDK-ARM/Boot/STM32H7S78-DK_Boot.uvoptx @@ -0,0 +1,585 @@ + + + + 1.0 + +
    ### uVision Project, (C) Keil Software
    + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32H7S78-DK_Boot + 0x4 + ARM-ADS + + 24000000 + + 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 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32H7Rx_64k -FS08000000 -FL010000 -FP0($$Device:STM32H7S7L8HxH$CMSIS\Flash\STM32H7Rx_64k.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U-O142 -O2254 -S0 -C0 -A1 -N00("ARM CoreSight SW-DP") -D00(5BA02477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC10000 -FN1 -FF0STM32H7Rx_64k.FLM -FS08000000 -FL010000 -FP0($$Device:STM32H7S7L8HxH$CMSIS\Flash\STM32H7Rx_64k.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 + + + + + + + + + + + + + Application/MDK-ARM + 0 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + ../startup_stm32h7s7xx.s + startup_stm32h7s7xx.s + 0 + 0 + + + + + Application/User/Boot/Core + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ../../Boot/Core/Src/main.c + main.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ../../Boot/Core/Src/extmem_manager.c + extmem_manager.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ../../Boot/Core/Src/stm32h7rsxx_it.c + stm32h7rsxx_it.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ../../Boot/Core/Src/stm32h7rsxx_hal_msp.c + stm32h7rsxx_hal_msp.c + 0 + 0 + + + + + Drivers/CMSIS + 0 + 0 + 0 + 0 + + 3 + 6 + 1 + 0 + 0 + 0 + ../../Boot/Core/Src/system_stm32h7rsxx.c + system_stm32h7rsxx.c + 0 + 0 + + + + + Drivers/STM32H7RSxx_HAL_Driver + 0 + 0 + 0 + 0 + + 4 + 7 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + stm32h7rsxx_hal_cortex.c + 0 + 0 + + + 4 + 8 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + stm32h7rsxx_hal_rcc.c + 0 + 0 + + + 4 + 9 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + stm32h7rsxx_hal_rcc_ex.c + 0 + 0 + + + 4 + 10 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + stm32h7rsxx_hal_flash.c + 0 + 0 + + + 4 + 11 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + stm32h7rsxx_hal_flash_ex.c + 0 + 0 + + + 4 + 12 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + stm32h7rsxx_hal_gpio.c + 0 + 0 + + + 4 + 13 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + stm32h7rsxx_hal_dma.c + 0 + 0 + + + 4 + 14 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + stm32h7rsxx_hal_dma_ex.c + 0 + 0 + + + 4 + 15 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + stm32h7rsxx_hal_pwr.c + 0 + 0 + + + 4 + 16 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + stm32h7rsxx_hal_pwr_ex.c + 0 + 0 + + + 4 + 17 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + stm32h7rsxx_hal.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + stm32h7rsxx_hal_exti.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c + stm32h7rsxx_hal_xspi.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + stm32h7rsxx_hal_tim.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + stm32h7rsxx_hal_tim_ex.c + 0 + 0 + + + + + Middlewares/STM32_ExtMem_Manager + 0 + 0 + 0 + 0 + + 5 + 22 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c + stm32_extmem.c + 0 + 0 + + + 5 + 23 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c + stm32_boot_xip.c + 0 + 0 + + + 5 + 24 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c + stm32_sal_xspi.c + 0 + 0 + + + 5 + 25 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c + stm32_sal_sd.c + 0 + 0 + + + 5 + 26 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c + stm32_sfdp_data.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c + stm32_sfdp_driver.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c + stm32_psram_driver.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c + stm32_sdcard_driver.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ../../Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c + stm32_user_driver.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
    diff --git a/MDK-ARM/Boot/STM32H7S78-DK_Boot.uvprojx b/MDK-ARM/Boot/STM32H7S78-DK_Boot.uvprojx new file mode 100644 index 0000000..05d9152 --- /dev/null +++ b/MDK-ARM/Boot/STM32H7S78-DK_Boot.uvprojx @@ -0,0 +1,1716 @@ + + + 2.1 +
    ### uVision Project, (C) Keil Software
    + + + STM32H7S78-DK_Boot + 0x4 + ARM-ADS + 6140001::V6.14.1::ARMCLANG + 1 + + + STM32H7S7L8HxH + STMicroelectronics + Keil.STM32H7RSxx_DFP.1.0.0 + https://www.keil.com/pack/ + IRAM(0x20000000-0x2000FFFF) IRAM2(0x24000000-0x24071BFF) IROM(0x8000000-0x800FFFF) CLOCK(12000000) FPU3(DFPU) CPUTYPE("Cortex-M7") ELITTLE TZ + + + + 0 + + + + + + + + + + + $$Device:STM32H7S7L8HxH$CMSIS\SVD\STM32H7S.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + STM32H7S78-DK_Boot\ + STM32H7S78-DK_Boot + 1 + 0 + 1 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 1 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM7 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM7 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 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-M7" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 0 + 0x24000000 + 0x71c00 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 1 + 0 + 5 + 3 + 1 + 1 + 0 + 0 + 0 + + + USE_HAL_DRIVER,STM32H7S7xx + + ../../Boot/Core/Inc;../../Drivers/STM32H7RSxx_HAL_Driver/Inc;../../Drivers/STM32H7RSxx_HAL_Driver/Inc/Legacy;../../Middlewares/ST/STM32_ExtMem_Manager;../../Middlewares/ST/STM32_ExtMem_Manager/boot;../../Middlewares/ST/STM32_ExtMem_Manager/sal;../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp;../../Middlewares/ST/STM32_ExtMem_Manager/psram;../../Middlewares/ST/STM32_ExtMem_Manager/sdcard;../../Middlewares/ST/STM32_ExtMem_Manager/user;../../Drivers/CMSIS/Device/ST/STM32H7RSxx/Include;../../Drivers/CMSIS/Include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + + + ../Boot/Core/Inc + + + + 0 + 0 + 0 + 0 + 1 + 0 + + + + stm32h7s7xx_flash.sct + + + --diag_suppress L6312,L6314 + + + + + + + + Application/MDK-ARM + + + startup_stm32h7s7xx.s + 2 + ../startup_stm32h7s7xx.s + + + + + Application/User/Boot/Core + + + main.c + 1 + ../../Boot/Core/Src/main.c + + + extmem_manager.c + 1 + ../../Boot/Core/Src/extmem_manager.c + + + stm32h7rsxx_it.c + 1 + ../../Boot/Core/Src/stm32h7rsxx_it.c + + + stm32h7rsxx_hal_msp.c + 1 + ../../Boot/Core/Src/stm32h7rsxx_hal_msp.c + + + + + Drivers/CMSIS + + + system_stm32h7rsxx.c + 1 + ../../Boot/Core/Src/system_stm32h7rsxx.c + + + + + Drivers/STM32H7RSxx_HAL_Driver + + + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + + + stm32h7rsxx_hal_tim.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_tim_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_cortex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_rcc.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_rcc_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_flash.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_flash_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_gpio.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_dma.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_dma_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_pwr.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_pwr_ex.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_exti.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32h7rsxx_hal_xspi.c + 1 + ../../Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + Middlewares/STM32_ExtMem_Manager + + + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + + + + + + stm32_extmem.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_boot_xip.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_sal_xspi.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_sal_sd.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_sfdp_data.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_sfdp_driver.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_psram_driver.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_sdcard_driver.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + stm32_user_driver.c + 1 + ../../Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + ::CMSIS + + + + + + + + + + + + + + + + +
    + diff --git a/MDK-ARM/Boot/stm32h7s7xx_flash.sct b/MDK-ARM/Boot/stm32h7s7xx_flash.sct new file mode 100644 index 0000000..26fd46b --- /dev/null +++ b/MDK-ARM/Boot/stm32h7s7xx_flash.sct @@ -0,0 +1,39 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x08000000 0x08010000 ; load region size_region +{ + ER_ROM 0x08000000 0x08010000 ; load address = execution address + { + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 + { + } + + RW_DTCM 0x20000000 0x00010000 ; RW data + { + *(STACK, +RW) + *(HEAP, +RW) + } + + RW_SRAMAHB 0x30000000 0x8000 + { + .ANY (+RO) + .ANY (+XO) + } + + RW_BKPSRAM 0x38800000 0x1000 + { + } + + RW_RAM 0x24000000 0x00072000 + { + .ANY (+RW +ZI) + } +} diff --git a/MDK-ARM/Boot/stm32h7s7xx_sram.sct b/MDK-ARM/Boot/stm32h7s7xx_sram.sct new file mode 100644 index 0000000..b0e221c --- /dev/null +++ b/MDK-ARM/Boot/stm32h7s7xx_sram.sct @@ -0,0 +1,34 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LOAD_FLASH 0x24050000 0x00022000 { ; load region size_region + ER_ROM 0x24050000 0x00022000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + ER_ITCM 0x00000000 0x00010000 { ; + } + + RW_DTCM 0x20000000 0x00010000 { ; RW data + *(STACK) + *(HEAP) + } + + RW_SRAMAHB 0x30000000 0x8000 { + } + + RW_BKPSRAM 0x38800000 0x1000 { + } + + RW_RAM 0x24000000 0x00050000-0x400 { + .ANY (+RW +ZI) + } + + RW_NONCACHEABLEBUFFER 0x24050000-0x400 0x400 { + *(noncacheable_buffer) + } +} diff --git a/MDK-ARM/Project.uvmpw b/MDK-ARM/Project.uvmpw new file mode 100644 index 0000000..11dca12 --- /dev/null +++ b/MDK-ARM/Project.uvmpw @@ -0,0 +1,23 @@ + + + + 1.0 + +
    ### uVision Project, (C) Keil Software
    + + + + + .\Boot\STM32H7S78-DK_Boot.uvprojx + 1 + 1 + + + + .\Appli\STM32H7S78-DK_Appli.uvprojx + 1 + 1 + 1 + + +
    diff --git a/MDK-ARM/startup_stm32h7s7xx.s b/MDK-ARM/startup_stm32h7s7xx.s new file mode 100644 index 0000000..f80c8e9 --- /dev/null +++ b/MDK-ARM/startup_stm32h7s7xx.s @@ -0,0 +1,633 @@ +;******************************************************************************* +;* File Name : startup_stm32h7s7xx.s +;* Author : MCD Application Team +;* Description : STM32H7S7xx 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-M7 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 0x1000 + + 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 0x1000 + + 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 PVD_PVM_IRQHandler ; PVD/PVM through EXTI Line detection + DCD 0 ; Reserved + DCD DTS_IRQHandler ; Digital Temperature Sensor + DCD IWDG_IRQHandler ; Internal Watchdog + DCD WWDG_IRQHandler ; Window Watchdog + DCD RCC_IRQHandler ; RCC global interrupts through EXTI Line detection + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD FLASH_IRQHandler ; FLASH interrupts + DCD RAMECC_IRQHandler ; RAMECC interrupts + DCD FPU_IRQHandler ; FPU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TAMP_IRQHandler ; Tamper and TimeStamp interrupts through EXTI Line detection + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD EXTI0_IRQHandler ; EXTI Line0 + DCD EXTI1_IRQHandler ; EXTI Line1 + DCD EXTI2_IRQHandler ; EXTI Line2 + DCD EXTI3_IRQHandler ; EXTI Line3 + DCD EXTI4_IRQHandler ; EXTI Line4 + DCD EXTI5_IRQHandler ; EXTI Line5 + DCD EXTI6_IRQHandler ; EXTI Line6 + DCD EXTI7_IRQHandler ; EXTI Line7 + DCD EXTI8_IRQHandler ; EXTI Line8 + DCD EXTI9_IRQHandler ; EXTI Line9 + DCD EXTI10_IRQHandler ; EXTI Line10 + DCD EXTI11_IRQHandler ; EXTI Line11 + DCD EXTI12_IRQHandler ; EXTI Line12 + DCD EXTI13_IRQHandler ; EXTI Line13 + DCD EXTI14_IRQHandler ; EXTI Line14 + DCD EXTI15_IRQHandler ; EXTI Line15 + DCD RTC_IRQHandler ; RTC wakeup and alarm interrupts through EXTI Line detection + DCD SAES_IRQHandler ; SAES + DCD CRYP_IRQHandler ; CRYP + DCD PKA_IRQHandler ; PKA + DCD HASH_IRQHandler ; HASH + DCD RNG_IRQHandler ; RNG + DCD ADC1_2_IRQHandler ; ADC1 & ADC2 + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 + DCD TIM1_BRK_IRQHandler ; TIM1 Break + DCD TIM1_UP_IRQHandler ; TIM1 Update + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare + DCD TIM2_IRQHandler ; TIM2 + DCD TIM3_IRQHandler ; TIM3 + DCD TIM4_IRQHandler ; TIM4 + DCD TIM5_IRQHandler ; TIM5 + DCD TIM6_IRQHandler ; TIM6 + DCD TIM7_IRQHandler ; TIM7 + DCD TIM9_IRQHandler ; TIM9 + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD SPI3_IRQHandler ; SPI3 + DCD SPI4_IRQHandler ; SPI4 + DCD SPI5_IRQHandler ; SPI5 + DCD SPI6_IRQHandler ; SPI6 + DCD HPDMA1_Channel0_IRQHandler ; HPDMA1 Channel 0 + DCD HPDMA1_Channel1_IRQHandler ; HPDMA1 Channel 1 + DCD HPDMA1_Channel2_IRQHandler ; HPDMA1 Channel 2 + DCD HPDMA1_Channel3_IRQHandler ; HPDMA1 Channel 3 + DCD HPDMA1_Channel4_IRQHandler ; HPDMA1 Channel 4 + DCD HPDMA1_Channel5_IRQHandler ; HPDMA1 Channel 5 + DCD HPDMA1_Channel6_IRQHandler ; HPDMA1 Channel 6 + DCD HPDMA1_Channel7_IRQHandler ; HPDMA1 Channel 7 + DCD SAI1_A_IRQHandler ; Serial Audio Interface 1 block A + DCD SAI1_B_IRQHandler ; Serial Audio Interface 1 block B + DCD SAI2_A_IRQHandler ; Serial Audio Interface 2 block A + DCD SAI2_B_IRQHandler ; Serial Audio Interface 2 block B + DCD I2C1_EV_IRQHandler ; I2C1 Event + DCD I2C1_ER_IRQHandler ; I2C1 Error + DCD I2C2_EV_IRQHandler ; I2C2 Event + DCD I2C2_ER_IRQHandler ; I2C2 Error + DCD I2C3_EV_IRQHandler ; I2C3 Event + DCD I2C3_ER_IRQHandler ; I2C3 Error + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART3_IRQHandler ; USART3 + DCD UART4_IRQHandler ; UART4 + DCD UART5_IRQHandler ; UART5 + DCD UART7_IRQHandler ; UART7 + DCD UART8_IRQHandler ; UART8 + DCD I3C1_EV_IRQHandler ; I3C1 Event + DCD I3C1_ER_IRQHandler ; I3C1 Error + DCD OTG_HS_IRQHandler ; USB OTG HS + DCD ETH_IRQHandler ; Ethernet + DCD CORDIC_IRQHandler ; CORDIC + DCD GFXTIM_IRQHandler ; GFXTIM + DCD DCMIPP_IRQHandler ; DCMIPP + DCD LTDC_IRQHandler ; LTDC + DCD LTDC_ER_IRQHandler ; LTDC error + DCD DMA2D_IRQHandler ; DMA2D + DCD JPEG_IRQHandler ; JPEG + DCD GFXMMU_IRQHandler ; GFXMMU + DCD I3C1_WKUP_IRQHandler ; I3C1 wakeup + DCD MCE1_IRQHandler ; MCE1 + DCD MCE2_IRQHandler ; MCE2 + DCD MCE3_IRQHandler ; MCE3 + DCD XSPI1_IRQHandler ; XSPI1 + DCD XSPI2_IRQHandler ; XSPI2 + DCD FMC_IRQHandler ; FMC + DCD SDMMC1_IRQHandler ; SDMMC1 + DCD SDMMC2_IRQHandler ; SDMMC2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD OTG_FS_IRQHandler ; USB OTG FS + DCD TIM12_IRQHandler ; TIM12 + DCD TIM13_IRQHandler ; TIM13 + DCD TIM14_IRQHandler ; TIM14 + DCD TIM15_IRQHandler ; TIM15 + DCD TIM16_IRQHandler ; TIM16 + DCD TIM17_IRQHandler ; TIM17 + DCD LPTIM1_IRQHandler ; LP TIM1 + DCD LPTIM2_IRQHandler ; LP TIM2 + DCD LPTIM3_IRQHandler ; LP TIM3 + DCD LPTIM4_IRQHandler ; LP TIM4 + DCD LPTIM5_IRQHandler ; LP TIM5 + DCD SPDIF_RX_IRQHandler ; SPDIF_RX + DCD MDIOS_IRQHandler ; MDIOS + DCD ADF1_FLT0_IRQHandler ; ADF1 Filter 0 + DCD CRS_IRQHandler ; CRS + DCD UCPD1_IRQHandler ; UCPD1 + DCD CEC_IRQHandler ; HDMI_CEC + DCD PSSI_IRQHandler ; PSSI + DCD LPUART1_IRQHandler ; LP UART1 + DCD WAKEUP_PIN_IRQHandler ; Wake-up pins interrupt + DCD GPDMA1_Channel8_IRQHandler ; GPDMA1 Channel 8 + DCD GPDMA1_Channel9_IRQHandler ; GPDMA1 Channel 9 + DCD GPDMA1_Channel10_IRQHandler ; GPDMA1 Channel 10 + DCD GPDMA1_Channel11_IRQHandler ; GPDMA1 Channel 11 + DCD GPDMA1_Channel12_IRQHandler ; GPDMA1 Channel 12 + DCD GPDMA1_Channel13_IRQHandler ; GPDMA1 Channel 13 + DCD GPDMA1_Channel14_IRQHandler ; GPDMA1 Channel 14 + DCD GPDMA1_Channel15_IRQHandler ; GPDMA1 Channel 15 + DCD HPDMA1_Channel8_IRQHandler ; HPDMA1 Channel 8 + DCD HPDMA1_Channel9_IRQHandler ; HPDMA1 Channel 9 + DCD HPDMA1_Channel10_IRQHandler ; HPDMA1 Channel 10 + DCD HPDMA1_Channel11_IRQHandler ; HPDMA1 Channel 11 + DCD HPDMA1_Channel12_IRQHandler ; HPDMA1 Channel 12 + DCD HPDMA1_Channel13_IRQHandler ; HPDMA1 Channel 13 + DCD HPDMA1_Channel14_IRQHandler ; HPDMA1 Channel 14 + DCD HPDMA1_Channel15_IRQHandler ; HPDMA1 Channel 15 + DCD GPU2D_IRQHandler ; GPU2D + DCD GPU2D_ER_IRQHandler ; GPU2D error + DCD ICACHE_IRQHandler ; ICACHE + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 Interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 Interrupt 1 + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 Interrupt 0 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 Interrupt 1 + + +__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 +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 PVD_PVM_IRQHandler [WEAK] + EXPORT DTS_IRQHandler [WEAK] + EXPORT IWDG_IRQHandler [WEAK] + EXPORT WWDG_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT RAMECC_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT TAMP_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 RTC_IRQHandler [WEAK] + EXPORT SAES_IRQHandler [WEAK] + EXPORT CRYP_IRQHandler [WEAK] + EXPORT PKA_IRQHandler [WEAK] + EXPORT HASH_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT ADC1_2_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 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 TIM9_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT SPI6_IRQHandler [WEAK] + EXPORT HPDMA1_Channel0_IRQHandler [WEAK] + EXPORT HPDMA1_Channel1_IRQHandler [WEAK] + EXPORT HPDMA1_Channel2_IRQHandler [WEAK] + EXPORT HPDMA1_Channel3_IRQHandler [WEAK] + EXPORT HPDMA1_Channel4_IRQHandler [WEAK] + EXPORT HPDMA1_Channel5_IRQHandler [WEAK] + EXPORT HPDMA1_Channel6_IRQHandler [WEAK] + EXPORT HPDMA1_Channel7_IRQHandler [WEAK] + EXPORT SAI1_A_IRQHandler [WEAK] + EXPORT SAI1_B_IRQHandler [WEAK] + EXPORT SAI2_A_IRQHandler [WEAK] + EXPORT SAI2_B_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT UART8_IRQHandler [WEAK] + EXPORT I3C1_EV_IRQHandler [WEAK] + EXPORT I3C1_ER_IRQHandler [WEAK] + EXPORT OTG_HS_IRQHandler [WEAK] + EXPORT ETH_IRQHandler [WEAK] + EXPORT CORDIC_IRQHandler [WEAK] + EXPORT GFXTIM_IRQHandler [WEAK] + EXPORT DCMIPP_IRQHandler [WEAK] + EXPORT LTDC_IRQHandler [WEAK] + EXPORT LTDC_ER_IRQHandler [WEAK] + EXPORT DMA2D_IRQHandler [WEAK] + EXPORT JPEG_IRQHandler [WEAK] + EXPORT GFXMMU_IRQHandler [WEAK] + EXPORT I3C1_WKUP_IRQHandler [WEAK] + EXPORT MCE1_IRQHandler [WEAK] + EXPORT MCE2_IRQHandler [WEAK] + EXPORT MCE3_IRQHandler [WEAK] + EXPORT XSPI1_IRQHandler [WEAK] + EXPORT XSPI2_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT SDMMC2_IRQHandler [WEAK] + EXPORT OTG_FS_IRQHandler [WEAK] + EXPORT TIM12_IRQHandler [WEAK] + EXPORT TIM13_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT LPTIM4_IRQHandler [WEAK] + EXPORT LPTIM5_IRQHandler [WEAK] + EXPORT SPDIF_RX_IRQHandler [WEAK] + EXPORT MDIOS_IRQHandler [WEAK] + EXPORT ADF1_FLT0_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + EXPORT UCPD1_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT PSSI_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT WAKEUP_PIN_IRQHandler [WEAK] + EXPORT GPDMA1_Channel8_IRQHandler [WEAK] + EXPORT GPDMA1_Channel9_IRQHandler [WEAK] + EXPORT GPDMA1_Channel10_IRQHandler [WEAK] + EXPORT GPDMA1_Channel11_IRQHandler [WEAK] + EXPORT GPDMA1_Channel12_IRQHandler [WEAK] + EXPORT GPDMA1_Channel13_IRQHandler [WEAK] + EXPORT GPDMA1_Channel14_IRQHandler [WEAK] + EXPORT GPDMA1_Channel15_IRQHandler [WEAK] + EXPORT HPDMA1_Channel8_IRQHandler [WEAK] + EXPORT HPDMA1_Channel9_IRQHandler [WEAK] + EXPORT HPDMA1_Channel10_IRQHandler [WEAK] + EXPORT HPDMA1_Channel11_IRQHandler [WEAK] + EXPORT HPDMA1_Channel12_IRQHandler [WEAK] + EXPORT HPDMA1_Channel13_IRQHandler [WEAK] + EXPORT HPDMA1_Channel14_IRQHandler [WEAK] + EXPORT HPDMA1_Channel15_IRQHandler [WEAK] + EXPORT GPU2D_IRQHandler [WEAK] + EXPORT GPU2D_ER_IRQHandler [WEAK] + EXPORT ICACHE_IRQHandler [WEAK] + EXPORT FDCAN1_IT0_IRQHandler [WEAK] + EXPORT FDCAN1_IT1_IRQHandler [WEAK] + EXPORT FDCAN2_IT0_IRQHandler [WEAK] + EXPORT FDCAN2_IT1_IRQHandler [WEAK] + +PVD_PVM_IRQHandler +DTS_IRQHandler +IWDG_IRQHandler +WWDG_IRQHandler +RCC_IRQHandler +FLASH_IRQHandler +RAMECC_IRQHandler +FPU_IRQHandler +TAMP_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 +RTC_IRQHandler +SAES_IRQHandler +CRYP_IRQHandler +PKA_IRQHandler +HASH_IRQHandler +RNG_IRQHandler +ADC1_2_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 +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 +TIM9_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +SPI3_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +SPI6_IRQHandler +HPDMA1_Channel0_IRQHandler +HPDMA1_Channel1_IRQHandler +HPDMA1_Channel2_IRQHandler +HPDMA1_Channel3_IRQHandler +HPDMA1_Channel4_IRQHandler +HPDMA1_Channel5_IRQHandler +HPDMA1_Channel6_IRQHandler +HPDMA1_Channel7_IRQHandler +SAI1_A_IRQHandler +SAI1_B_IRQHandler +SAI2_A_IRQHandler +SAI2_B_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +UART7_IRQHandler +UART8_IRQHandler +I3C1_EV_IRQHandler +I3C1_ER_IRQHandler +OTG_HS_IRQHandler +ETH_IRQHandler +CORDIC_IRQHandler +GFXTIM_IRQHandler +DCMIPP_IRQHandler +LTDC_IRQHandler +LTDC_ER_IRQHandler +DMA2D_IRQHandler +JPEG_IRQHandler +GFXMMU_IRQHandler +I3C1_WKUP_IRQHandler +MCE1_IRQHandler +MCE2_IRQHandler +MCE3_IRQHandler +XSPI1_IRQHandler +XSPI2_IRQHandler +FMC_IRQHandler +SDMMC1_IRQHandler +SDMMC2_IRQHandler +OTG_FS_IRQHandler +TIM12_IRQHandler +TIM13_IRQHandler +TIM14_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +LPTIM3_IRQHandler +LPTIM4_IRQHandler +LPTIM5_IRQHandler +SPDIF_RX_IRQHandler +MDIOS_IRQHandler +ADF1_FLT0_IRQHandler +CRS_IRQHandler +UCPD1_IRQHandler +CEC_IRQHandler +PSSI_IRQHandler +LPUART1_IRQHandler +WAKEUP_PIN_IRQHandler +GPDMA1_Channel8_IRQHandler +GPDMA1_Channel9_IRQHandler +GPDMA1_Channel10_IRQHandler +GPDMA1_Channel11_IRQHandler +GPDMA1_Channel12_IRQHandler +GPDMA1_Channel13_IRQHandler +GPDMA1_Channel14_IRQHandler +GPDMA1_Channel15_IRQHandler +HPDMA1_Channel8_IRQHandler +HPDMA1_Channel9_IRQHandler +HPDMA1_Channel10_IRQHandler +HPDMA1_Channel11_IRQHandler +HPDMA1_Channel12_IRQHandler +HPDMA1_Channel13_IRQHandler +HPDMA1_Channel14_IRQHandler +HPDMA1_Channel15_IRQHandler +GPU2D_IRQHandler +GPU2D_ER_IRQHandler +ICACHE_IRQHandler +FDCAN1_IT0_IRQHandler +FDCAN1_IT1_IRQHandler +FDCAN2_IT0_IRQHandler +FDCAN2_IT1_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/Middlewares/.DS_Store b/Middlewares/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..f39d385dcbed73465fec447f80256bd5080d75a1 GIT binary patch literal 6148 zcmeHKyJ`b55S(>f7~Hr_sb9z+9LDJbcJDl{NWfr7;v(Hu`L2ALXCDNcOK_DY%))A< z)sBRwxV;5n%R_$yEC9^tj`;LpY`*V4vPnf8&Cht;?{^-XV^dof!MPKxvFYEQcBlMj zyxkOERb3P^z;6=2PFo6Qq7N&zV#1-=#V??a# pJSZHZ9227)bK&LqI+8N4`JDS*;gA?~#)D4O&w%S9lLCLOz!4$r8C?JX literal 0 HcmV?d00001 diff --git a/Middlewares/ST/STM32_ExtMem_Manager/LICENSE.md b/Middlewares/ST/STM32_ExtMem_Manager/LICENSE.md new file mode 100644 index 0000000..e7c249d --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/LICENSE.md @@ -0,0 +1,80 @@ +SLA0044 Rev5/February 2018 + +## Software license agreement + +### __ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT__ + +BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE +OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS +INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES +(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON +BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES +TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT. + +Under STMicroelectronics’ intellectual property rights, the redistribution, +reproduction and use in source and binary forms of the software or any part +thereof, with or without modification, are permitted provided that the following +conditions are met: + +1. Redistribution of source code (modified or not) must retain any copyright +notice, this list of conditions and the disclaimer set forth below as items 10 +and 11. + +2. Redistributions in binary form, except as embedded into microcontroller or +microprocessor device manufactured by or for STMicroelectronics or a software +update for such device, must reproduce any copyright notice provided with the +binary code, this list of conditions, and the disclaimer set forth below as +items 10 and 11, in documentation and/or other materials provided with the +distribution. + +3. Neither the name of STMicroelectronics nor the names of other contributors to +this software may be used to endorse or promote products derived from this +software or part thereof without specific written permission. + +4. This software or any part thereof, including modifications and/or derivative +works of this software, must be used and execute solely and exclusively on or in +combination with a microcontroller or microprocessor device manufactured by or +for STMicroelectronics. + +5. No use, reproduction or redistribution of this software partially or totally +may be done in any manner that would subject this software to any Open Source +Terms. “Open Source Terms” shall mean any open source license which requires as +part of distribution of software that the source code of such software is +distributed therewith or otherwise made available, or open source license that +substantially complies with the Open Source definition specified at +www.opensource.org and any other comparable open source license such as for +example GNU General Public License (GPL), Eclipse Public License (EPL), Apache +Software License, BSD license or MIT license. + +6. STMicroelectronics has no obligation to provide any maintenance, support or +updates for the software. + +7. The software is and will remain the exclusive property of STMicroelectronics +and its licensors. The recipient will not take any action that jeopardizes +STMicroelectronics and its licensors' proprietary rights or acquire any rights +in the software, except the limited rights specified hereunder. + +8. The recipient shall comply with all applicable laws and regulations affecting +the use of the software or any part thereof including any applicable export +control law or regulation. + +9. Redistribution and use of this software or any part thereof other than as +permitted under this license is void and will automatically terminate your +rights under this license. + +10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE +DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL +STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER +EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY +RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY. diff --git a/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c b/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c new file mode 100644 index 0000000..ef4607f --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c @@ -0,0 +1,191 @@ +/** + ****************************************************************************** + * @file stm32_boot_xip.c + * @author MCD Application Team + * @brief This file manages booting in execute-in-place (XIP) mode. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_boot_xip.h" +#include "stm32_extmem_conf.h" + +/** @addtogroup BOOT + * @{ + */ + +/** @addtogroup BOOT_XIP + * @{ + */ + +/* Private typedefs ----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ + +/* Offset of the image from the boot memory base */ +#ifndef EXTMEM_XIP_IMAGE_OFFSET +#define EXTMEM_XIP_IMAGE_OFFSET 0 +#endif /* EXTMEM_XIP_IMAGE_OFFSET */ + +/* Offset of the vector table from the start of the image */ +#ifndef EXTMEM_HEADER_OFFSET +#define EXTMEM_HEADER_OFFSET 0 +#endif /* EXTMEM_HEADER_OFFSET */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +BOOTStatus_TypeDef JumpToApplication(void); +BOOTStatus_TypeDef MapMemory(void); +BOOTStatus_TypeDef GetBaseAddress(uint32_t MemIndex, uint32_t *BaseAddress); + +/** + * @addtogroup BOOT_XIP_Exported_Functions Boot XIP exported functions + * @{ + */ + +/** + * @brief Boots the application by mapping the memory and jumping to the application. + * @retval BOOTStatus_TypeDef Status of the operation. + */ +BOOTStatus_TypeDef BOOT_Application(void) +{ + BOOTStatus_TypeDef retr; + + /* Mount the memory */ + retr = MapMemory(); + if (BOOT_OK == retr) + { + /* Jump on the application */ + retr = JumpToApplication(); + } + return retr; +} + +/** + * @} + */ + +/** + * @defgroup BOOT_XIP_Private_Functions Boot XIP private functions + * @{ + */ + +/** + * @brief Maps the external memory. + * @retval BOOTStatus_TypeDef Status of the operation. + */ +BOOTStatus_TypeDef MapMemory(void) +{ + BOOTStatus_TypeDef retr = BOOT_OK; + + /* Map all the memory */ + for (uint8_t index = 0; index < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)); index++) + { + switch (EXTMEM_MemoryMappedMode(index, EXTMEM_ENABLE)) + { + case EXTMEM_ERROR_NOTSUPPORTED : + if (EXTMEM_MEMORY_BOOTXIP == index) + { + retr = BOOT_ERROR_INCOMPATIBLEMEMORY; + } + else + { + /* We consider the memory will be not used any more */ + EXTMEM_DeInit(index); + } + case EXTMEM_OK: + break; + default : + retr = BOOT_ERROR_MAPPEDMODEFAIL; + break; + } + } + return retr; +} + +/** + * @brief Jumps to the application using its vector table. + * @retval BOOTStatus_TypeDef Status of the operation. + */ +BOOTStatus_TypeDef JumpToApplication(void) +{ + uint32_t primask_bit; + typedef void (*pFunction)(void); + static pFunction JumpToApp; + uint32_t Application_vector; + + if (EXTMEM_OK != EXTMEM_GetMapAddress(EXTMEM_MEMORY_BOOTXIP, &Application_vector)) + { + return BOOT_ERROR_INCOMPATIBLEMEMORY; + } + + /* Suspend SysTick */ + HAL_SuspendTick(); + +#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + /* if I-Cache is enabled, disable I-Cache-----------------------------------*/ + if (SCB->CCR & SCB_CCR_IC_Msk) + { + SCB_DisableICache(); + } +#endif /* __ICACHE_PRESENT */ + +#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + /* if D-Cache is enabled, disable D-Cache-----------------------------------*/ + if (SCB->CCR & SCB_CCR_DC_Msk) + { + SCB_DisableDCache(); + } +#endif /* __DCACHE_PRESENT */ + + /* Initialize user application's Stack Pointer & Jump to user application */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Apply offsets for image location and vector table offset */ + Application_vector += EXTMEM_XIP_IMAGE_OFFSET + EXTMEM_HEADER_OFFSET; + + SCB->VTOR = (uint32_t)Application_vector; + JumpToApp = (pFunction)(*(__IO uint32_t *)(Application_vector + 4u)); + +#if (defined(__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) + /* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */ + __set_MSPLIM(0x00000000); +#elif (defined(__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) + /* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */ + __set_MSPLIM(0x00000000); +#elif (defined(__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) + /* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */ + __set_MSPLIM(0x00000000); +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8_1M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + + __set_MSP(*(__IO uint32_t *) Application_vector); + + /* Re-enable the interrupts */ + __set_PRIMASK(primask_bit); + + JumpToApp(); + return BOOT_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.h b/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.h new file mode 100644 index 0000000..e9395a1 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.h @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * @file stm32_boot_xip.h + * @author MCD Application Team + * @brief Header for stm32_boot_xip.c 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. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_BOOT_XIP_H__ +#define __STM32_BOOT_XIP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** @addtogroup BOOT_XIP + * @{ + */ + +/* Exported defines ---------------------------------------------------------*/ +/** + * @defgroup BOOT_XIP_Private_Defines Boot XIP exported definitions + * @{ + */ +/** + * @brief List of status codes for XIP + */ +typedef enum +{ + BOOT_OK, /*!< Operation successful */ + BOOT_ERROR_UNSUPPORTED_MEMORY, /*!< Unsupported memory type */ + BOOT_ERROR_NOBASEADDRESS, /*!< No base address for the memory */ + BOOT_ERROR_MAPPEDMODEFAIL, /*!< Error during memory mapping */ + BOOT_ERROR_INCOMPATIBLEMEMORY, /*!< Selected memory not compatible with XIP boot */ + BOOT_ERROR_DRIVER, /*!< Error in driver operation */ +} BOOTStatus_TypeDef; + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** + * @defgroup BOOT_XIP_Exported_Functions Boot XIP exported functions + * @{ + */ + +BOOTStatus_TypeDef BOOT_Application(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BOOT_XIP_H__ */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c new file mode 100644 index 0000000..853ea5d --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c @@ -0,0 +1,2906 @@ +/** + ****************************************************************************** + * @file stm32_sfdp_data.c + * @author MCD Application Team + * @brief This file includes a driver for SFDP support + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem_conf.h" + +#if defined(EXTMEM_DRIVER_NOR_SFDP) && (EXTMEM_DRIVER_NOR_SFDP == 1) +#include "stm32_sfdp_driver_api.h" +#include "stm32_sfdp_data.h" +#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL != 0 && defined(EXTMEM_MACRO_DEBUG) +#include +#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL != 0 && EXTMEM_MACRO_DEBUG */ +#include + +/** @defgroup NOR_SFDP_DATA Data module + * @ingroup NOR_SFDP + * @{ + */ + +/* Private defines ------------------------------------------------------------*/ +/** @defgroup NOR_SFDP_DATA_Private_Defines Private Defines + * This group contains all private defines of the NOR SFDP data module. + * @{ + */ + +/** @brief Reset method definition + * + * Defines the reset method used for SFDP. + */ +typedef enum +{ + RESET_NONE, + RESET_FH_4DATA_8CLOCK, + RESET_FH_4DATA_10CLOCK, + RESET_FH_4DATA_16CLOCK, + RESET_INSTRUCTION_F0, + RESET_INSTRUCTION_66_99, + RESET_ERROR +} RESET_METHOD; + +/** @brief TRUE definition + * + * Defines the value for true. + */ +#define EXTMEM_SFDP_TRUE 1u /**< True value */ + +/** @brief FALSE definition + * + * Defines the value for false. + */ +#define EXTMEM_SFDP_FALSE 0u /**< False value */ + +/** @brief No address management definition + * + * Value indicating no address management case. + */ +#define EXTMEM_ADDRESS_NONE 0xFFu /**< No address management */ + +/** + * @brief Clock definition for 200 MHz + */ +#define CLOCK_200MHZ 200000000u +/** + * @brief Clock definition for 166 MHz + */ +#define CLOCK_166MHZ 166000000u +/** + * @brief Clock definition for 133 MHz + */ +#define CLOCK_133MHZ 133000000u +/** + * @brief Clock definition for 100 MHz + */ +#define CLOCK_100MHZ 100000000u + +/** + * @brief SFDP signature + */ +#define SFDP_SIGNATURE 0x50444653U +#define SFDP_SIGNATURE_INVERTED 0x44505346U +/** + * @brief SFDP header size + */ +#define SFDP_HEADER_SIZE 8U + +/** + * @brief SFDP param header size + */ +#define SFDP_PARAM_HEADER_SIZE 8U + +/** + * @brief SFDP basic table default size + */ +#define SFDP_PARAMS_BASIC_TABLE_DEFAULTSIZE 23u + +/** + * @brief SFDP Basic Parameter Table (MSB and LSB) + */ +#define SFDP_BASIC_PARAMETER_TABLE_MSB 0xFFU +#define SFDP_BASIC_PARAMETER_TABLE_LSB 0x00U + +/** + * @brief DEBUG macro string + */ +#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 3 && defined(EXTMEM_MACRO_DEBUG) +#define SFDP_DEBUG_STR(_STR_) do{ \ + EXTMEM_MACRO_DEBUG("\t\tSFDP::");\ + EXTMEM_MACRO_DEBUG(_STR_); \ + EXTMEM_MACRO_DEBUG("\n"); \ + }while(0); +#else +#define SFDP_DEBUG_STR(_STR_) +#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 3 && EXTMEM_MACRO_DEBUG */ + +/** + * @brief DEBUG macro string + integer value + */ +#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 3 && defined(EXTMEM_MACRO_DEBUG) +#define SFDP_DEBUG_INT(_STR_,_INT_) do { \ + char int_char[50]; \ + EXTMEM_MACRO_DEBUG("\t\tSFDP::"); \ + (void)sprintf(int_char,"%s0x%x",_STR_, _INT_); \ + EXTMEM_MACRO_DEBUG((uint8_t *)int_char); \ + EXTMEM_MACRO_DEBUG("\n"); \ + }while(0); +#else +#define SFDP_DEBUG_INT(_STR_,_INT_) +#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 3 && EXTMEM_MACRO_DEBUG */ + +/** + * @brief DEBUG macro for function call + */ +#define CHECK_FUNCTION_CALL(_FUNC_) do{ \ + retr = _FUNC_; \ + if ( EXTMEM_SFDP_OK != retr)\ + { \ + goto error; \ + } \ + }while(0); + +/** + * @} + */ + +/* Private typedefs ---------------------------------------------------------*/ +/** @defgroup NOR_SFDP_DATA_Private_TypeDefs Private typedefs + * @{ + */ + +/** + * @brief Memory link configuration structure. + */ +typedef struct +{ + SAL_XSPI_PhysicalLinkTypeDef PhyLink; /*!< Physical link type */ + uint8_t DummyCycle; /*!< Number of dummy cycles */ +} TableConfig_t; + + +/** + * @brief SFDP parameter header structure. + */ +typedef struct +{ + uint8_t ID_lsb; /*!< Least significant byte of ID */ + uint8_t Minor_revision; /*!< Minor revision */ + uint8_t Major_revision; /*!< Major revision */ + uint8_t Length; /*!< Length of the table */ + uint8_t TableAddressPointer[3]; /*!< Table address pointer */ + uint8_t ID_msb; /*!< Most significant byte of ID */ +} SFDP_ParameterHeader_t; + +/** + * @brief SFDP parameter table structure. + */ +typedef struct +{ + SFDP_ParamID_TypeDef type; /*!< List of parameter tables available */ + uint32_t address; /*!< Address of the table */ + uint8_t size; /*!< Size of the table */ +} SFDP_ParameterTable_t; + +/** + * @brief SFDP JEDEC Basic Parameters structure. + */ +typedef struct +{ + uint32_t size; + union + { + uint8_t data_BYTE[23 * 4]; /*!< Data in bytes format */ + uint32_t data_DWORD[23]; /*!< Data in DWORD format */ + struct + { + struct + { + uint32_t BlockSectorEraseSizes:2; + uint32_t WriteGranularity:1; + uint32_t VolatileRegisterProtect:1; + uint32_t WriteEnableInstructionVolatileRegister:1; + uint32_t :3; + uint32_t _4KEraseInstruction:8; + uint32_t Support_1S1S2SFastRead:1; + uint32_t AddressBytes:2; + uint32_t Support_DTR:1; + uint32_t Support_1S2S2SFastRead:1; + uint32_t Support_1S4S4SFastRead:1; + uint32_t Support_1S1S4SFastRead:1; + uint32_t :8; + } D1; + struct + { + uint32_t FlashSize; + } D2; + + /* Fast read */ + struct + { + uint32_t _1S4S4S_DummyClock:5; + uint32_t _1S4S4S_ModeClock:3; + uint32_t _1S4S4S_FastReadInstruction:8; + uint32_t _1S1S4S_DummyClock:5; + uint32_t _1S1S4S_ModeClock:3; + uint32_t _1S1S4S_FastReadInstruction:8; + } D3; + struct + { + uint32_t _1S1S2S_DummyClock:5; + uint32_t _1S1S2S_ModeClock:3; + uint32_t _1S1S2S_FastReadInstruction:8; + uint32_t _1S2S2S_DummyClock:5; + uint32_t _1S2S2S_ModeClock:3; + uint32_t _1S2S2S_FastReadInstruction:8; + } D4; + struct + { + uint32_t _2S2S2S_FastReadSupport:1; + uint32_t :3; + uint32_t _4S4S4S_FastReadSupport:1; + uint32_t :27; + } D5; + struct + { + uint32_t :16; + uint32_t _2S2S2S_DummyClock:5; + uint32_t _2S2S2S_ModeClock:3; + uint32_t _2S2S2S_FastReadInstruction:8; + } D6; + struct + { + uint32_t :16; + uint32_t _4S4S4S_DummyClock:5; + uint32_t _4S4S4S_ModeClock:3; + uint32_t _4S4S4S_FastReadInstruction:8; + } D7; + + /* Erase */ + struct + { + uint32_t EraseType1_Size:8; + uint32_t EraseType1_Instruction:8; + uint32_t EraseType2_Size:8; + uint32_t EraseType2_Instruction:8; + } D8; + struct + { + uint32_t EraseType3_Size:8; + uint32_t EraseType3_Instruction:8; + uint32_t EraseType4_Size:8; + uint32_t EraseType4_Instruction:8; + } D9; + + /* Timing */ + struct + { + uint32_t MutliplierEraseTime:4; + uint32_t EraseType1_TypicalTime_count:5; + uint32_t EraseType1_TypicalTime_units:2; + uint32_t EraseType2_TypicalTime_count:5; + uint32_t EraseType2_TypicalTime_units:2; + uint32_t EraseType3_TypicalTime_count:5; + uint32_t EraseType3_TypicalTime_units:2; + uint32_t EraseType4_TypicalTime_count:5; + uint32_t EraseType4_TypicalTime_units:2; + } D10; + struct + { + uint32_t MutliplierProgamTime:4; + uint32_t PageSize:4; + uint32_t PageProgram_TypicalTime:6; + uint32_t ByteProgram_TypicalTime:5; + uint32_t AddByteProgram_TypicalTime:5; + + uint32_t ChipErase_TypicalTime_count:5; /* 28:24 count */ + uint32_t ChipErase_TypicalTime_units:2; /* 30:29 units (00b: 16 ms, 01b: 256 ms, 10b: 4 s, 11b: 64 s) */ + + uint32_t :1; + } D11; + struct + { + uint32_t ProhibitedOpDuringProgramSuspend:4; + uint32_t ProhibitedOpDuringEraseSuspend:4; + uint32_t :1; + uint32_t ProgramResumeToSuspendInterval:4; + uint32_t SuspendInProgress_ProgramMaxLatency:7; + uint32_t EraseResumeToSuspendInterval:4; + uint32_t SuspendInProgress_EraseMaxLatency:7; + uint32_t :1; + } D12; + struct + { + uint32_t ProgramResume_Intruction:8; + uint32_t ProgramSuspend_Intruction:8; + uint32_t Resume_Intruction:8; + uint32_t Suspend_Intruction:8; + } D13; + struct + { + uint32_t :2; + uint32_t StatusRegister:6; + uint32_t ExitDeepPowerdownDelay:7; + uint32_t ExitDeepPowerdown_Instruction:8; + uint32_t EnterDeepPowerdown_Instruction:8; + uint32_t DeepPowerdown_Support:1; + } D14; + struct + { + uint32_t _4S4S4S_DisableSequence:4; + uint32_t _4S4S4S_EnableSequence:5; + uint32_t _0S4S4S_Support:1; + uint32_t _0S4S4S_ExitMethod:6; + uint32_t _0S4S4S_EntryMethod:4; + uint32_t QuadEnableRequirement:3; + uint32_t HoldORReset_Disable:1; + uint32_t :8; + } D15; + struct + { + uint32_t VolatileNonVolatileRegister_WriteEnable:7; + uint32_t :1; + uint32_t SoftResetRescueSequence_Support:6; + uint32_t Exit4ByteAddressing:10; + uint32_t Enter4ByteAddressing:8; + } D16; + /* Added one for octal management, this part depends on the information size of the flash device */ + struct + { + uint32_t _1S8S8S_DummyClock:5; + uint32_t _1S8S8S_ModeClock:3; + uint32_t _1S8S8S_FastReadInstruction:8; + uint32_t _1S1S8S_DummyClock:5; + uint32_t _1S1S8S_ModeClock:3; + uint32_t _1S1S8S_FastReadInstruction:8; + } D17; + struct + { + uint32_t :18; + uint32_t VariableOutputDriverStrength:5; + uint32_t JEDECSPIProtocolReset:1; + uint32_t DataStrobeSTRMode:2; + uint32_t DataSTrobeQPISTRMode:1; + uint32_t DataSTrobeQPIDTRMode:1; + uint32_t :1; + uint32_t OctalDTRCommandExtension:2; + uint32_t OctalByteOrder:1; + } D18; + struct + { + uint32_t _8s8s8s_DisableSequence:4; + uint32_t _8s8s8s_EnableSequence:5; + uint32_t _8S8S8S_Support:1; + uint32_t _8S8S8S_ExitMethod:6; + uint32_t _8S8S8S_EnterMethod:4; + uint32_t OctalRequirement:3; + uint32_t :9; + } D19; + struct + { + uint32_t _4S4S4S_MaximumSpeedWithoutStrobe:4; /* 1111b: not supported, 1110b: not characterized, 1010b: Reserved + 1100b: 400 MHz, 1011b: 333 MHz, 1010b: 266 MHz, 1001b: 250 MHz + 1000b: 200 MHz, 0111b: 166 MHz, 0110b: 133 MHz, 0101b: 100 MHz + 0100b: 80 MHz, 0011b: 66 MHz, 0010b: 50 MHz, 0001b: 33 MHz */ + uint32_t _4S4S4S_MaximumSpeedWithStrobe:4; + uint32_t _4S4D4D_MaximumSpeedWithoutStrobe:4; + uint32_t _4S4D4D_MaximumSpeedWithStrobe:4; + uint32_t _8S8S8S_MaximumSpeedWithoutStrobe:4; + uint32_t _8S8S8S_MaximumSpeedWithStrobe:4; + uint32_t _8D8D8D_MaximumSpeedWithoutStrobe:4; + uint32_t _8D8D8D_MaximumSpeedWithStrobe:4; + } D20; + struct + { + uint32_t _1S1D1D_FastReadSupport:1; + uint32_t _1S2D2D_FastReadSupport:1; + uint32_t _1S4D4D_FastReadSupport:1; + uint32_t _4S4D4D_FastReadSupport:1; + uint32_t :28; + } D21; + struct + { + uint32_t _1S1D1D_DummyClock:5; + uint32_t _1S1D1D_ModeClock:3; + uint32_t _1S1D1D_FastReadInstruction:8; + uint32_t _1S2D2D_DummyClock:5; + uint32_t _1S2D2D_ModeClock:3; + uint32_t _1S2D2D_FastReadInstruction:8; + } D22; + struct + { + uint32_t _1S4D4D_DummyClock:5; + uint32_t _1S4D4D_ModeClock:3; + uint32_t _1S4D4D_FastReadInstruction:8; + uint32_t _4S4D4D_DummyClock:5; + uint32_t _4S4D4D_ModeClock:3; + uint32_t _4S4D4D_FastReadInstruction:8; + } D23; + } Param_DWORD; + } Params; +} SFDP_JEDECBasic_Params_t; + +/** + * @brief SFDP JEDEC 4ByteAddress Params definition + */ +typedef union +{ + uint8_t data_BYTE[2 * 4]; /*!< data in BYTE format */ + uint32_t data_DWORD[2]; /*!< data in DWORD format */ + struct + { + struct + { + uint32_t Support_1S1S1S_ReadCommand:1; /*!< Instruction=13h */ + uint32_t Support_1S1S1S_FastReadCommand:1; /*!< Instruction=0Ch */ + uint32_t Support_1S1S2S_FastReadCommand:1; /*!< Instruction=3Ch */ + uint32_t Support_1S2S2S_FastReadCommand:1; /*!< Instruction=BCh */ + uint32_t Support_1S1S4S_FastReadCommand:1; /*!< Instruction=6Ch */ + uint32_t Support_1S4S4S_FastReadCommand:1; /*!< Instruction=ECh */ + uint32_t Support_1S1S1S_PageProgramCommand:1;/*!< Instruction=12h */ + uint32_t Support_1S1S4S_PageProgramCommand:1;/*!< Instruction=34h */ + uint32_t Support_1S4S4S_PageProgramCommand:1;/*!< Instruction=3Eh */ + uint32_t Support_EraseCommandType1size:1; /*!< support of erase type1 */ + uint32_t Support_EraseCommandType2size:1; /*!< Instruction lookup in next Dword */ + uint32_t Support_EraseCommandType3size:1; /*!< Instruction lookup in next Dword */ + uint32_t Support_EraseCommandType4size:1; /*!< Instruction lookup in next Dword */ + uint32_t Support_1S1D1D_DTRReadCommand:1; /*!< Instruction=0Eh */ + uint32_t Support_1S2D2D_DTRReadCommand:1; /*!< Instruction=BEh */ + uint32_t Support_1S4D4D_DTRReadCommand:1; /*!< Instruction=EEh */ + uint32_t Support_VolatileIndividualSectorLockReadCommand:1; /* Instruction=E0h */ + uint32_t Support_VolatileIndividualSectorLockWriteCommand:1; /* Instruction=E1h */ + uint32_t Support_NVolatileIndividualSectorLockReadCommand:1; /* Instruction=E2h */ + uint32_t Support_NVolatileIndividualSectorLockWriteCommand:1;/* Instruction=E3h */ + uint32_t Support_1S1S8S_FastReadCommand:1; /* Instruction=7Ch */ + uint32_t Support_1S8S8S_FastReadCommand:1; /* Instruction=CCh */ + uint32_t Support_1S8D8D_DTRReadCommand:1; /* Instruction=FDh */ + uint32_t Support_1S1S8S_PageProgramCommand:1;/* Instruction=84h */ + uint32_t Support_1S8S8S_PageProgramCommand:1;/* Instruction=8Eh */ + uint32_t :7; + } D1; + struct + { + uint32_t InstructionEraseType1:8; /* common usage is:21h for 4 kbyte erase*/ + uint32_t InstructionEraseType2:8; /* common usage is:5Ch for 32 kbyte erase*/ + uint32_t InstructionEraseType3:8; /* common usage is:DCh for 64 kbyte erase*/ + uint32_t InstructionEraseType4:8; /* common usage is:DCh for 256 kbyte erase*/ + } D2; + } Param_DWORD; +} SFDP_JEDEC4ByteAddress_Params_t; + + +/** + * @brief SFDP JEDEC XSPI10 Params definition + */ +typedef union +{ + uint8_t data_BYTE[6 * 4]; /*!< data in BYTE format */ + uint32_t data_DWORD[6]; /*!< data in DWORD format */ + struct + { + /* Command Codes used in 8D-8D-8D protocol mode */ + struct + { + uint32_t ReadFastWrapCommand:8; /* 0 means not supported */ + uint32_t ReadFastCommand:8; + uint32_t :6; + uint32_t NumberOfDataBytesForWriteRegisterCommand:1; + uint32_t NumberOfAdditionnalModifierBytesForWriteRegisterCommand:1; + uint32_t NumberOfAdditionnalModifierBytesForStatusConfigRegisterCommand:1; + uint32_t InitialLaLatencyForReadNonVolatileRegisterCommand:1; + uint32_t InitialLatencyForReadVolatileRegisterCommand:1; + uint32_t NumberOfAdditionalModifierBytesForReadRegisterCommand:1; + uint32_t InitialLatencyForReadStatusRegisterCommand:1; + uint32_t NumberOfAdditionalModifierBytesForReadStatusRegisterCommand:1; + uint32_t SFDPCommand_8D8D8DMode_DummyCycles:1; + uint32_t SFDPCommand_8D8D8DMode_AddressBytes:1; + } D1; + /* Commands Codes used in 8D-8D-8D protocol mode */ + struct + { + uint32_t WriteNVolatileRegisterCommand:8; + uint32_t WriteVolatileRegisterCommand:8; + uint32_t ReadNVolatileRegisterCommand:8; + uint32_t ReadVolatileRegisterCommand:8; + } D2; + /* Memory Commands in 8D-8D-8D protocol mode */ + struct + { + uint32_t :10; + uint32_t EnterDefaultProtocolMode_support:1; + uint32_t SoftResetAndEnterDefaultProtocolMode_support:1; + uint32_t ResetEnable_support:1; + uint32_t SoftReset_support:1; + uint32_t ExitDeepPowerDown_support:1; + uint32_t EnterDeepPowerDown_support:1; + uint32_t WriteNVolatileRegister_support:1; + uint32_t WriteVolatileRegister_support:1; + uint32_t WriteRegister_support:1; + uint32_t ClearFlagStatusReg_support:1; + uint32_t WriteStatusConfigurationRegister_support:1; + uint32_t ReadNVolatileRegister_support:1; + uint32_t ReadVolatileRegister_support:1; + uint32_t ReadRegister_support:1; + uint32_t ReadFlagStatusRegister_support:1; + uint32_t ReadConfigurationRegister_support:1; + uint32_t EraseChip_support:1; + uint32_t Erase_32Kbytes_support:1; + uint32_t Erase_4Kbytes_support:1; + uint32_t SetupReadWrap_support:1; + uint32_t ReadFastWrap_support:1; + uint32_t ReadSFDP_8D8D8D:1; + } D3; /* this naming to be aligned with the specification */ + /* Dummy cycles used for various frequencies */ + struct + { + uint32_t :2; + uint32_t Operation200Mhz_ConfigPattern:5; + uint32_t Operation200Mhz_DummyCycle:5; + uint32_t :20; + } D4; + /* Dummy cycles used for various frequencies */ + struct + { + uint32_t :2; + uint32_t Operation100Mhz_ConfigPattern:5; + uint32_t Operation100Mhz_DummyCycle:5; + uint32_t Operation133Mhz_ConfigPattern:5; + uint32_t Operation133Mhz_DummyCycle:5; + uint32_t Operation166Mhz_ConfigPattern:5; + uint32_t Operation166Mhz_DummyCycle:5; + } D5; + /* Default Dummy cycles after POR */ + struct + { + uint32_t _8D8D8DDefaultPOR_DummyCycle:5; + uint32_t _8S8S8SDefaultPOR_DummyCycle:5; + uint32_t :22; + } D6; + + } Param_DWORD; +} SFDP_JEDEC_XSPI10_t; /* contains the command codes used in 8D-8D-8D protocol mode */ + +/** + * @brief SFDP JEDEC octal ddr params definition + */ +typedef union +{ + uint8_t data_BYTE[8 * 4]; /*!< data in BYTE format */ + uint32_t data_DWORD[8]; /*!< data in DWORD format */ + struct + { + /* 1st DWORD - First Command Sequence */ + struct + { + uint32_t Byte3CommandSequence:8; + uint32_t Byte2CommandSequence:8; + uint32_t Byte1CommandSequence:8; + uint32_t LengthCommand:8; + } D1; + /* 2nd DWORD - First Command Sequence (continued)*/ + struct + { + uint32_t Byte7CommandSequence:8; + uint32_t Byte6CommandSequence:8; + uint32_t Byte5CommandSequence:8; + uint32_t Byte4CommandSequence:8; + } D2; + /* 1st DWORD - Second Command Sequence */ + struct + { + uint32_t Byte3CommandSequence:8; + uint32_t Byte2CommandSequence:8; + uint32_t Byte1CommandSequence:8; + uint32_t LengthCommand:8; + } D3; + /* 2nd DWORD - Second Command Sequence (continued)*/ + struct + { + uint32_t Byte7CommandSequence:8; + uint32_t Byte6CommandSequence:8; + uint32_t Byte5CommandSequence:8; + uint32_t Byte4CommandSequence:8; + } D4; + /* 1st DWORD - third Command Sequence */ + struct + { + uint32_t Byte3CommandSequence:8; + uint32_t Byte2CommandSequence:8; + uint32_t Byte1CommandSequence:8; + uint32_t LengthCommand:8; + } D5; + /* 2nd DWORD - third Command Sequence (continued)*/ + struct + { + uint32_t Byte7CommandSequence:8; + uint32_t Byte6CommandSequence:8; + uint32_t Byte5CommandSequence:8; + uint32_t Byte4CommandSequence:8; + } D6; + /* 1st DWORD - fourth Command Sequence */ + struct + { + uint32_t Byte3CommandSequence:8; + uint32_t Byte2CommandSequence:8; + uint32_t Byte1CommandSequence:8; + uint32_t LengthCommand:8; + } D7; + /* 2nd DWORD - fourth Command Sequence (continued)*/ + struct + { + uint32_t Byte7CommandSequence:8; + uint32_t Byte6CommandSequence:8; + uint32_t Byte5CommandSequence:8; + uint32_t Byte4CommandSequence:8; + } D8; + } Param_DWORD; +} SFDP_JEDEC_OCTALDDR_t; /* contains the command codes used in 8D-8D-8D protocol mode */ + +/** + * @brief SFDP JEDEC SCCR Params definition + */ +typedef union +{ + uint8_t data_b[28 * 4]; /*!< data in byte format */ + uint32_t data_DWORD[28]; /*!< data in DWORD format */ + struct + { + + uint32_t AddressOffsetVolatileRegister; + uint32_t AddressOffsetNonVolatileRegister; + + + /* Generic Addressable Read/Write Status/Control register commands for volatile registers */ + struct + { + uint32_t NbDummyCyclesReadStatusControlRegisterCommandForVolatileRegisters_1S1S1S:4; + uint32_t :2; + uint32_t NbDummyCyclesReadRegisterCmdVolatileRegister_8D8D8D_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdVolatileRegister_8S8S8S_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdVolatileRegister_4S4D4D_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdVolatileRegister_4S4S4S_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdVolatileRegister_2S2S2S_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdVolatileRegister_1S1S1S_mode:2; + + uint32_t NbAddressBytesGenericAddressableReadWriteStatusControlRegisterCommandsVolatileRegisters:2; + uint32_t GenericAddressableWriteRegisterCmdVolatileRegister_support:1; + uint32_t GenericAddressableReadRegisterCmdVolatileRegister_support:1; + } D3; + /* Generic Addressable Read/Write Status/Control register commands for non-volatile registers */ + struct + { + uint32_t NbDummyCyclesReadStatusControlRegisterCommandForNVolatileRegisters_1S1S1S:4; + uint32_t :2; + uint32_t NbDummyCyclesReadRegisterCmdNonVolatileRegister_8D8D8D_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdNonVolatileRegister_8S8S8S_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdNonVolatileRegister_4S4D4D_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdNonVolatileRegister_4S4S4S_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdNonVolatileRegister_2S2S2S_mode:4; + uint32_t NbDummyCyclesReadRegisterCmdNonVolatileRegister_1S1S1S_mode:2; + + uint32_t NbAddressBytesGenericAddressableReadWriteStatusControlRegisterCommandsNVolatileRegisters:2; + uint32_t GenericAddressableWriteRegisterCmdNonVolatileRegister_support:1; + uint32_t GenericAddressableReadRegisterCmdNonVolatileRegister_support:1; + } D4; + /* WIP (Required for xSPI) */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t WIPBitLocationRegister:3; + uint32_t LocalAddressForWIP:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t WIPpolarity:1; + uint32_t WIPBitAvailable:1; + } D5; + /* WEL */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t WELBitLocationRegister:3; + uint32_t WELLocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t WELWriteAccessBit:1; + uint32_t WELpolarity:1; + uint32_t WELBitAvailable:1; + } D6; + /* Program Error */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t Sharing:1; + uint32_t Polarity:1; + uint32_t BitAvailable:1; + } D7; + /* Erase Error */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t Sharing:1; + uint32_t Polarity:1; + uint32_t BitAvailable:1; + } D8; + /* 9th DWORD * Variable Dummy Cycle Settings * Volatile Register */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationLSBPhysicalBitsRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t NumberBitsUsedToSetWaitStates:2; + uint32_t BitAvailable:1; + } D9; + /* 10th DWORD * Variable Dummy Cycle Settings * Non Volatile Register */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationLSBPhysicalBitsRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t NumberBitsUsedToSetWaitStates:2; + uint32_t BitAvailable:1; + } D10; + /* 11th DWORD * Variable Dummy Cycle Settings * bit patterns */ + struct + { + uint32_t :2; + uint32_t BitPatternUsedToSet_22DummyCycles:5; + uint32_t Support_22DummyCycles:1; + uint32_t BitPatternUsedToSet_24DummyCycles:5; + uint32_t Support_24DummyCycles:1; + uint32_t BitPatternUsedToSet_26DummyCycles:5; + uint32_t Support_26DummyCycles:1; + uint32_t BitPatternUsedToSet_28DummyCycles:5; + uint32_t Support_28DummyCycles:1; + uint32_t BitPatternUsedToSet_30DummyCycles:5; + uint32_t Support_30DummyCycles:1; + } D11; + /* 12th DWORD * Variable Dummy Cycle Settings * bit patterns */ + struct + { + uint32_t :2; + uint32_t BitPatternUsedToSet_12DummyCycles:5; + uint32_t Support_12DummyCycles:1; + uint32_t BitPatternUsedToSet_14DummyCycles:5; + uint32_t Support_14DummyCycles:1; + uint32_t BitPatternUsedToSet_16DummyCycles:5; + uint32_t Support_16DummyCycles:1; + uint32_t BitPatternUsedToSet_18DummyCycles:5; + uint32_t Support_18DummyCycles:1; + uint32_t BitPatternUsedToSet_20DummyCycles:5; + uint32_t Support_20DummyCycles:1; + } D12; + /* 13th DWORD * Variable Dummy Cycle Settings * bit patterns */ + struct + { + uint32_t :2; + uint32_t BitPatternUsedToSet_2DummyCycles:5; + uint32_t Support_2DummyCycles:1; + uint32_t BitPatternUsedToSet_4DummyCycles:5; + uint32_t Support_4DummyCycles:1; + uint32_t BitPatternUsedToSet_6DummyCycles:5; + uint32_t Support_6DummyCycles:1; + uint32_t BitPatternUsedToSet_8DummyCycles:5; + uint32_t Support_8DummyCycles:1; + uint32_t BitPatternUsedToSet_10DummyCycles:5; + uint32_t Support_10DummyCycles:1; + } D13; + /* 14th DWORD * QPI Mode Enable Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D14; + /* 15th DWORD * QPI Mode Enable - Non Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D15; + /* 16th DWORD * Octal Mode Enable Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D16; + /* 17th DWORD * Octal Mode Enable - Non Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D17; + /* 18th DWORD * STR or DTR mode select * Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D18; + /* 19th DWORD * STR or DTR mode select * Non Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D19; + /* 20th DWORD * STR Octal Mode Enable * Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D20; + /* 21th DWORD * STR Octal Mode Enable * Non Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D21; + /* 22th DWORD * DTR Octal Mode Enable * Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D22; + /* 23th DWORD * DTR Octal Mode Enable * Non Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D23; + /* 24th DWORD * DPD Status */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D24; + /* 25th DWORD * UDPD Status */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t BitPolarity:1; + uint32_t BitAvailable:1; + } D25; + /* 26th DWORD * Output Driver Strength - Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t NumberOfPhysicalBits:2; + } D26; + /* 27th DWORD * Output Driver Strength - Non Volatile */ + struct + { + uint32_t CommandWriteAccess:8; + uint32_t CommandReadAccess:8; + uint32_t AddressRegisterOrModesSupported:8; /* If Bit 28 is 1: Address of register where bit is located + Local address AAAA-AAAA + If Bit 28 is 0: Modes supported and dummy cycles + used for direct command + */ + uint8_t BitLocationRegister:3; + uint32_t LocalAddress:1; + uint32_t BitAccessedByCommandsUsingAddress:1; + uint32_t :1; + uint32_t NumberOfPhysicalBits:2; + } D27; + /* 27th DWORD * Output Driver Strength - Non Volatile */ + struct + { + uint32_t :16; + uint32_t BitPatternSupportDriverType4 :3; + uint32_t BitPatternSupportDriverType3 :3; + uint32_t BitPatternSupportDriverType2 :3; + uint32_t BitPatternSupportDriverType1 :3; + uint32_t BitPatternSupportDriverType0 :3; + } D28; + + + } Param_DWORD; +} SFDP_JEDEC_SCCR_Map_t; /* contains the command codes used in 8D-8D-8D protocol mode */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup NOR_SFDP_DATA_Private_Variables Private Variables + * @{ + */ +/** + * @brief this variable contains all the table available on a memory + */ +static SFDP_ParameterTable_t sfdp_param_info[SFDP_MAX_NB_OF_PARAM]; + +/** + * @brief this variable contains the JEDEC basic table info + */ +static SFDP_JEDECBasic_Params_t JEDEC_Basic = {0}; + +/** + * @brief this variable contains the JEDEC address 4-Byte address table info + */ +static SFDP_JEDEC4ByteAddress_Params_t JEDEC_Address4Bytes = {0}; + +/** + * @brief this variable contains the JEDEC XSPIV1.0 table info + */ +static SFDP_JEDEC_XSPI10_t JEDEC_XSPI10; + +/** + * @brief this variable contains the JEDEC SCCR table info + */ +static SFDP_JEDEC_SCCR_Map_t JEDEC_SCCR_Map; + +/** + * @brief this variable contains the JEDEC octal DDR table info + */ +static SFDP_JEDEC_OCTALDDR_t JEDEC_OctalDdr; + + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup NOR_SFDP_DATA_Private_Functions Private Functions + * @{ + */ +SFDP_StatusTypeDef sfdp_get_paraminfo(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint32_t sfdp_address, + SFDP_ParameterTable_t *Param_info); +SFDP_StatusTypeDef sfdp_enter_octal_mode(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object); +uint32_t sfdp_getfrequencevalue(uint32_t BitField); +SFDP_StatusTypeDef sfdp_set_dummycycle(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint32_t Value); +/** + * @} + */ + +/** @defgroup NOR_SFDP_DATA_Private_JEDEC_Functions Private Functions for JEDEC decoding + * @{ + */ +SFDP_StatusTypeDef JEDEC_Basic_ManageQuadEnableRequirement(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object); +SFDP_StatusTypeDef JEDEC_Basic_Manage4S4S4SEnableSequence(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object); + +/** @defgroup NOR_SFDP_DATA_Private_Singature_Functions Private Functions for SFDP signature + * @{ + */ +SFDP_StatusTypeDef CheckSFDP_Signature(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint32_t Signature); +/** + * @} + */ + + +/** @defgroup NOR_SFDP_DATA_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Reads the SFDP header for the current configuration and adjusts the memory type if required. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @param sfdp_header Pointer to the SFDP header structure to be filled. + * @retval SFDP_StatusTypeDef Status of the operation: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef SFDP_ReadHeader(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, SFDP_HeaderTypeDef *sfdp_header) +{ + SFDP_StatusTypeDef retr; + uint8_t retry_counter = 0; + SFDP_DEBUG_STR(__func__); + + do + { + /* Reset the signature value */ + sfdp_header->Signature = 0; + + /* send the SFDP command to read the header */ + if (HAL_OK != SAL_XSPI_GetSFDP(&Object->sfdp_private.SALObject, 0, (uint8_t *)sfdp_header, SFDP_HEADER_SIZE)) + { + retr = EXTMEM_SFDP_ERROR_SFDPREAD; + goto error; + } + + /* view the header signature value */ + SFDP_DEBUG_INT("SFDP signature::", sfdp_header->Signature); + + switch (CheckSFDP_Signature(Object, sfdp_header->Signature)) + { + case EXTMEM_SFDP_OK: + SFDP_DEBUG_INT("param_number=", sfdp_header->param_number); + SFDP_DEBUG_INT("AccessProtocol=", sfdp_header->AccessProtocol); + retr = EXTMEM_SFDP_OK; + retry_counter = 2u; + break; + case EXTMEM_SFDP_ERROR_SIGNATUREMTYPE: + retr = EXTMEM_SFDP_ERROR_SIGNATURE; + retry_counter++; + break; + /* case EXTMEM_SFDP_ERROR_SIGNATURE :*/ + default : + retr = EXTMEM_SFDP_ERROR_SIGNATURE; + retry_counter = 2u; + break; + } + } while (retry_counter < 2u); + +error: + return retr; +} + +/** + * @brief Retrieves the SFDP header for the NOR memory device. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @param sfdp_header Pointer to the SFDP header structure to be filled. + * @retval SFDP_StatusTypeDef Status of the operation: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef SFDP_GetHeader(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, SFDP_HeaderTypeDef *sfdp_header) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_ERROR_SIGNATURE; + SFDP_DEBUG_STR(__func__); + const TableConfig_t table_config[] = + { + {PHY_LINK_1S1S1S, 8u}, + {PHY_LINK_4S4S4S, 2u}, + {PHY_LINK_4S4S4S, 8u}, + {PHY_LINK_4S4S4S, 6u}, + {PHY_LINK_8D8D8D, 8u}, + {PHY_LINK_8D8D8D, 20u}, + {PHY_LINK_8D8D8D, 10u}, + {PHY_LINK_8D8D8D, 16u} + }; + + /* Loop to find the link configuration of the memory */ + for (uint8_t index = 0u; + (index < (sizeof(table_config) / sizeof(TableConfig_t))) && + (retr == EXTMEM_SFDP_ERROR_SIGNATURE) + ; index++) + { + /* Set the command mode */ + SFDP_DEBUG_STR("try a command configuration"); + + /* Configure the link */ + Object->sfdp_private.DriverInfo.SpiPhyLink = table_config[index].PhyLink; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_PHY_LINK, + &Object->sfdp_private.DriverInfo.SpiPhyLink); + SAL_XSPI_SET_SFDPDUMMYCYLE(Object->sfdp_private.SALObject, table_config[index].DummyCycle); + + /* Loop on the instruction extension */ + for (uint8_t IExt = 0u; + (IExt < 2u) && (retr == EXTMEM_SFDP_ERROR_SIGNATURE); IExt++) + { + SAL_XSPI_SET_COMMANDEXTENSION(Object->sfdp_private.SALObject, IExt); + /* Read the sfdp header */ + if (EXTMEM_SFDP_OK == SFDP_ReadHeader(Object, sfdp_header)) + { + retr = EXTMEM_SFDP_OK; + } + + if (table_config[index].PhyLink < PHY_LINK_4S4S4S) + { + /* Config 1 is invalid so exit the loop */ + break; + } + } + } + return retr; +} + +/** + * @brief Collects all SFDP parameter table information and builds driver data. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @retval SFDP_StatusTypeDef Status of the operation: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef SFDP_CollectData(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_OK; + uint32_t sfdp_address = SFDP_HEADER_SIZE; + SFDP_DEBUG_STR(__func__); + + /* Reset the table mask */ + Object->sfdp_private.Sfdp_table_mask = 0; + + /* Reset the param info */ + (void)memset(sfdp_param_info, 0x0, sizeof(sfdp_param_info)); + + /* Get the table param info */ + for (uint8_t index = 0u; index < (Object->sfdp_private.Sfdp_param_number + 1u); index++) + { + CHECK_FUNCTION_CALL(sfdp_get_paraminfo(Object, sfdp_address, &sfdp_param_info[index])) + Object->sfdp_private.Sfdp_table_mask |= (uint32_t)sfdp_param_info[index].type; + sfdp_address += SFDP_PARAM_HEADER_SIZE; + } + + /* Read each table param to extract the information to build the driver */ + for (uint8_t index = 0u; sfdp_param_info[index].type != SFDP_PARAMID_UNKNOWN; index++) + { + uint8_t *ptr = NULL; + uint32_t size = sfdp_param_info[index].size; + switch (sfdp_param_info[index].type) + { + case SFDP_PARAMID_BASIC_SPIPROTOCOL: + JEDEC_Basic.size = sfdp_param_info[index].size; + ptr = JEDEC_Basic.Params.data_BYTE; + break; + case SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION: + ptr = JEDEC_Address4Bytes.data_BYTE; + break; + case SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP: + ptr = JEDEC_SCCR_Map.data_b; + break; + case SFDP_PARAMID_XSPI_V1_0: + ptr = JEDEC_XSPI10.data_BYTE; + break; + case SFDP_PARAMID_OCTAL_DDR: + ptr = JEDEC_OctalDdr.data_BYTE; + break; + default : + SFDP_DEBUG_STR("the table is not yet handled by the SW"); + break; + } + if (ptr != NULL) + { + if (HAL_OK != SAL_XSPI_GetSFDP(&Object->sfdp_private.SALObject, + sfdp_param_info[index].address, + ptr, size * 4u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + } + + if (SFDP_PARAMID_BASIC_SPIPROTOCOL == sfdp_param_info[index].type) + { + /* Save data about the reset procedure */ + Object->sfdp_private.Reset_info = JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support; + } + } + +error: + return retr; +} + +/** + * @brief Resets the NOR memory device using the SFDP-defined reset procedure. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @retval SFDP_StatusTypeDef Status of the operation: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef SFDP_MemoryReset(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object) +{ + RESET_METHOD reset_method; + SFDP_StatusTypeDef retr = EXTMEM_SFDP_ERROR_NO_PARAMTABLE_BASIC; + uint32_t sfdp_address = SFDP_HEADER_SIZE; + uint8_t find = 0u; + SFDP_DEBUG_STR(__func__); + + /* Get the table param info */ + for (uint8_t index = 0u; index < (Object->sfdp_private.Sfdp_param_number + 1u); index++) + { + retr = sfdp_get_paraminfo(Object, sfdp_address, &sfdp_param_info[0]); + if (EXTMEM_SFDP_OK == retr) + { + /* Check if the table is basic table */ + if (SFDP_PARAMID_BASIC_SPIPROTOCOL == sfdp_param_info[0].type) + { + /* Read the JEDEC basic param */ + if (HAL_OK != SAL_XSPI_GetSFDP(&Object->sfdp_private.SALObject, + sfdp_param_info[0].address, + JEDEC_Basic.Params.data_BYTE, + ((uint32_t)sfdp_param_info[0].size) * 4u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + } + else + { + retr = EXTMEM_SFDP_OK; + find = 1u; + } + } + } + + if ((EXTMEM_SFDP_OK != retr) || (1u == find)) + { + /* Stop reading, if there is an error or if the table has been found */ + break; + } + /* Look for the next table */ + sfdp_address += SFDP_PARAM_HEADER_SIZE; + } + + /* If an error has been returned or if the table has not been found */ + if ((EXTMEM_SFDP_OK != retr) || (0u == find)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Determine how to proceed memory reset */ + if (0x0u == JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support) + { + /* 00_0000b: no software reset instruction is supported */ + reset_method = RESET_NONE; + } + else if (0x1u == (0x1u & JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support)) + { + /* xx_xxx1b: drive Fh on all 4 data wires for 8 clocks */ + reset_method = RESET_FH_4DATA_8CLOCK; + } + else if (0x2u == (0x2u & JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support)) + { + /* xx_xx1xb: drive Fh on all 4 data wires for 10 clocks if device is operating in 4-byte address mode */ + reset_method = RESET_FH_4DATA_10CLOCK; + } + else if (0x4u == (0x4u & JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support)) + { + /* xx_x1xxb: drive Fh on all 4 data wires for 16 clocks */ + reset_method = RESET_FH_4DATA_16CLOCK; + } + else if (0x8u == (0x8u & JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support)) + { + /* xx_1xxxb: issue instruction F0h */ + reset_method = RESET_INSTRUCTION_F0; + } + else if (0x10u == (0x10u & JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support)) + { + /* x1_xxxxb: issue reset enable instruction 66h, then issue reset instruction 99h. The reset enable, + reset sequence may be issued on 1, 2, or 4 wires depending on the device operating mode. + */ + reset_method = RESET_INSTRUCTION_66_99; + } + else if (0x20u == (0x20u & JEDEC_Basic.Params.Param_DWORD.D16.SoftResetRescueSequence_Support)) + { + /* 1x_xxxxb: exit 0-4-4 mode is required prior to other reset sequences above if the device may be + operating in this mode. See 6.4.18, 0-4-4 Mode Exit + */ + /* JEDEC_Basic.Params.Param_DWORD.D16.Exit4ByteAddressing + Exit 4-Byte Addressing + xx_xxxx_xxx1b: issue instruction E9h to exit 4-Byte address mode (write enable instruction 06h is not required) + xx_xxxx_xx1xb: issue write enable instruction 06h, then issue instruction E9h to exit 4-Byte address mode + xx_xxxx_x1xxb: 8-bit volatile extended address register used to define A[31:A24] bits. Read with instruction C8h. + Write instruction is C5h, data length is 1 byte. Return to lowest memory segment + by setting A[31:24] to 00h and use 3-Byte addressing. + xx_xxxx_1xxxb: 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used to enable/disable + 4-byte address mode. When MSB is cleared to 0, 3-byte address mode is active + and A30:A24 are used to select the active 128 Mbit memory segment. + Read with instruction 16h. Write instruction is 17h, data length is 1 byte. + xx_xxx1_xxxxb: A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. + Read instruction is B5h. Bit[0] controls address mode [0=3-Byte; 1=4-Byte]. + Write configuration register instruction is B1h, data length is 2 bytes. + xx_xx1x_xxxxb: Hardware reset + xx_x1xx_xxxxb: Software reset (see bits 13:8 in this DWORD) + xx_1xxx_xxxxb: Power cycle + x1_xxxx_xxxxb: Reserved + */ + retr = EXTMEM_SFDP_ERROR_NOTYETHANDLED; + goto error; + } + else + { + /* No coherence, should be managed as error */ + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + switch (reset_method) + { + case RESET_NONE: + break; + case RESET_INSTRUCTION_66_99: + /* Perform the reset in 1, 2 and 4 lines */ + SFDP_DEBUG_STR("::reset 0x66 0x99"); + (void)SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, 0x66, NULL, 0); + (void)SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, 0x99, NULL, 0); + break; + case RESET_INSTRUCTION_F0: + case RESET_FH_4DATA_8CLOCK: + case RESET_FH_4DATA_10CLOCK: + case RESET_FH_4DATA_16CLOCK: + retr = EXTMEM_SFDP_ERROR_NOTYETHANDLED; + break; + /* case RESET_ERROR:*/ + default : + retr = EXTMEM_SFDP_ERROR_PARAM; + break; + } +error : + return retr; +} + +/** + * @brief Builds the generic driver information from SFDP tables. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @param FreqUpdated Pointer to a variable set to 1 if the frequency is updated, 0 otherwise. + * @retval SFDP_StatusTypeDef Status of the operation: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef SFDP_BuildGenericDriver(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint8_t *FreqUpdated) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_OK; + static const uint16_t block_erase_unit[] = { 16u, 256u, 4000u, 64000u}; + static const uint32_t chip_erase_unit[] = { 16u, 256u, 4000u, 64000u}; + SFDP_DEBUG_STR(__func__); + uint8_t flag4byteAddress = 0u; + uint32_t dummyCycles; + uint32_t dummyCyclesValue; + uint8_t FlashSize; + + if ((Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_BASIC_SPIPROTOCOL) != + (uint32_t)SFDP_PARAMID_BASIC_SPIPROTOCOL) + { + /* This table is mandatory to build the driver data */ + retr = EXTMEM_SFDP_ERROR_NO_PARAMTABLE_BASIC; + goto error; + } + + /* --------------------------------------------------- + * Flash sizing + * --------------------------------------------------- + */ + /* Calculation of the flash density in puissance of 2 */ + if ((JEDEC_Basic.Params.Param_DWORD.D2.FlashSize & 0x80000000u) == 0x0u) + { +#if ( __CORTEX_M == 0) +#error "the assembly instruction is not available" +#else + Object->sfdp_private.FlashSize = 31u - (uint8_t)__CLZ((JEDEC_Basic.Params.Param_DWORD.D2.FlashSize + 1u)); +#endif /* __CORTEX_M */ + } + else + { + Object->sfdp_private.FlashSize = (uint8_t)(JEDEC_Basic.Params.Param_DWORD.D2.FlashSize & 0x7FFFFFFFu); + } + + /* Conversion bit to byte */ + Object->sfdp_private.FlashSize = Object->sfdp_private.FlashSize - 3u; /* divide by eight the value */ + + SFDP_DEBUG_INT("-> flash size: 2^", Object->sfdp_private.FlashSize); + FlashSize = Object->sfdp_private.FlashSize - 1u; + (void) SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_FLASHSIZE, &FlashSize); + + /* get the page size info */ + Object->sfdp_private.PageSize = ((uint32_t)1u << JEDEC_Basic.Params.Param_DWORD.D11.PageSize); + + /* --------------------------------------------------- + * Set default command + * --------------------------------------------------- + */ + Object->sfdp_private.DriverInfo.PageProgramInstruction = SFDP_DRIVER_PAGE_PROGRAM_COMMAND; + + + /* --------------------------------------------------- + * Erase management + * --------------------------------------------------- + */ + /* Manage erase data */ + Object->sfdp_private.DriverInfo.EraseType1Size = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D8.EraseType1_Size; + Object->sfdp_private.DriverInfo.EraseType1Command = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D8.EraseType1_Instruction; + Object->sfdp_private.DriverInfo.EraseType2Size = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D8.EraseType2_Size; + Object->sfdp_private.DriverInfo.EraseType2Command = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D8.EraseType2_Instruction; + Object->sfdp_private.DriverInfo.EraseType3Size = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D9.EraseType3_Size; + Object->sfdp_private.DriverInfo.EraseType3Command = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D9.EraseType3_Instruction; + Object->sfdp_private.DriverInfo.EraseType4Size = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D9.EraseType4_Size; + Object->sfdp_private.DriverInfo.EraseType4Command = (uint8_t)JEDEC_Basic.Params.Param_DWORD.D9.EraseType4_Instruction; + + if (Object->sfdp_private.DriverInfo.EraseType1Size != 0x0u) + { + Object->sfdp_private.DriverInfo.EraseType1Timing = + (uint32_t)JEDEC_Basic.Params.Param_DWORD.D10.MutliplierEraseTime * + (JEDEC_Basic.Params.Param_DWORD.D10.EraseType1_TypicalTime_count + 1u) * + block_erase_unit[JEDEC_Basic.Params.Param_DWORD.D10.EraseType1_TypicalTime_units]; + } + + if (Object->sfdp_private.DriverInfo.EraseType2Size != 0x0u) + { + Object->sfdp_private.DriverInfo.EraseType2Timing = + (uint32_t)JEDEC_Basic.Params.Param_DWORD.D10.MutliplierEraseTime * + (JEDEC_Basic.Params.Param_DWORD.D10.EraseType2_TypicalTime_count + 1u) * + block_erase_unit[JEDEC_Basic.Params.Param_DWORD.D10.EraseType2_TypicalTime_units]; + } + + if (Object->sfdp_private.DriverInfo.EraseType3Size != 0x0u) + { + Object->sfdp_private.DriverInfo.EraseType3Timing = + (uint32_t)JEDEC_Basic.Params.Param_DWORD.D10.MutliplierEraseTime * + (JEDEC_Basic.Params.Param_DWORD.D10.EraseType3_TypicalTime_count + 1u) * + block_erase_unit[JEDEC_Basic.Params.Param_DWORD.D10.EraseType3_TypicalTime_units]; + } + + if (Object->sfdp_private.DriverInfo.EraseType4Size != 0x0u) + { + Object->sfdp_private.DriverInfo.EraseType4Timing = + (uint32_t)JEDEC_Basic.Params.Param_DWORD.D10.MutliplierEraseTime * + (JEDEC_Basic.Params.Param_DWORD.D10.EraseType4_TypicalTime_count + 1u) * + block_erase_unit[JEDEC_Basic.Params.Param_DWORD.D10.EraseType4_TypicalTime_units]; + } + + Object->sfdp_private.DriverInfo.EraseChipTiming = + JEDEC_Basic.Params.Param_DWORD.D10.MutliplierEraseTime * + (JEDEC_Basic.Params.Param_DWORD.D11.ChipErase_TypicalTime_count + 1u) * + chip_erase_unit[JEDEC_Basic.Params.Param_DWORD.D11.ChipErase_TypicalTime_units]; + + /* ------------------------------------------------------ + * WIP/WEL : write in progress/ write enable management + * ------------------------------------------------------ + */ + /* This bit definition is maintained for legacy compatibility only. New system implementations + should refer to 6.4.19 for a full definition of volatile and non-volatile behavior. */ + Object->sfdp_private.DriverInfo.ReadWELCommand = SFDP_DRIVER_READ_STATUS_REGISTER_COMMAND; + Object->sfdp_private.DriverInfo.ReadWIPCommand = SFDP_DRIVER_READ_STATUS_REGISTER_COMMAND; + if (JEDEC_Basic.Params.Param_DWORD.D1.WriteEnableInstructionVolatileRegister == 0u) + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_50H_COMMAND; + } + else + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND; + } + + /* Volatile or Non-Volatile Register and Write Enable Instruction for Status Register 1 + The instruction 01h is typically used to write status register 1 which contains Block Protection (BP) + and other bits. Status register 1 is written by the first data byte following the instruction 01h. + The protection bits must be written to zero to enable writes/erases to the device. + This field describes how to modify the writable bits in status register 1 + in either a volatile or non-volatile manner. + Bits 1:0 in status register 1 are de-facto standard write enable and busy status and + are excluded from the definitions below. + */ + /* xxx_xxx1b: Non-Volatile Status Register 1, powers-up to last written value, use instruction 06h to enable write */ + if ((JEDEC_Basic.Params.Param_DWORD.D16.VolatileNonVolatileRegister_WriteEnable & 0x1u) != 0u) + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND; + } + /* xxx_xx1xb: Volatile Status Register 1, + status register powers-up with bits set to "1"s, use instruction 06h to enable write */ + else if ((JEDEC_Basic.Params.Param_DWORD.D16.VolatileNonVolatileRegister_WriteEnable & 0x02u) != 0u) + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND; + } + /* xxx_x1xxb: Volatile Status Register 1, status register powers-up with bits set to "1"s, + use instruction 50h to enable write */ + else if ((JEDEC_Basic.Params.Param_DWORD.D16.VolatileNonVolatileRegister_WriteEnable & 0x04u) != 0u) + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_50H_COMMAND; + } + /* xxx_1xxxb: Non-Volatile/Volatile status register 1 powers-up to last written value in the non-volatile + status register, use instruction 06h to enable write to non-volatile status register. + Volatile status register may be activated after power-up to override the non-volatile status register, + use instruction 50h to enable write and activate the volatile status register.*/ + else if ((JEDEC_Basic.Params.Param_DWORD.D16.VolatileNonVolatileRegister_WriteEnable & 0x08u) != 0u) + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND; + } + /* xx1_xxxxb: Status Register 1 contains a mix of volatile and non-volatile bits. The 06h instruction is used to + enable writing of the register.*/ + else if ((JEDEC_Basic.Params.Param_DWORD.D16.VolatileNonVolatileRegister_WriteEnable & 0x10u) != 0u) + { + Object->sfdp_private.DriverInfo.WriteWELCommand = SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND; + } + /* x1x_xxxxb: Reserved + 1xx_xxxxb: Reserved + NOTE If the status register is read-only then this field will contain all zeros in bits 4:0. + */ + else + { + retr = EXTMEM_SFDP_ERROR_JEDECBASIC_D16; + goto error; + } + + if (0u != (Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP)) + { + /* WIP */ + if (0u != JEDEC_SCCR_Map.Param_DWORD.D5.WIPBitAvailable) + { + Object->sfdp_private.DriverInfo.ReadWIPCommand = (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D5.CommandReadAccess; + Object->sfdp_private.DriverInfo.WIPPosition = JEDEC_SCCR_Map.Param_DWORD.D5.WIPBitLocationRegister; + Object->sfdp_private.DriverInfo.WIPBusyPolarity = (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D5.WIPpolarity; + Object->sfdp_private.DriverInfo.WIPPosition = JEDEC_SCCR_Map.Param_DWORD.D5.WIPBitLocationRegister; + + if (0u != JEDEC_SCCR_Map.Param_DWORD.D5.BitAccessedByCommandsUsingAddress) + { + /* Address management */ + Object->sfdp_private.DriverInfo.WIPAddress = (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D5.LocalAddressForWIP; + } + else + { + /* in that case there is no address to manage, the value EXTMEM_ADDRESS_NONE is used to detect the difference */ + Object->sfdp_private.DriverInfo.WIPAddress = EXTMEM_ADDRESS_NONE; + } + } + + /* WEL */ + if (0u != JEDEC_SCCR_Map.Param_DWORD.D6.WELBitAvailable) + { + Object->sfdp_private.DriverInfo.ReadWELCommand = (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D6.CommandReadAccess; + Object->sfdp_private.DriverInfo.WELPosition = JEDEC_SCCR_Map.Param_DWORD.D6.WELBitLocationRegister; + Object->sfdp_private.DriverInfo.WELBusyPolarity = (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D6.WELpolarity; + Object->sfdp_private.DriverInfo.WELPosition = JEDEC_SCCR_Map.Param_DWORD.D6.WELBitLocationRegister; + + if (0u != JEDEC_SCCR_Map.Param_DWORD.D5.BitAccessedByCommandsUsingAddress) + { + /* Address management */ + Object->sfdp_private.DriverInfo.WELAddress = (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D6.WELLocalAddress; + } + else + { + /* in that case there is no address to manage, the value EXTMEM_ADDRESS_NONE is used to detect the difference */ + Object->sfdp_private.DriverInfo.WELAddress = EXTMEM_ADDRESS_NONE; + } + } + } + else + { + Object->sfdp_private.DriverInfo.WELPosition = 1; + Object->sfdp_private.DriverInfo.WELBusyPolarity = 0; + + /* + * WIP : Status register read management + * Basic D14 Status register Polling device Busy + */ + if (0x01u == (JEDEC_Basic.Params.Param_DWORD.D14.StatusRegister & 0x01u)) + { + /* xx_xxx1b: Use of legacy polling is supported by reading the Status Register with 05h instruction + and checking WIP bit[0] (0=ready; 1=busy). */ + Object->sfdp_private.DriverInfo.ReadWIPCommand = SFDP_DRIVER_READ_STATUS_REGISTER_COMMAND; + Object->sfdp_private.DriverInfo.WIPPosition = 0u; + Object->sfdp_private.DriverInfo.WIPBusyPolarity = 0u; + } + else if (0x02u == (JEDEC_Basic.Params.Param_DWORD.D14.StatusRegister & 0x02u)) + { + /* xx_xx1xb: Bit 7 of the Flag Status Register may be polled any time a Program, Erase, Suspend/Resume + command is issued, or after a Reset command while the device is busy. The read instruction is 70h. + Flag Status Register bit definitions: bit[7]: Program or erase controller status (0=busy; 1=ready)*/ + Object->sfdp_private.DriverInfo.ReadWIPCommand = 0x70; + Object->sfdp_private.DriverInfo.WIPPosition = 7u; + Object->sfdp_private.DriverInfo.WIPBusyPolarity = 0u; + } + else + { + retr = EXTMEM_SFDP_ERROR_JEDECBASIC_D14; + goto error; + } + } + + /* Set default value for Read instruction */ + Object->sfdp_private.DriverInfo.ReadInstruction = SFDP_DRIVER_READ_COMMAND; + dummyCycles = 0; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + + /* --------------------------------------------------- + * command based on SFDP_PARAMID_BASIC_SPIPROTOCOL + * --------------------------------------------------- + */ + if (((Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_BASIC_SPIPROTOCOL) + == (uint32_t)SFDP_PARAMID_BASIC_SPIPROTOCOL) + && (Object->sfdp_private.Config < EXTMEM_LINK_CONFIG_8LINES)) + { + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_1S1S1S; + + if (Object->sfdp_private.Config > EXTMEM_LINK_CONFIG_1LINE) + { + /* control if read 1s1s2s is available */ + if (JEDEC_Basic.Params.Param_DWORD.D4._1S1S2S_FastReadInstruction != 0u) + { + dummyCycles = JEDEC_Basic.Params.Param_DWORD.D4._1S1S2S_DummyClock + + JEDEC_Basic.Params.Param_DWORD.D4._1S1S2S_ModeClock; + Object->sfdp_private.DriverInfo.ReadInstruction = + (uint8_t)JEDEC_Basic.Params.Param_DWORD.D4._1S1S2S_FastReadInstruction; + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_1S1S2S; + } + + /* control if read 1S2S2S is available */ + if (JEDEC_Basic.Params.Param_DWORD.D4._1S2S2S_FastReadInstruction != 0u) + { + dummyCycles = JEDEC_Basic.Params.Param_DWORD.D4._1S2S2S_DummyClock + + JEDEC_Basic.Params.Param_DWORD.D4._1S2S2S_ModeClock; + Object->sfdp_private.DriverInfo.ReadInstruction = + (uint8_t)JEDEC_Basic.Params.Param_DWORD.D4._1S2S2S_FastReadInstruction; + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_1S2S2S; + } + + /* The memory work only in 2S2S2S */ + if (JEDEC_Basic.Params.Param_DWORD.D5._2S2S2S_FastReadSupport != 0u) + { + dummyCycles = JEDEC_Basic.Params.Param_DWORD.D6._2S2S2S_DummyClock + + JEDEC_Basic.Params.Param_DWORD.D6._2S2S2S_ModeClock; + Object->sfdp_private.DriverInfo.ReadInstruction = + (uint8_t)JEDEC_Basic.Params.Param_DWORD.D6._2S2S2S_FastReadInstruction; + } + } + + /* the command set is only based on this table */ + /* determine the best line configuration */ + if (Object->sfdp_private.Config > EXTMEM_LINK_CONFIG_2LINES) + { + if (JEDEC_Basic.Params.Param_DWORD.D5._4S4S4S_FastReadSupport != 0u) + { + dummyCycles = JEDEC_Basic.Params.Param_DWORD.D7._4S4S4S_DummyClock + + JEDEC_Basic.Params.Param_DWORD.D7._4S4S4S_ModeClock; + Object->sfdp_private.DriverInfo.ReadInstruction = + (uint8_t)JEDEC_Basic.Params.Param_DWORD.D7._4S4S4S_FastReadInstruction; + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_4S4S4S; + + retr = JEDEC_Basic_Manage4S4S4SEnableSequence(Object); + if (retr != EXTMEM_SFDP_OK) + { + goto error; + } + } + else /* other configuration with more 4 lines */ + { + /* not yet handled */ + } + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + +#if defined(IS25WP032D_ENABLE_DTR) + /* Check support of DTR feature (DTR Support in D1) */ + if (JEDEC_Basic.Params.Param_DWORD.D1.Support_DTR == 1u) + { + /* Additional information regarding DTR read instruction and dummy cycles might be present in + D21 : Fast Read (1S-1D-1D), (1S-2D-2D), (1S-4D-4D), and (4S-4D-4D) Support + and + D23 : Fast Read (1S-4D-4D) and (4S-4D-4D) Wait States, Mode Bit Clocks, and Instruction */ + /* Extract values for 4S4D4D */ + if (JEDEC_Basic.Params.Param_DWORD.D21._4S4D4D_FastReadSupport == 1u) + { + dummyCycles = JEDEC_Basic.Params.Param_DWORD.D23._4S4D4D_DummyClock + + JEDEC_Basic.Params.Param_DWORD.D23._4S4D4D_ModeClock; + Object->sfdp_private.DriverInfo.ReadInstruction = + (uint8_t)JEDEC_Basic.Params.Param_DWORD.D23._4S4D4D_FastReadInstruction; + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_4S4D4D; + } + else + { + /* Other specific cases to be managed : for example, when Basic Flash Parameter Table is not long enough + and D21, ... are not provided by the card. Specific cases section might have to be updated when adding + support for new memories whose SFDP parameter table is not complete */ + + /* Specific case for ISSI memories */ + if (Object->sfdp_private.ManuID == EXTMEM_MANUFACTURER_ISSI) /* ISSI manufacturer ID */ + { + dummyCycles = 6u; + Object->sfdp_private.DriverInfo.ReadInstruction = 0x0D; + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_4S4D4D; + SAL_XSPI_SET_DTRREADDUMMYCYLE(Object->sfdp_private.SALObject, (uint8_t)dummyCycles); + } + + } + } +#endif /* IS25WP032D_ENABLE_DTR */ + + } + + /* Configure the link */ + if (HAL_OK != SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_PHY_LINK, + &Object->sfdp_private.DriverInfo.SpiPhyLink)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + if (HAL_OK != SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, &dummyCycles)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + } + + /* ----------------------------------------------------------------------------------------------------------------- + If an octal DDR table is present and the target is 8D8D8D, + when switch in octal DDR mode + ----------------------------------------------------------------------------------------------------------------- + */ + if (((uint32_t)SFDP_PARAMID_OCTAL_DDR == (Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_OCTAL_DDR)) + && (EXTMEM_LINK_CONFIG_8LINES == Object->sfdp_private.Config)) + { + /* check if we are not already in octal mode */ + if (PHY_LINK_8D8D8D == Object->sfdp_private.DriverInfo.SpiPhyLink) + { + flag4byteAddress = 1u; + } + else + { + /* Execute the flash command sequence to switch in octal DDR */ + if (EXTMEM_SFDP_OK == sfdp_enter_octal_mode(Object)) + { + /* switch the memory interface configuration according to the Access protocol field */ + flag4byteAddress = 1u; + /* Specific case of GigaDevice memory GD25LX512ME whose Instruction mode remains on 8S (8bit commands) */ + if (Object->sfdp_private.ManuID == EXTMEM_MANUFACTURER_GIGADEVICE) + { + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_8S8D8D; + } + else + { + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_8D8D8D; + } + + /* update the physical link */ + if (HAL_OK != SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_PHY_LINK, + &Object->sfdp_private.DriverInfo.SpiPhyLink)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + if (Object->sfdp_private.Sfdp_AccessProtocol == 0xFDu) + { + /* set 20 wait state */ + dummyCycles = 20; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + if (Object->sfdp_private.Sfdp_AccessProtocol == 0xFEu) + { + /* set 8 wait state */ + dummyCycles = 8; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + } + else + { + /* an error occurs when trying to switch the mode */ + /* when continue the process and check if another mode could be targeted */ + } + } + + if ((0u != (Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_BASIC_SPIPROTOCOL)) && + (JEDEC_Basic.size > 16u)) + { + /* check octal information to determine */ + /* 0b00 Command Extension is the same as the Command. + (Command / Command Extension has the same value for the whole clock period.)*/ + /* 0b01 Command Extension is the inverse of the Command. + Command Extension acts as a confirmation of the Command */ + /* 0b11 Command and Command Extension forms a 16-bit command word */ + if (JEDEC_Basic.Params.Param_DWORD.D18.OctalDTRCommandExtension > 1u) + { + retr = EXTMEM_SFDP_ERROR_NOTYETHANDLED; + goto error; + } + SAL_XSPI_SET_COMMANDEXTENSION(Object->sfdp_private.SALObject, + (uint8_t)JEDEC_Basic.Params.Param_DWORD.D18.OctalDTRCommandExtension); + } + + /* In octal mode, check if JEDEC xSPI (Profile 1.0) Parameter Table is provided, and if yes, + check value of SFDP command dummy cycles in 1st DWORD */ + if ((Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_XSPI_V1_0) + == (uint32_t)SFDP_PARAMID_XSPI_V1_0) + { + if (JEDEC_XSPI10.Param_DWORD.D1.SFDPCommand_8D8D8DMode_DummyCycles == 1U) + { + SAL_XSPI_SET_SFDPDUMMYCYLE(Object->sfdp_private.SALObject, EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_OPI); + } + } + } + + /* Check WIP flag with new access mode */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + if ((Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION) == + (uint32_t)SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION) + { + if (0u == flag4byteAddress) + { + /* xxxx_xxx1b: issue instruction B7h (preceding write enable not required) */ + if (0x01u == (JEDEC_Basic.Params.Param_DWORD.D16.Enter4ByteAddressing & 0x01u)) + { + /* send command to enter 4-bytes Address mode */ + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, 0xB7, NULL, 0)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Set 4-Byte addressing on PHY side */ + if (HAL_OK != SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_ADDRESS_4BYTES, NULL)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* flag4byteAddress = 1u; this setting is not needed because variable is no more used */ + } + /* xxxx_xx1xb: issue write enable instruction 06h, then issue instruction B7h */ + else if (0x2u == (JEDEC_Basic.Params.Param_DWORD.D16.Enter4ByteAddressing & 0x2u)) + { + /* send command to write enable */ + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, + Object->sfdp_private.DriverInfo.WriteWELCommand, NULL, 0u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* control the write enable */ + if (HAL_OK != SAL_XSPI_CheckStatusRegister(&Object->sfdp_private.SALObject, + Object->sfdp_private.DriverInfo.ReadWELCommand, + Object->sfdp_private.DriverInfo.WELAddress, + (((Object->sfdp_private.DriverInfo.WELBusyPolarity == 0u) ? 1u : 0u) + << Object->sfdp_private.DriverInfo.WELPosition), + 1u << Object->sfdp_private.DriverInfo.WELPosition, + Object->sfdp_private.ManuID, 1000)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* send command to enter 4-bytes Address mode */ + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, 0xB7, NULL, 0u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + } + /* x1xx_xxxxb: Always operates in 4-Byte address mode */ + else if (0x40u == (JEDEC_Basic.Params.Param_DWORD.D16.Enter4ByteAddressing & 0x40u)) + { + /* nothing to do */ + /* flag4byteAddress = 1u; this setting is not needed because variable is no more used */ + } + /* xx1x_xxxxb: Supports dedicated 4-Byte address instruction set. + Consult vendor data sheet for the instruction set definition.*/ + else if (0x20u == (JEDEC_Basic.Params.Param_DWORD.D16.Enter4ByteAddressing & 0x20u)) + { + /* specific memory */ + /* on Macronix nothing to do the command are 4Byte specific so nothing to do */ + /* flag4byteAddress = 1u; this setting is not needed because variable is no more used */ + } + /* xxxx_x1xxb: 8-bit volatile extended address register used to define A[31:24] bits. Read with instruction C8h. + Write instruction is C5h with 1 byte of data. Select the active 128 Mbit memory segment + by setting the appropriate A[31:24] bits and use 3-Byte addressing. + xxxx_1xxxb: 8-bit volatile bank register used to define A[30:A24] bits. MSB (bit[7]) is used + to enable/disable 4-byte address mode. When MSB is set to 1, 4-byte address mode is active + and A[30:24] bits are do not care. Read with instruction 16h. Write instruction is 17h + with 1 byte of data. When MSB is cleared to 0, select the active 128 Mbit segment + by setting the appropriate A[30:24] bits and use 3-Byte addressing. + xxx1_xxxxb: A 16-bit nonvolatile configuration register controls 3-Byte/4-Byte address mode. + Read instruction is B5h. Bit[0] controls address mode [0=3-Byte;1=4-Byte]. + Write configuration register instruction is B1h, data length is 2 bytes. + */ + else + { + retr = EXTMEM_SFDP_ERROR_NOTYETHANDLED; + goto error; + + } + + /* Set 4 bytes addressing on PHY side */ + if (HAL_OK != SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_ADDRESS_4BYTES, NULL)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Set the read and program instruction for 4 bytes Address */ + if (PHY_LINK_1S1S1S == Object->sfdp_private.DriverInfo.SpiPhyLink) + { + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S1S1S_ReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0x13U; + } + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S1S1S_PageProgramCommand) + { + Object->sfdp_private.DriverInfo.PageProgramInstruction = 0x12u; + } + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S1S1S_FastReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0x0Cu; + dummyCycles = EXTMEM_FAST_READ_NB_DUMMY_CYCLES_DEFAULT; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + } + + if (PHY_LINK_1S1S2S == Object->sfdp_private.DriverInfo.SpiPhyLink) + { + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S1S2S_FastReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0x3CU; + } + } + + if (PHY_LINK_1S2S2S == Object->sfdp_private.DriverInfo.SpiPhyLink) + { + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S2S2S_FastReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0xBCU; + } + } + + if (PHY_LINK_1S1D1D == Object->sfdp_private.DriverInfo.SpiPhyLink) + { + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S1D1D_DTRReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0x0EU; + } + } + } + + if ((EXTMEM_LINK_CONFIG_8LINES == Object->sfdp_private.Config) + && (PHY_LINK_1S1S1S == Object->sfdp_private.DriverInfo.SpiPhyLink)) + { + /* check if we can switch to 1S8S8S */ + if ((0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S8S8S_FastReadCommand) + && (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S8S8S_PageProgramCommand)) + { + /* Patch Micron write command 0x81 @0x0 0xE7 */ + Object->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_1S8S8S; + if (HAL_OK != SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_PHY_LINK, + &Object->sfdp_private.DriverInfo.SpiPhyLink)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + Object->sfdp_private.DriverInfo.ReadInstruction = 0xCC; + Object->sfdp_private.DriverInfo.PageProgramInstruction = 0x8E; + } + } + + /* + need to be study more; it seems that Macronix used it to define the command maybe because only one mode is + supported in their case + */ + if (Object->sfdp_private.DriverInfo.SpiPhyLink == PHY_LINK_8S8D8D) + { + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S8S8S_PageProgramCommand) + { + Object->sfdp_private.DriverInfo.PageProgramInstruction = 0x02u; + } + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S8S8S_FastReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0xCCu; + dummyCycles = EXTMEM_FAST_READ_NB_DUMMY_CYCLES_DEFAULT; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + if (0u != JEDEC_Address4Bytes.Param_DWORD.D1.Support_1S8D8D_DTRReadCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = 0xFDu; + } + } + + Object->sfdp_private.DriverInfo.EraseType1Command = + (uint8_t)JEDEC_Address4Bytes.Param_DWORD.D2.InstructionEraseType1; + Object->sfdp_private.DriverInfo.EraseType2Command = + (uint8_t)JEDEC_Address4Bytes.Param_DWORD.D2.InstructionEraseType2; + Object->sfdp_private.DriverInfo.EraseType3Command = + (uint8_t)JEDEC_Address4Bytes.Param_DWORD.D2.InstructionEraseType3; + Object->sfdp_private.DriverInfo.EraseType4Command = + (uint8_t)JEDEC_Address4Bytes.Param_DWORD.D2.InstructionEraseType4; + } + + if (((uint32_t)SFDP_PARAMID_XSPI_V1_0 == (Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_XSPI_V1_0)) + && + ((PHY_LINK_8D8D8D == Object->sfdp_private.DriverInfo.SpiPhyLink) + || (PHY_LINK_8S8D8D == Object->sfdp_private.DriverInfo.SpiPhyLink))) + { + uint32_t ClockOut = 0u; + uint32_t MaxFreqMhz; + /* Read command */ + if (0u != JEDEC_XSPI10.Param_DWORD.D1.ReadFastCommand) + { + Object->sfdp_private.DriverInfo.ReadInstruction = (uint8_t)JEDEC_XSPI10.Param_DWORD.D1.ReadFastCommand; + } + + if (JEDEC_XSPI10.Param_DWORD.D6._8D8D8DDefaultPOR_DummyCycle != 0u) + { + /* Set the default dummy cycle of this mode */ + dummyCycles = JEDEC_XSPI10.Param_DWORD.D6._8D8D8DDefaultPOR_DummyCycle; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + + /* Adapt the memory interface frequency according to its capabilities */ + MaxFreqMhz = sfdp_getfrequencevalue(JEDEC_Basic.Params.Param_DWORD.D20._8D8D8D_MaximumSpeedWithStrobe); + if (MaxFreqMhz > Object->sfdp_private.DriverInfo.ClockIn) + { + /* Adjust the frequency with the ClockIn */ + MaxFreqMhz = Object->sfdp_private.DriverInfo.ClockIn; + } + + /* Adapt the memory interface frequency according to max requested frequency as defined in configuration table. */ + if (Object->sfdp_public.MaxFreq != 0) + { + if (MaxFreqMhz > Object->sfdp_public.MaxFreq) + { + /* Adjust the frequency with the max clock frequency defined in configuration table */ + MaxFreqMhz = Object->sfdp_public.MaxFreq; + } + } + + /* Update the clock to be aligned with selected configuration */ + if (HAL_OK != SAL_XSPI_SetClock(&Object->sfdp_private.SALObject, Object->sfdp_private.DriverInfo.ClockIn, + MaxFreqMhz, &ClockOut)) + { + retr = EXTMEM_SFDP_ERROR_SETCLOCK; + goto error; + } + *FreqUpdated = 1u; /* Used to indicate that the clock configuration has been updated */ + + /* get the dummy cycle value according to the real output clock */ + if ((ClockOut >= CLOCK_200MHZ) && (JEDEC_XSPI10.Param_DWORD.D4.Operation200Mhz_DummyCycle != 0u)) + { + dummyCycles = JEDEC_XSPI10.Param_DWORD.D4.Operation200Mhz_DummyCycle; + dummyCyclesValue = JEDEC_XSPI10.Param_DWORD.D4.Operation200Mhz_ConfigPattern; + } + else if ((ClockOut >= CLOCK_166MHZ) && (JEDEC_XSPI10.Param_DWORD.D5.Operation166Mhz_DummyCycle != 0u)) + { + dummyCycles = JEDEC_XSPI10.Param_DWORD.D5.Operation166Mhz_DummyCycle; + dummyCyclesValue = JEDEC_XSPI10.Param_DWORD.D5.Operation166Mhz_ConfigPattern; + } + else if ((ClockOut >= CLOCK_133MHZ) && (JEDEC_XSPI10.Param_DWORD.D5.Operation133Mhz_DummyCycle != 0u)) + { + dummyCycles = JEDEC_XSPI10.Param_DWORD.D5.Operation133Mhz_DummyCycle; + dummyCyclesValue = JEDEC_XSPI10.Param_DWORD.D5.Operation133Mhz_ConfigPattern; + } + else /* if (ClockOut =< 100Mhz) */ + { + dummyCycles = JEDEC_XSPI10.Param_DWORD.D5.Operation100Mhz_DummyCycle; + dummyCyclesValue = JEDEC_XSPI10.Param_DWORD.D5.Operation100Mhz_ConfigPattern; + } + + /* Specific case of GigaDevice memory with wrongly coded SFDP table in JEDEC_SCCR_Map.Param_DWORD.D9 */ + if (Object->sfdp_private.ManuID == EXTMEM_MANUFACTURER_GIGADEVICE) + { + dummyCycles = 16; + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + else + { + /* Write the dummy cycle value in the configuration register using information coming from SCCR Map */ + if ((0u != (Object->sfdp_private.Sfdp_table_mask & (uint32_t)SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP)) + && (0u != JEDEC_SCCR_Map.Param_DWORD.D9.BitAvailable)) + { + /* Update the frequency with MaxFreqMhz information */ + if (sfdp_set_dummycycle(Object, dummyCyclesValue) == EXTMEM_SFDP_OK) + { + /* Set the dummy cycle corresponding */ + (void)SAL_XSPI_MemoryConfig(&Object->sfdp_private.SALObject, PARAM_DUMMY_CYCLES, (void *)&dummyCycles); + } + } + else + { + retr = EXTMEM_SFDP_ERROR_CONFIGDUMMY; + goto error; + } + } + } + +error : + return retr; +} + +/** + * @brief Checks the busy flag (WIP) of the NOR memory device. + * @param SFDPObject Pointer to the NOR SFDP memory instance object descriptor. + * @param Timeout Timeout value in milliseconds. + * @retval EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef Status of the operation: EXTMEM_DRIVER_NOR_SFDP_OK if not busy, + * error code otherwise. + */ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_check_FlagBUSY(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Timeout) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_BUSY; + SFDP_DEBUG_STR((uint8_t *)__func__) + if (0u != SFDPObject->sfdp_private.DriverInfo.ReadWIPCommand) + { + /* check that the WIP flag is not set */ + if (HAL_OK == SAL_XSPI_CheckStatusRegister(&SFDPObject->sfdp_private.SALObject, + SFDPObject->sfdp_private.DriverInfo.ReadWIPCommand, + SFDPObject->sfdp_private.DriverInfo.WIPAddress, + SFDPObject->sfdp_private.DriverInfo.WIPBusyPolarity + << SFDPObject->sfdp_private.DriverInfo.WIPPosition, + 1u << SFDPObject->sfdp_private.DriverInfo.WIPPosition, + SFDPObject->sfdp_private.ManuID, Timeout)) + { + retr = EXTMEM_DRIVER_NOR_SFDP_OK; + } + } + return retr; +} + +/** + * @} + */ + +/** @addtogroup NOR_SFDP_DATA_Functions + * @{ + */ + +/** + * @brief Returns the frequency value in Hz corresponding to a bit field. + * @param BitField Bit field value from SFDP table. + * @return Frequency value in Hz, or 0 if unknown. + */ +uint32_t sfdp_getfrequencevalue(uint32_t BitField) +{ + const uint16_t freqMhz_table[] = { 0x0, 33, 50, 66, 80, 100, 133, 166, 200, 250, 266, 333, 400 }; + SFDP_DEBUG_STR(__func__); + + if (BitField < 0b1010u) + { + return (uint32_t)freqMhz_table[BitField] * 1000000u; + } + return 0; /* the max frequency is unknown */ +} + +/** + * @brief Reads and checks the SFDP parameter header at the specified address. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @param sfdp_address Address of the SFDP parameter table. + * @param Param_info Pointer to the parameter info structure to be filled. + * @return SFDP_StatusTypeDef: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef sfdp_get_paraminfo(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint32_t sfdp_address, + SFDP_ParameterTable_t *Param_info) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_OK; + SFDP_ParameterHeader_t sfdp_param_header = {0}; + SFDP_DEBUG_STR(__func__); + + /* send the SFDP command to read the header */ + if (HAL_OK != SAL_XSPI_GetSFDP(&Object->sfdp_private.SALObject, sfdp_address, + (uint8_t *)&sfdp_param_header, SFDP_PARAM_HEADER_SIZE)) + { + retr = EXTMEM_SFDP_ERROR_SFDPREAD; + goto error; + } + + Param_info->type = SFDP_PARAMID_UNKNOWN; + Param_info->size = sfdp_param_header.Length ; + Param_info->address = (((uint32_t)sfdp_param_header.TableAddressPointer[2u] << 16u) + | ((uint32_t)sfdp_param_header.TableAddressPointer[1u] << 8u) + | ((uint32_t)sfdp_param_header.TableAddressPointer[0u])); + + if ((sfdp_param_header.ID_msb > 0x00u) && (sfdp_param_header.ID_msb < 0x80u)) + { + if ((sfdp_param_header.ID_lsb & 0x01u) == 0x01u) + { + Param_info->type = SFDP_PARAMID_VENDOR; + SFDP_DEBUG_STR("-> type SFDP_PARAMID_VENDOR"); + } + else + { + Param_info->type = SFDP_PARAMID_FUNCTION_VENDOR; + SFDP_DEBUG_STR("-> type SFDP_PARAMID_FUNCTION_VENDOR"); + } + } + else if (sfdp_param_header.ID_msb >= 0x80u) + { + if ((sfdp_param_header.ID_lsb & 0x01u) == 0x00u) + { + Param_info->type = SFDP_PARAMID_FUNCTION_JEDEC; + SFDP_DEBUG_STR("-> type SFDP_PARAMID_FUNCTION_JEDEC"); + } + + if (sfdp_param_header.ID_msb == SFDP_BASIC_PARAMETER_TABLE_MSB) + { + switch (sfdp_param_header.ID_lsb) + { + case SFDP_BASIC_PARAMETER_TABLE_LSB : + Param_info->type = SFDP_PARAMID_BASIC_SPIPROTOCOL; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_BASIC_SPIPROTOCOL"); + Param_info->size = ((sfdp_param_header.Length) < SFDP_PARAMS_BASIC_TABLE_DEFAULTSIZE) + ? sfdp_param_header.Length : SFDP_PARAMS_BASIC_TABLE_DEFAULTSIZE; + break; + case 0x81u: + Param_info->type = SFDP_PARAMID_SECTORMAP; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_SECTORMAP"); + break; + case 0x03u: + Param_info->type = SFDP_PARAMID_RPMC; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_RPMC"); + break; + case 0x84u: + Param_info->type = SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION"); + break; + case 0x05u: + Param_info->type = SFDP_PARAMID_XSPI_V1_0; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_XSPI_V1_0"); + break; + case 0x06u: + Param_info->type = SFDP_PARAMID_XSPI_V2_0; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_XSPI_V2_0"); + break; + case 0x87u: + Param_info->type = SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP"); + break; + case 0x88u: + Param_info->type = SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP_MULTICHIP; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP_MULTICHIP"); + break; + case 0x09u: + Param_info->type = SFDP_PARAMID_STATUS_CONTROL_CONFIG_XSPI_V2_0; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_STATUS_CONTROL_CONFIG_XSPI_V2_0"); + break; + case 0x0Au: + Param_info->type = SFDP_PARAMID_OCTAL_DDR; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_OCTAL_DDR"); + break; + case 0x8Bu: + Param_info->type = SFDP_PARAMID_MSPT; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_MSPT"); + break; + case 0x0Cu: + Param_info->type = SFDP_PARAMID_X4QUAD_DS; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_X4QUAD_DS"); + break; + case 0x8Du: + Param_info->type = SFDP_PARAMID_QUAD_DDR; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_QUAD_DDR"); + break; + case 0x8Eu: + Param_info->type = SFDP_PARAMID_SECURE_PACKET_READ_WRITE; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_SECURE_PACKET_READ_WRITE"); + break; + case 0x0Fu: + Param_info->type = SFDP_PARAMID_RESERVED; + SFDP_DEBUG_STR("-> info SFDP_PARAMID_RESERVED"); + break; + default : + SFDP_DEBUG_STR("-> info SFDP_PARAMID_????"); + break; + } + } + + if (Param_info->type == SFDP_PARAMID_UNKNOWN) + { + SFDP_DEBUG_STR("-> the table is not compliant with to JEDEC standard"); + } + } + else + { + /* Unexpected value for MSB field of SFDP Parameter ID */ + SFDP_DEBUG_STR("-> Unexpected value for MSB field of SFDP Parameter ID"); + retr = EXTMEM_SFDP_ERROR_SFDPREAD; + goto error; + } + +error: + return retr; +} + +/** + * @brief Executes the octal DDR table to enter octal DDR mode. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @return SFDP_StatusTypeDef: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef sfdp_enter_octal_mode(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_OK; + uint8_t data[7]; + SFDP_DEBUG_STR(__func__); + /* D1-D2 command */ + if (0u != JEDEC_OctalDdr.Param_DWORD.D1.LengthCommand) + { + data[0] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D1.Byte1CommandSequence; + data[1] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D1.Byte2CommandSequence; + data[2] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D1.Byte3CommandSequence; + data[3] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D2.Byte4CommandSequence; + data[4] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D2.Byte5CommandSequence; + data[5] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D2.Byte6CommandSequence; + data[6] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D2.Byte7CommandSequence; + + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, data[0], &data[1], + (uint16_t)(JEDEC_OctalDdr.Param_DWORD.D1.LengthCommand - 1u))) + { + retr = EXTMEM_SFDP_ERROR_OCTALMODE; + goto error; + } + } + + /* D3-D4 command */ + if (0u != JEDEC_OctalDdr.Param_DWORD.D3.LengthCommand) + { + /* wait for busy flag clear */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + data[0] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D3.Byte1CommandSequence; + data[1] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D3.Byte2CommandSequence; + data[2] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D3.Byte3CommandSequence; + data[3] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D4.Byte4CommandSequence; + data[4] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D4.Byte5CommandSequence; + data[5] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D4.Byte6CommandSequence; + data[6] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D4.Byte7CommandSequence; + + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, data[0], &data[1], + (uint16_t)(JEDEC_OctalDdr.Param_DWORD.D3.LengthCommand - 1u))) + { + retr = EXTMEM_SFDP_ERROR_OCTALMODE; + goto error; + } + } + + /* D5-D6 command */ + if (0u != JEDEC_OctalDdr.Param_DWORD.D5.LengthCommand) + { + /* wait for busy flag clear */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + data[0] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D5.Byte1CommandSequence; + data[1] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D5.Byte2CommandSequence; + data[2] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D5.Byte3CommandSequence; + data[3] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D6.Byte4CommandSequence; + data[4] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D6.Byte5CommandSequence; + data[5] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D6.Byte6CommandSequence; + data[6] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D6.Byte7CommandSequence; + + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, data[0], &data[1], + (uint16_t)(JEDEC_OctalDdr.Param_DWORD.D5.LengthCommand - 1u))) + { + retr = EXTMEM_SFDP_ERROR_OCTALMODE; + goto error; + } + } + + /* D7-D8 command */ + if (0u != JEDEC_OctalDdr.Param_DWORD.D7.LengthCommand) + { + /* wait for busy flag clear */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + data[0] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D7.Byte1CommandSequence; + data[1] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D7.Byte2CommandSequence; + data[2] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D7.Byte3CommandSequence; + data[3] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D8.Byte4CommandSequence; + data[4] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D8.Byte5CommandSequence; + data[5] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D8.Byte6CommandSequence; + data[6] = (uint8_t)JEDEC_OctalDdr.Param_DWORD.D8.Byte7CommandSequence; + + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, data[0], &data[1], + (uint16_t)(JEDEC_OctalDdr.Param_DWORD.D7.LengthCommand - 1u))) + { + retr = EXTMEM_SFDP_ERROR_OCTALMODE; + goto error; + } + + /* no more wait for busy flag clear here, as command format might have changed to Octal */ + } + + /* Abort any ongoing transfer to avoid performance issue */ + SAL_XSPI_Abort(&Object->sfdp_private.SALObject); + +error: + return retr; +} + +/** + * @brief Writes the configuration register to set the dummy cycle value. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @param DummyValue Dummy cycle value to set. + * @return SFDP_StatusTypeDef: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef sfdp_set_dummycycle(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint32_t DummyValue) +{ + const uint8_t MaskWaitStateValue[4] = { 0x3u, 0x7u, 0xFu, 0x1Fu }; + SFDP_StatusTypeDef retr = EXTMEM_SFDP_OK; + uint8_t localValue[2] = { 0 }; + uint32_t Address; + + if ((JEDEC_SCCR_Map.Param_DWORD.D9.BitAccessedByCommandsUsingAddress == 0u) && + (JEDEC_SCCR_Map.Param_DWORD.D9.BitAvailable == 1u)) + { + /* Not yet supported */ + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Compute the Address */ + if (JEDEC_SCCR_Map.Param_DWORD.D9.LocalAddress == 1u) + { + /* Local Address is found in Byte 1 of 32-bit address */ + Address = JEDEC_SCCR_Map.Param_DWORD.D9.AddressRegisterOrModesSupported << 8; + } + else + { + /* Specific case of GigaDevice GD25LX512ME where register address is wrongly coded in SFDP table */ + if (Object->sfdp_private.ManuID == 0xC8) + { + /* Address value in datasheet : 1, address value coded in SFDP table 200 */ + Address = 1U; + } + else + { + /* Local address for Variable Dummy Cycle Settings bits is found in last byte of the address */ + Address = JEDEC_SCCR_Map.Param_DWORD.D9.AddressRegisterOrModesSupported; + } + } + + /* Read the configuration */ + if (HAL_OK != SAL_XSPI_CommandSendReadAddress(&Object->sfdp_private.SALObject, + (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D9.CommandReadAccess, + Address, + (uint8_t *)localValue, + 2u, + Object->sfdp_private.ManuID)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* send command to write enable */ + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, + Object->sfdp_private.DriverInfo.WriteWELCommand, NULL, 0u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* control the write enable */ + if (HAL_OK != SAL_XSPI_CheckStatusRegister(&Object->sfdp_private.SALObject, + Object->sfdp_private.DriverInfo.ReadWELCommand, + Object->sfdp_private.DriverInfo.WELAddress, + ((Object->sfdp_private.DriverInfo.WELBusyPolarity == 0u) ? 1u : 0u) + << Object->sfdp_private.DriverInfo.WELPosition, + 1u << Object->sfdp_private.DriverInfo.WELPosition, + Object->sfdp_private.ManuID, 1000)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* clear the value */ + localValue[0] = localValue[0] & ~(MaskWaitStateValue[JEDEC_SCCR_Map.Param_DWORD.D9.NumberBitsUsedToSetWaitStates] + << JEDEC_SCCR_Map.Param_DWORD.D9.BitLocationLSBPhysicalBitsRegister); + + /* Apply the value with the mask */ + localValue[0] = localValue[0] + | (uint8_t)(DummyValue << JEDEC_SCCR_Map.Param_DWORD.D9.BitLocationLSBPhysicalBitsRegister); + localValue[1] = localValue[0]; + + /* Write de configuration */ + if (HAL_OK != SAL_XSPI_Write(&Object->sfdp_private.SALObject, + (uint8_t)JEDEC_SCCR_Map.Param_DWORD.D9.CommandWriteAccess, + Address, (uint8_t *)localValue, 2u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* wait for busy flag clear */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + +error : + return retr; +} + +/** + * @brief Manages the Quad Enable Requirement (QER) for the NOR memory device. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @return SFDP_StatusTypeDef: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef JEDEC_Basic_ManageQuadEnableRequirement(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_ERROR_NOTYETHANDLED; + uint8_t localValue[2]; + + /* switch the mode in QSPI if available */ + switch (JEDEC_Basic.Params.Param_DWORD.D15.QuadEnableRequirement & 0x7u) + { + case 0x0u: /* 000b: Device does not have a QE bit. Device detects 1-1-4 and 1-4-4 reads based on instruction. + IO3/HOLD# functions as hold during instruction phase.*/ + break; + case 0x1u: /* 001b: QE is bit 1 of status register 2. It is set via Write Status with two data bytes + where bit 1 of the second byte is one. + It is cleared via Write Status with two data bytes where bit 1 of the second byte is zero. + Writing only one byte to the status register has the side-effect of clearing status register 2, + including the QE bit. The 100b code is used if writing one byte to the status register + does not modify status register 2. + */ + break; + case 0x2u: + { + /* 010b: QE is bit 6 of status register 1. It is set via Write Status with one data byte where bit 6 is one. + It is cleared via Write Status with one data byte where bit 6 is zero. */ + /* 1 - set the write enable */ + if (HAL_OK != SAL_XSPI_SendReadCommand(&Object->sfdp_private.SALObject, + Object->sfdp_private.DriverInfo.WriteWELCommand, NULL, 0u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* 2 - read the status register */ + if (HAL_OK != SAL_XSPI_SendReadCommand(&Object->sfdp_private.SALObject, SFDP_DRIVER_READ_STATUS_REGISTER_COMMAND, + (uint8_t *)&localValue[0], 1u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* 3 - update the status register to enable QPI mode*/ + localValue[0] = localValue[0] | 0x40u; + + /* 4 - write the status register with QPI mode to 1 */ + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, 0x1u, (uint8_t *)&localValue[0], 1u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* wait busy flag */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + retr = EXTMEM_SFDP_OK; + break; + } + case 0x3u: /* 011b: QE is bit 7 of status register 2. It is set via Write status register 2 instruction 3Eh + with one data byte where bit 7 is one. It is cleared via Write status register 2 + instruction 3Eh with one data byte where bit 7 is zero. + The status register 2 is read using instruction 3Fh.*/ + break; + case 0x4u: + { + /* 100b: QE is bit 1 of status register 2. It is set via Write Status with two data bytes + where bit 1 of the second byte is one. + It is cleared via Write Status with two data bytes where bit 1 of the second byte is zero. + In contrast to the 001b code, writing 1 byte to the status register does not modify status register 2.*/ + + /* Read the status register */ + if (HAL_OK != SAL_XSPI_SendReadCommand(&Object->sfdp_private.SALObject, 0x5, (uint8_t *)&localValue[0], 2u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Update the status register */ + localValue[1] |= 2u; + + /* WEL */ + if (HAL_OK != SAL_XSPI_SendReadCommand(&Object->sfdp_private.SALObject, + Object->sfdp_private.DriverInfo.WriteWELCommand, + NULL, 0u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Write the status register */ + if (HAL_OK != SAL_XSPI_CommandSendData(&Object->sfdp_private.SALObject, 0x1u, (uint8_t *)&localValue[0], 2u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Wait busy flag */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != driver_check_FlagBUSY(Object, 100)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + /* Optional : only for control read the status register and check write operation is OK */ + localValue[1] = 0xFF; + if (HAL_OK != SAL_XSPI_SendReadCommand(&Object->sfdp_private.SALObject, 0x5, (uint8_t *)&localValue[0], 2u)) + { + retr = EXTMEM_SFDP_ERROR_DRIVER; + goto error; + } + + retr = EXTMEM_SFDP_OK; + break; + } + case 0x5u: /* 101b: QE is bit 1 of the status register 2. Status register 1 is read using Read Status + instruction 05h. Status register 2 is read using instruction 35h. + QE is set via Write Status instruction 01h with two data bytes where bit 1 of + the second byte is one. It is cleared via Write Status with two data bytes + where bit 1 of the second byte is zero.*/ + break; + case 0x6u: /* 110b: QE is bit 1 of the status register 2. + Status register 1 is read using Read Status instruction 05h. + Status register 2 is read using instruction 35h, and status register 3 is read + using instruction 15h. QE is set via Write Status Register instruction 31h + with one data byte where bit 1 is one. + It is cleared via Write Status Register instruction 31h with one data byte where bit 1 is zero.*/ + break; + case 0x7u: /*111b: Reserved */ + break; + default :/* Added for Misra */ + break; + } +error : + return retr; +} + +/** + * @brief Manages the 4S-4S-4S enable sequence for the NOR memory device. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @return SFDP_StatusTypeDef: EXTMEM_SFDP_OK if successful, error code otherwise. + */ +SFDP_StatusTypeDef JEDEC_Basic_Manage4S4S4SEnableSequence(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_ERROR_NOTYETHANDLED; + uint8_t instruction = 0x00u; + + /* 4-4-4 mode enable sequences; This field describes the supported methods to enter 4-4-4 mode from 1-1-1 mode */ + /* x_xxx1b: set QE per QER description above, then issue instruction 38h */ + if ((JEDEC_Basic.Params.Param_DWORD.D15._4S4S4S_EnableSequence & 0x1u) == 0x1u) + { + retr = JEDEC_Basic_ManageQuadEnableRequirement(Object); + instruction = 0x38u; + } + /* x_x1xxb: issue instruction 35h */ + else if ((JEDEC_Basic.Params.Param_DWORD.D15._4S4S4S_EnableSequence & 0x4u) == 0x4u) + { + /* If QE bit exists, Quad Enable Requirement describes method to enable Quad operations */ + retr = JEDEC_Basic_ManageQuadEnableRequirement(Object); + instruction = 0x35u; + } + else + { + /* nothing to do managed as EXTMEM_SFDP_ERROR_NOTYETHANDLED */ + } + + /* + x_1xxxb: device uses a read-modify-write sequence of operations: read configuration + using instruction 65h followed by address 800003h, set bit 6, write configuration + using instruction 71h followed by address 800003h. This configuration is volatile. + 1_xxxxb: + 4-4-4 mode enable sequences + Device uses a read-modify-write sequence of operations: + Read Volatile Enhanced Configuration Register using instruction 65h, no address is required, reset bit 7 to 0. + Write Volatile Enhanced Configuration Register using instruction 61h, no address is required. + This configuration is volatile. + 4-4-4 mode disable sequences + Device uses a read-modify-write sequence of operations: + Read Volatile Enhanced Configuration Register using instruction 65h, no address is required, set bit 7 to 1. + Write Volatile Enhanced Configuration Register using instruction 61h, no address is required. + This configuration is volatile. + NOTE If device is in 0-4-4 mode, then this mode must be exited before the 4-4-4 enable sequence is issued. + */ + if ((retr == EXTMEM_SFDP_OK) && (instruction != 0u)) + { + (void)SAL_XSPI_SendReadCommand(&Object->sfdp_private.SALObject, instruction, NULL, 0u); + /* @note on memory W25Q64JV the command 38h does not exist so the control on command execution has been removed */ + retr = EXTMEM_SFDP_OK; + } + + return retr; +} + +/** + * @brief Checks the validity of the SFDP signature for the NOR memory device. + * @param Object Pointer to the NOR SFDP memory instance object descriptor. + * @param Signature Value of the SFDP signature to check. + * @return SFDP_StatusTypeDef: EXTMEM_SFDP_OK if valid, error code otherwise. + */ +SFDP_StatusTypeDef CheckSFDP_Signature(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint32_t Signature) +{ + SFDP_StatusTypeDef retr = EXTMEM_SFDP_ERROR_SIGNATURE; + + /* check the magic number */ + switch (Signature) + { + case SFDP_SIGNATURE : + SFDP_DEBUG_STR("signature of the header: OK"); + retr = EXTMEM_SFDP_OK; + break; + case SFDP_SIGNATURE_INVERTED : + SFDP_DEBUG_STR("signature of the header: KO inverted data order"); + /* Change the memory type settings */ + if (HAL_OK == SAL_XSPI_UpdateMemoryType(&Object->sfdp_private.SALObject, SAL_XSPI_ORDERINVERTED)) + { + retr = EXTMEM_SFDP_ERROR_SIGNATUREMTYPE; + } + break; + default : + SFDP_DEBUG_STR("signature of the header: KO"); + break; + } + return retr; +} +/** + * @} + */ + +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.h b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.h new file mode 100644 index 0000000..97615da --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.h @@ -0,0 +1,147 @@ +/** + ****************************************************************************** + * @file stm32_sfdp_data.h + * @author MCD Application Team + * @brief This file contains the sfdp functions prototypes. + ****************************************************************************** + * @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 __STM32_SFDP_DATA_H +#define __STM32_SFDP_DATA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if EXTMEM_SAL_XSPI == 1 +#include "../sal/stm32_sal_xspi_api.h" +#else +#error "the driver SFDP requires the enable of EXTMEM_SAL_XSPI" +#endif /* EXTMEM_SAL_XSPI_ENABLED */ + +/** + * @addtogroup NOR_SFDP_DATA + * @ingroup NOR_SFDP + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ + +/** + * @brief Maximum number of SFDP parameter in SFDP table + */ +#define SFDP_MAX_NB_OF_PARAM 10U + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup NOR_SFDP_DATA_Exported_Types Exported Types + * @ingroup NOR_SFDP_DATA + * @{ + */ + +/** + * @brief SFDP parameter table ID + */ +typedef enum +{ + SFDP_PARAMID_UNKNOWN = 0x00000U, + SFDP_PARAMID_VENDOR = 0x00001U, + SFDP_PARAMID_FUNCTION_VENDOR = 0x00002U, + SFDP_PARAMID_FUNCTION_JEDEC = 0x00004U, + SFDP_PARAMID_BASIC_SPIPROTOCOL = 0x00008U, + SFDP_PARAMID_SECTORMAP = 0x00010U, + SFDP_PARAMID_RPMC = 0x00020U, + SFDP_PARAMID_4BYTE_ADDRESS_INSTRUCTION = 0x00040U, + SFDP_PARAMID_XSPI_V1_0 = 0x00080U, + SFDP_PARAMID_XSPI_V2_0 = 0x00100U, + SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP = 0x00200U, + SFDP_PARAMID_STATUS_CONTROL_CONFIG_REGISTER_MAP_MULTICHIP = 0x00400U, + SFDP_PARAMID_STATUS_CONTROL_CONFIG_XSPI_V2_0 = 0x00800U, + SFDP_PARAMID_OCTAL_DDR = 0x01000U, + SFDP_PARAMID_MSPT = 0x02000U, + SFDP_PARAMID_X4QUAD_DS = 0x04000U, + SFDP_PARAMID_QUAD_DDR = 0x08000U, + SFDP_PARAMID_SECURE_PACKET_READ_WRITE = 0x10000U, + SFDP_PARAMID_RESERVED = 0x20000U +} SFDP_ParamID_TypeDef; + +/** + * @brief SFDP status typedef + */ +typedef enum +{ + EXTMEM_SFDP_OK, /*!< Status OK */ + EXTMEM_SFDP_ERROR_PARAM, + EXTMEM_SFDP_ERROR_NOREADFUNCTION, + EXTMEM_SFDP_ERROR_SFDPREAD, + EXTMEM_SFDP_ERROR_SIGNATURE, /*!< Signature is invalid */ + EXTMEM_SFDP_ERROR_SIGNATUREMTYPE, /*!< Signature is invalid due to wrong memory type */ + EXTMEM_SFDP_ERROR_PARAMTABLE_NOTFOUND, + EXTMEM_SFDP_ERROR_NO_PARAMTABLE_BASIC, + EXTMEM_SFDP_ERROR_NO_32BITADDRESSING, + EXTMEM_SFDP_ERROR_JEDECBASIC_D14, + EXTMEM_SFDP_ERROR_JEDECBASIC_D16, + EXTMEM_SFDP_ERROR_OCTALMODE, + EXTMEM_SFDP_ERROR_DRIVER, + EXTMEM_SFDP_ERROR_SETCLOCK, + EXTMEM_SFDP_ERROR_CONFIGDUMMY, + EXTMEM_SFDP_ERROR_NOTYETHANDLED +} SFDP_StatusTypeDef; + +/** + * @brief SFDP header + */ +typedef struct +{ + uint32_t Signature; /*!< Signature value */ + uint8_t Minor_revision; /*!< Minor revision */ + uint8_t Major_revision; /*!< Major revision */ + uint8_t param_number; /*!< Number of parameters */ + uint8_t AccessProtocol; /*!< Access protocol type */ +} SFDP_HeaderTypeDef; + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup NOR_SFDP_Data_Exported_Functions Exported Functions + * @{ + */ + +SFDP_StatusTypeDef SFDP_GetHeader(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, + SFDP_HeaderTypeDef *sfdp_header); +SFDP_StatusTypeDef SFDP_ReadHeader(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, + SFDP_HeaderTypeDef *sfdp_header); +SFDP_StatusTypeDef SFDP_CollectData(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object); +SFDP_StatusTypeDef SFDP_MemoryReset(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object); +SFDP_StatusTypeDef SFDP_BuildGenericDriver(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *Object, uint8_t *FreqUpdated); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_check_FlagBUSY(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Timeout); + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SFDP_DATA_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c new file mode 100644 index 0000000..e79a35f --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c @@ -0,0 +1,816 @@ +/** + ****************************************************************************** + * @file stm32_sfdp_driver.c + * @author MCD Application Team + * @brief This file includes a driver for SFDP support + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem_conf.h" + +#if EXTMEM_DRIVER_NOR_SFDP == 1 +#include "stm32_sfdp_driver_type.h" +#include "stm32_sfdp_driver_api.h" +#include "stm32_sfdp_data.h" +#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL != 0 && defined(EXTMEM_MACRO_DEBUG) +#include +#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL != 0 && EXTMEM_MACRO_DEBUG */ +#include + +/** @defgroup NOR_SFDP NOR SFDP driver + * @ingroup EXTMEM_DRIVER + * @{ + */ + + +/* Private Macros ------------------------------------------------------------*/ +/** @defgroup NOR_SFDP_Private_Macro DRIVER NOR SFDP Private Macro + * @{ + */ +/** + * @brief MIN macro + */ +#define MIN(_A_,_B_) ((_A_) > (_B_))?(_B_):(_A_); + +/** + * @brief Default timeout + */ +#define DRIVER_DEFAULT_TIMEOUT 300 + +/** + * @brief Default clock value to read SFDP data + */ +#define DRIVER_SFDP_DEFAULT_CLOCK 50000000u + +/** + * @brief DEBUG macro + */ +#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 1 && defined(EXTMEM_MACRO_DEBUG) +/** + * @brief Debug macro for a string + * @param _STR_ string + */ +#define SFDP_DEBUG_STR(_STR_) \ + { \ + EXTMEM_MACRO_DEBUG("\tSFDP::"); \ + EXTMEM_MACRO_DEBUG(_STR_); \ + EXTMEM_MACRO_DEBUG("\n\r"); \ + } + +/** + * @brief debug macro for low level + */ +#if EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 2 +#define DEBUG_DRIVER(_STR_) \ + { \ + EXTMEM_MACRO_DEBUG("\tSFDP::DRIVER::"); \ + EXTMEM_MACRO_DEBUG(_STR_); \ + EXTMEM_MACRO_DEBUG("\n"); \ + } +#else +#define DEBUG_DRIVER(_STR_) +#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 2 */ + +/** + * @brief debug macro for an integer + */ +#define DEBUG_ID(_ID_) \ + { \ + char StrID[40]; \ + EXTMEM_MACRO_DEBUG("\tSFDP:: Flash ID("); \ + (void)sprintf(StrID, "0x%x:0x%x:0x%x:0x%x", \ + _ID_[0],_ID_[1],_ID_[2],_ID_[3]); \ + EXTMEM_MACRO_DEBUG(StrID); \ + EXTMEM_MACRO_DEBUG(")\n"); \ + } + +/** + * @brief Debug macro for error + */ +#define DEBUG_DRIVER_ERROR(_STR_) SFDP_DEBUG_STR(_STR_) +#else +#define DEBUG_ID(_ID_) +#define SFDP_DEBUG_STR(_STR_) +#define DEBUG_DRIVER(_STR_) +#define DEBUG_DRIVER_ERROR(_STR_) +#endif /* EXTMEM_DRIVER_NOR_SFDP_DEBUG_LEVEL > 1 && EXTMEM_MACRO_DEBUG */ + +/** + * @} + */ + +/* Private typedefs ---------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup DRIVER_SFDP_Private_Functions DRIVER SFDP Private Functions + * @{ + */ +static EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_set_FlagWEL(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Timeout); +__weak void EXTMEM_MemCopy(uint32_t *Destination_Address, const uint8_t *ptrData, uint32_t DataSize); + +/** + * @} + */ + +/** @defgroup DRIVER_SFDP_Exported_Functions DRIVER SFDP Exported Functions + * @{ + */ + +/** + * @brief Initializes the NOR SFDP driver. + * @param Peripheral Pointer to peripheral. + * @param Config Configuration type. + * @param ClockInput Clock input value. + * @param SFDPObject Pointer to memory object. + * @retval EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef Status of the operation. + */ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config, + uint32_t ClockInput, + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK; + SFDP_HeaderTypeDef JEDEC_SFDP_Header; + uint8_t FreqUpdate = 0u; + uint8_t DataID[6]; + uint32_t ClockOut; + + /* Reset data of SFDPObject to zero */ + SFDP_DEBUG_STR("1 - reset data SFDPObject to zero") + (void)memset((void *)&SFDPObject->sfdp_private, 0x0, sizeof(SFDPObject->sfdp_private)); + + /* Initialize the SFDPObject */ + SFDP_DEBUG_STR("2 - initialize the SFDPObject") + SFDPObject->sfdp_private.Config = Config; + SFDPObject->sfdp_private.DriverInfo.SpiPhyLink = PHY_LINK_1S1S1S; + SFDPObject->sfdp_private.DriverInfo.ClockIn = ClockInput; + SAL_XSPI_SET_SFDPDUMMYCYLE(SFDPObject->sfdp_private.SALObject, EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_DEFAULT); + + /* Set memory speed to 50Mhz maximum */ + SFDP_DEBUG_STR("3 - set memory link and speed to 50Mhz maximum") + (void)SAL_XSPI_Init(&SFDPObject->sfdp_private.SALObject, Peripheral); + (void)SAL_XSPI_SetClock(&SFDPObject->sfdp_private.SALObject, ClockInput, DRIVER_SFDP_DEFAULT_CLOCK, &ClockOut); + + /* Abort any ongoing XSPI action */ + (void)SAL_XSPI_DisableMapMode(&SFDPObject->sfdp_private.SALObject); + + /* Analyze the SFDP structure to get driver information */ + SFDP_DEBUG_STR("4 - analyze the SFDP structure to get driver information") + if (EXTMEM_SFDP_OK != SFDP_GetHeader(SFDPObject, &JEDEC_SFDP_Header)) + { + /* Perform SFDP Header reading (several modes are tried) */ + SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP; + goto error; + } + + /* Reset the memory */ + SFDP_DEBUG_STR("5 - reset the memory") + if (EXTMEM_SFDP_OK != SFDP_MemoryReset(SFDPObject)) + { + /* Memory Reset is considered unsuccessful. + Try to continue Initialisation procedure anyway. */ + SFDP_DEBUG_STR("ERROR::on the call of SFDP_MemoryReset but no error returned") + } + + /* Wait few ms after the reset operation, this is done to avoid issue on SFDP read */ + HAL_Delay(10); + + /* Analyze the SFDP structure to get driver information after the reset */ + SFDP_DEBUG_STR("6 - analyze the SFDP structure to get driver information") + if (EXTMEM_SFDP_OK != SFDP_GetHeader(SFDPObject, &JEDEC_SFDP_Header)) + { + /* SFDP header reading is considered unsuccessful. + Abort Initialisation procedure. */ + SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP; + goto error; + } + + /* Save information from the SFDP table + Nb of parameters starts at 0 (0 means 1 parameter) */ + if (JEDEC_SFDP_Header.param_number >= SFDP_MAX_NB_OF_PARAM) + { + SFDPObject->sfdp_private.Sfdp_param_number = SFDP_MAX_NB_OF_PARAM - 1; + } + else + { + SFDPObject->sfdp_private.Sfdp_param_number = JEDEC_SFDP_Header.param_number; + } + SFDPObject->sfdp_private.Sfdp_AccessProtocol = JEDEC_SFDP_Header.AccessProtocol; + + /* Read the flash ID. + This Flash ID could later be used to perform specific operations for some identified references. */ + SFDP_DEBUG_STR("7 - read the flash ID") + (void)SAL_XSPI_GetId(&SFDPObject->sfdp_private.SALObject, DataID, EXTMEM_READ_JEDEC_ID_SIZE); + DEBUG_ID(DataID); + + /* Keep manufacturer information, it could be used to help in + building of consistent driver */ + SFDPObject->sfdp_private.ManuID = DataID[0]; + + /* Get the complete SFDP data */ + SFDP_DEBUG_STR("8 - collect the SFDP data") + if (EXTMEM_SFDP_OK != SFDP_CollectData(SFDPObject)) + { + SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP; + goto error; + } + + /* Setup the generic driver information and prepare the physical layer */ + SFDP_DEBUG_STR("9 - build the generic driver information and prepare the physical layer") + if (EXTMEM_SFDP_OK != SFDP_BuildGenericDriver(SFDPObject, &FreqUpdate)) + { + SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_ERROR_BUILD") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_BUILD; + goto error; + } + + /* Adjust frequency supplied to memory, if required */ + SFDP_DEBUG_STR("10 - adjust the frequency if required") + if ((FreqUpdate == 0u) && (SFDPObject->sfdp_public.MaxFreq != 0u)) + { + (void)SAL_XSPI_SetClock(&SFDPObject->sfdp_private.SALObject, ClockInput, + SFDPObject->sfdp_public.MaxFreq, &ClockOut); + SFDP_DEBUG_STR("--> new freq configured"); + } + + /* Read again SFDP header to confirm memory access is properly setup */ + SFDP_DEBUG_STR("11 - read again the SFDP header to adjust memory type if necessary") + if (EXTMEM_SFDP_OK != SFDP_ReadHeader(SFDPObject, &JEDEC_SFDP_Header)) + { + SFDP_DEBUG_STR("ERROR::EXTMEM_DRIVER_NOR_SFDP_MEMTYPE_CHECK") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_MEMTYPE_CHECK; + goto error; + } + +error: + return retr; +} + +/** + * @brief This function un-initializes the NOR SFDP driver + * + * @param SFDPObject Memory object + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_DeInit(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject) +{ + SFDPObject->sfdp_private.FlashSize = 0; + return EXTMEM_DRIVER_NOR_SFDP_OK; +} + +/** + * @brief This function returns the flash memory information + * + * @param SFDPObject Memory object + * @param FlashInfo Pointer on flash info structure + **/ +void EXTMEM_DRIVER_NOR_SFDP_GetFlashInfo(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + EXTMEM_NOR_SFDP_FlashInfoTypeDef *FlashInfo) +{ + DEBUG_DRIVER((uint8_t *)__func__) + /* Format the info into structure */ + FlashInfo->FlashSize = SFDPObject->sfdp_private.FlashSize; + FlashInfo->PageSize = SFDPObject->sfdp_private.PageSize; + FlashInfo->EraseType1Size = (SFDPObject->sfdp_private.DriverInfo.EraseType1Size == 0u) ? 0u : + ((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType1Size); + FlashInfo->EraseType2Size = (SFDPObject->sfdp_private.DriverInfo.EraseType2Size == 0u) ? 0u : + ((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType2Size); + FlashInfo->EraseType3Size = (SFDPObject->sfdp_private.DriverInfo.EraseType3Size == 0u) ? 0u : + ((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType3Size); + FlashInfo->EraseType4Size = (SFDPObject->sfdp_private.DriverInfo.EraseType4Size == 0u) ? 0u : + ((uint32_t)1u << SFDPObject->sfdp_private.DriverInfo.EraseType4Size); +} + +/** + * @brief This function reads the memory + * + * @param SFDPObject Memory object + * @param Address Memory address + * @param Data Pointer on the data + * @param Size Data size to read (in bytes) + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Read(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Address, uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr; + DEBUG_DRIVER((uint8_t *)__func__) + + /* Check busy flag */ + retr = driver_check_FlagBUSY(SFDPObject, 5000); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Read::ERROR_CHECK_BUSY") + goto error; + } + + /* Perform read access using SAL service */ + if (HAL_OK != SAL_XSPI_Read(&SFDPObject->sfdp_private.SALObject, SFDPObject->sfdp_private.DriverInfo.ReadInstruction, + Address, Data, Size)) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Read::ERROR_READ") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_READ; + } +error : + return retr; +} + +/** + * @brief This function writes data in the memory + * + * @param SFDPObject Memory object + * @param Address Memory address + * @param Data Pointer on the data + * @param Size Data size to write + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Write(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Address, const uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr; + uint32_t size_write; + uint32_t local_size = Size; + uint32_t local_Address = Address; + uint32_t local_Data = (uint32_t)Data; + uint32_t misalignment = 0u; + + if (0u != (local_Address % SFDPObject->sfdp_private.PageSize)) + { + misalignment = 1u; + } + + DEBUG_DRIVER((uint8_t *)__func__) + while (local_size != 0u) + { + if (misalignment == 1u) + { + size_write = SFDPObject->sfdp_private.PageSize - (local_Address % SFDPObject->sfdp_private.PageSize); + size_write = MIN(local_size, size_write); + misalignment = 0u; + } + else + { + size_write = MIN(local_size, SFDPObject->sfdp_private.PageSize); + } + + /* Check WIP flag */ + retr = driver_check_FlagBUSY(SFDPObject, 5000u); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_CHECK_BUSY") + goto error; + } + + /* Wait for WEL flag */ + retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_CHECK_WEL") + goto error; + } + + /* Write the data */ + if (HAL_OK != SAL_XSPI_Write(&SFDPObject->sfdp_private.SALObject, + SFDPObject->sfdp_private.DriverInfo.PageProgramInstruction, + local_Address, (uint8_t *)local_Data, size_write)) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_WRITE") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITE; + goto error; + } + + local_size = local_size - size_write; + local_Address = local_Address + size_write; + local_Data = local_Data + size_write; + } + + /* Check busy flag */ + retr = driver_check_FlagBUSY(SFDPObject, 5000); +#if EXTMEM_MACRO_DEBUG + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_Write::ERROR_CHECK_BUSY_ON_EXIT") + } +#endif /* EXTMEM_MACRO_DEBUG */ + +error: + return retr; +} + +/** + * @brief This function writes data in the memory in mapped mode + * + * @param SFDPObject Memory object + * @param Address Memory address in mapped mode + * @param Data Pointer on the data + * @param Size Data size to write + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_WriteInMappedMode(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef + *SFDPObject, uint32_t Address, + const uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK; + uint32_t size_write; + uint32_t local_size = Size; + uint32_t local_Address = Address; + const uint8_t *local_Data = Data; + uint32_t size; + uint32_t misalignment = 0u; +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint8_t dcache_status = 1; +#endif /* __DCACHE_PRESENT */ + + DEBUG_DRIVER((uint8_t *)__func__) + + /* Check if the input address is 32bit aligned */ + if (0u != (local_Address % 4u)) + { + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_ADDRESS_ALIGNMENT; + goto error; + } + + if (0u != (local_Address % SFDPObject->sfdp_private.PageSize)) + { + misalignment = 1u; + } + +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + /* Check if DCache is already enabled */ + if (SCB->CCR & SCB_CCR_DC_Msk) + { + dcache_status = 1; + } + else + { + dcache_status = 0; + /* Enable DCache */ + SCB_EnableDCache(); + } +#endif /* __DCACHE_PRESENT */ + + while (local_size != 0u) + { + if (misalignment == 1u) + { + size_write = SFDPObject->sfdp_private.PageSize - (local_Address % SFDPObject->sfdp_private.PageSize); + size_write = MIN(local_size, size_write); + misalignment = 0u; + } + else + { + if (local_size > SFDPObject->sfdp_private.PageSize) + { + size_write = SFDPObject->sfdp_private.PageSize; + } + else + { + size_write = local_size; + if (0u != (local_size % sizeof(uint32_t))) + { + size_write = size_write + sizeof(uint32_t) - (local_size % sizeof(uint32_t)); + } + } + } + + /* Wait for Write enable flag */ + retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_write::ERROR_CHECK_WEL") + goto error; + } + + /* Enter the mapped mode */ + retr = EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode(SFDPObject); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + goto error; + } + + size = size_write; + /* Execute the copy */ + EXTMEM_MemCopy((uint32_t *)local_Address, local_Data, size_write); + +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + /* Clean DCache starting from a 32 byte aligned address in 32 byte granularity */ + SCB_CleanDCache_by_Addr((void *)(local_Address), size_write); +#endif /* __DCACHE_PRESENT */ + + /* Enter the mapped mode */ + retr = EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode(SFDPObject); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + goto error; + } + + /* Check busy flag */ + retr = driver_check_FlagBUSY(SFDPObject, 5000); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_write::ERROR_CHECK_BUSY_ON_EXIT") + goto error; + } + + /* Decrement the transfer size */ + if (local_size > size) + { + local_size = local_size - size; + local_Data = &local_Data[size]; + local_Address = local_Address + size; + } + else + { + local_size = 0; + } + } + +error: + +#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + /* Disable DCache if deactivated previously */ + if (!dcache_status) + { + SCB_DisableDCache(); + } +#endif /* __DCACHE_PRESENT */ + + return retr; +} + +/** + * @brief This function erases all the memory + * + * @param SFDPObject Memory object + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_MassErase(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr; + DEBUG_DRIVER((uint8_t *)__func__) + + /* Check busy flag */ + retr = driver_check_FlagBUSY(SFDPObject, 1000); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_read::ERROR_CHECK_BUSY") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_FLASHBUSY; + goto error; + } + + /* Wait for write enable flag */ + retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_read::ERROR_CHECK_WEL") + goto error; + } + + /* Launch mass erase command */ + (void)SAL_XSPI_CommandSendData(&SFDPObject->sfdp_private.SALObject, SFDP_DRIVER_ERASE_CHIP_COMMAND, NULL, 0); + + + /* Check busy flag : time to used should be set according the memory characteristic */ + retr = driver_check_FlagBUSY(SFDPObject, SFDPObject->sfdp_private.DriverInfo.EraseChipTiming); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + DEBUG_DRIVER_ERROR("EXTMEM_DRIVER_NOR_SFDP_MassErase::ERROR_CHECK_BUSY_ON_EXIT") + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_ERASE_TIMEOUT; + goto error; + } + +error: + return retr; +} + +/** + * @brief This function erases memory sector + * + * @param SFDPObject Memory object + * @param Address Memory address to start erase operation + * @param SectorType Type of sector + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_SectorErase(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef + *SFDPObject, uint32_t Address, + EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef + SectorType) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr; + uint8_t command; + uint8_t size; + uint32_t timeout; + DEBUG_DRIVER((uint8_t *)__func__) + + /* Check if the selected sector type is available */ + switch (SectorType) + { + case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1: + command = SFDPObject->sfdp_private.DriverInfo.EraseType1Command; + size = SFDPObject->sfdp_private.DriverInfo.EraseType1Size; + timeout = SFDPObject->sfdp_private.DriverInfo.EraseType1Timing; + break; + case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE2: + command = SFDPObject->sfdp_private.DriverInfo.EraseType2Command; + size = SFDPObject->sfdp_private.DriverInfo.EraseType2Size; + timeout = SFDPObject->sfdp_private.DriverInfo.EraseType2Timing; + break; + case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE3: + command = SFDPObject->sfdp_private.DriverInfo.EraseType3Command; + size = SFDPObject->sfdp_private.DriverInfo.EraseType3Size; + timeout = SFDPObject->sfdp_private.DriverInfo.EraseType3Timing; + break; + case EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE4: + command = SFDPObject->sfdp_private.DriverInfo.EraseType4Command; + size = SFDPObject->sfdp_private.DriverInfo.EraseType4Size; + timeout = SFDPObject->sfdp_private.DriverInfo.EraseType4Timing; + break; + default : + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE; + goto error; + break; + } + + /* Check if the command for this sector size is available */ + if (0x0u == command) + { + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE_UNAVAILABLE; + goto error; + } + + /* Check address alignment */ + if (0x0u != (Address % ((uint32_t)1u << size))) + { + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_ADDRESS_ALIGNMENT; + goto error; + } + + /* Check busy flag */ + retr = driver_check_FlagBUSY(SFDPObject, 5000u); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + goto error; + } + + /* Wait for write enable flag */ + retr = driver_set_FlagWEL(SFDPObject, DRIVER_DEFAULT_TIMEOUT); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + goto error; + } + + /* Launch erase command */ + (void)SAL_XSPI_CommandSendAddress(&SFDPObject->sfdp_private.SALObject, command, Address); + + /* Check busy flag */ + /* Timeout is set according the memory characteristic */ + retr = driver_check_FlagBUSY(SFDPObject, timeout); + if (EXTMEM_DRIVER_NOR_SFDP_OK != retr) + { + goto error; + } + + +error: + return retr; +} + +/** + * @brief This function enables the memory mapped mode + * + * @param SFDPObject Memory object + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode( + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK; + + /* Enter the mapped mode */ + if (HAL_OK != SAL_XSPI_EnableMapMode(&SFDPObject->sfdp_private.SALObject, + SFDPObject->sfdp_private.DriverInfo.ReadInstruction, + (uint8_t)SFDPObject->sfdp_private.SALObject.Commandbase.DummyCycles, + SFDPObject->sfdp_private.DriverInfo.PageProgramInstruction, 0)) + { + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_MAP_ENABLE; + } + + return retr; +} + +/** + * @brief This function disables the memory mapped mode + * + * @param SFDPObject Memory object + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode( + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_OK; + + /* Exit the mapped mode */ + if (HAL_OK != SAL_XSPI_DisableMapMode(&SFDPObject->sfdp_private.SALObject)) + { + retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_MAP_ENABLE; + } + + return retr; +} + + +/** + * @} + */ + +/** @addtogroup DRIVER_SFDP_Internal_Functions DRIVER SFDP Internal Functions + * @{ + */ + + +/** + * @} + */ + +/** @addtogroup DRIVER_SFDP_Private_Functions DRIVER SFDP Private Functions + * @{ + */ + +/** + * @brief This function enables the WEL Flag and checks its activation + * + * @param SFDPObject Memory object + * @param timeout Timeout value + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef driver_set_FlagWEL(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Timeout) +{ + EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef retr = EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITEENABLE; + DEBUG_DRIVER((uint8_t *)__func__) + + /* Send the command write enable */ + (void)SAL_XSPI_CommandSendData(&SFDPObject->sfdp_private.SALObject, + SFDPObject->sfdp_private.DriverInfo.WriteWELCommand, NULL, 0); + + /* Wait for write enable status */ + if (0u != SFDPObject->sfdp_private.DriverInfo.ReadWELCommand) + { + /* Check if flag write enable is enabled */ + if (HAL_OK == SAL_XSPI_CheckStatusRegister(&SFDPObject->sfdp_private.SALObject, + SFDPObject->sfdp_private.DriverInfo.ReadWELCommand, + SFDPObject->sfdp_private.DriverInfo.WELAddress, + ((SFDPObject->sfdp_private.DriverInfo.WELBusyPolarity == 0u) ? 1u : 0u) + << SFDPObject->sfdp_private.DriverInfo.WELPosition, + 1u << SFDPObject->sfdp_private.DriverInfo.WELPosition, + SFDPObject->sfdp_private.ManuID, Timeout)) + { + retr = EXTMEM_DRIVER_NOR_SFDP_OK; + } + } + return retr; +} + +/** + * @brief This function provides a default implementation of MemCopy functionality + * + * @param Destination_Address Destination Address where data is to be copied + * @param ptrData Pointer on source data to be copied + * @param DataSize Size of data to be copied (in bytes) + * @return @ref EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef + **/ +__weak void EXTMEM_MemCopy(uint32_t *Destination_Address, const uint8_t *ptrData, uint32_t DataSize) +{ + uint32_t *ptrDest = Destination_Address; + /* Write the data */ + for (uint32_t index = 0u; index < DataSize; index = index + 4u) + { + *ptrDest = ((uint32_t)ptrData[index] | ((uint32_t)ptrData[index + 1u] << 8u) | + ((uint32_t)ptrData[index + 2u] << 16u) | ((uint32_t)ptrData[index + 3u] << 24u)); + ptrDest++; + } +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_api.h b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_api.h new file mode 100644 index 0000000..fe3746f --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_api.h @@ -0,0 +1,121 @@ +/** + ****************************************************************************** + * @file stm32_sfdp_driver_api.h + * @author MCD Application Team + * @brief This file contains the sfdp driver definition. + ****************************************************************************** + * @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 __STM32_NOR_SFDP_DRIVER_API_H +#define __STM32_NOR_SFDP_DRIVER_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** @addtogroup NOR_SFDP + * @ingroup EXTMEM_DRIVER + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup DRIVER_SFDP_Exported_Types DRIVER SFDP Memory Exported Types + * @{ + */ + + +/** + * @brief List of error codes for the SFDP driver. + */ +typedef enum +{ + EXTMEM_DRIVER_NOR_SFDP_OK = 0, + EXTMEM_DRIVER_NOR_SFDP_ERROR_SFDP = -1, + EXTMEM_DRIVER_NOR_SFDP_ERROR_READ = -2, + EXTMEM_DRIVER_NOR_SFDP_ERROR_BUILD = -3, + EXTMEM_DRIVER_NOR_SFDP_ERROR_UNKNOWN_COMMAND = -4, + EXTMEM_DRIVER_NOR_SFDP_ERROR_BUSY = -5, + EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITEENABLE = -6, + EXTMEM_DRIVER_NOR_SFDP_ERROR_WRITE = -7, + EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE = -8, + EXTMEM_DRIVER_NOR_SFDP_ERROR_SECTORTYPE_UNAVAILABLE = -9, + EXTMEM_DRIVER_NOR_SFDP_ERROR_ADDRESS_ALIGNMENT = -10, + EXTMEM_DRIVER_NOR_SFDP_ERROR_ERASE_TIMEOUT = -11, + EXTMEM_DRIVER_NOR_SFDP_ERROR_FLASHBUSY = -12, + EXTMEM_DRIVER_NOR_SFDP_ERROR_MAP_ENABLE = -13, + EXTMEM_DRIVER_NOR_SFDP_ERROR_MEMTYPE_CHECK = -14, + EXTMEM_DRIVER_NOR_SFDP_ERROR = -128, +} EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef; + +/** + * @brief List of sector types for the SFDP driver. + */ +typedef enum +{ + EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1, + EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE2, + EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE3, + EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE4 +} EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef; + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** + * @addtogroup DRIVER_SFDP_Exported_Functions DRIVER SFDP exported functions + * @{ + */ +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config, + uint32_t ClockInput, + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_DeInit(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject); +void EXTMEM_DRIVER_NOR_SFDP_GetFlashInfo(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + EXTMEM_NOR_SFDP_FlashInfoTypeDef *FlashInfo); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Read(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Address, uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Write(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject, + uint32_t Address, const uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_WriteInMappedMode(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef + *SFDPObject, uint32_t Address, + const uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_MassErase(EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_SectorErase( + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef + *SFDPObject, uint32_t Address, + EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef SectorType); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode( + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject); +EXTMEM_DRIVER_NOR_SFDP_StatusTypeDef EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode( + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *SFDPObject); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_NOR_SFDP_DRIVER_API_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_type.h b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_type.h new file mode 100644 index 0000000..c4c3c07 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver_type.h @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * @file stm32_sfdp_driver_type.h + * @author MCD Application Team + * @brief This file contains the sfdp driver definition. + ****************************************************************************** + * @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 __STM32_SFDP_DRIVER_TYPE_H +#define __STM32_SFDP_DRIVER_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +/** @addtogroup NOR_SFDP + * @ingroup EXTMEM_DRIVER + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** + * @brief Instruction ID for common JEDEC commands + */ +#define SFDP_DRIVER_READ_COMMAND 0x03U + +#define SFDP_DRIVER_PAGE_PROGRAM_COMMAND 0x02U + +#define SFDP_DRIVER_READ_STATUS_REGISTER_COMMAND 0x05U + +#define SFDP_DRIVER_WRITE_ENABLE_50H_COMMAND 0x50U +#define SFDP_DRIVER_WRITE_ENABLE_06H_COMMAND 0x06U + +#define SFDP_DRIVER_ERASE_CHIP_COMMAND 0x60U + + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup DRIVER_SFDP_Exported_Types DRIVER SFDP Memory Exported Types + * @{ + */ + +/** + * @brief driver data used to manage the flash + */ +typedef struct +{ + + SAL_XSPI_PhysicalLinkTypeDef SpiPhyLink; /*!< Physical link information */ + uint32_t ClockIn; /*!< Input Clock */ + + /* Table of instructions (an instruction equal to zero means not supported) */ + /* WIP : write in progress */ + uint8_t ReadWIPCommand; /*!< Read write in progress command */ + uint8_t WIPPosition; /*!< Write in progress byte position */ + uint8_t WIPBusyPolarity; /*!< 0: Positive (WIP=1 means write is in progress) + 1: Inverted (WIP=0 means write is in progress) */ + uint8_t WIPAddress; /*!< Read write in progress address */ + + /* WEL: write enable */ + uint8_t WriteWELCommand; /*!< Write enable command */ + + /* WEL : read write enable */ + uint8_t ReadWELCommand; /*!< Read write enable status command */ + uint8_t WELPosition; /*!< Write enable position */ + uint8_t WELBusyPolarity; /*!< 0: Positive (WEL=1 means write is enabled) + 1: Inverted (WEL=0 means write is enabled) */ + uint8_t WELAddress; /*!< write enable address */ + + /* Page Program */ + uint8_t PageProgramInstruction; /*!< Page program command */ + + /* Read management */ + uint8_t ReadInstruction; /*!< Read command */ + + /* Erase management */ + uint8_t EraseType1Size; /*!< Erase 1 size */ + uint8_t EraseType1Command; /*!< Erase 1 command */ + uint8_t EraseType2Size; /*!< Erase 2 size */ + uint8_t EraseType2Command; /*!< Erase 2 command */ + uint8_t EraseType3Size; /*!< Erase 3 size */ + uint8_t EraseType3Command; /*!< Erase 3 command */ + uint8_t EraseType4Size; /*!< Erase 4 size */ + uint8_t EraseType4Command; /*!< Erase 4 command */ + + uint32_t EraseType1Timing; /*!< Erase 1 timing */ + uint32_t EraseType2Timing; /*!< Erase 2 timing */ + uint32_t EraseType3Timing; /*!< Erase 3 timing */ + uint32_t EraseType4Timing; /*!< Erase 4 timing */ + uint32_t EraseChipTiming; /*!< Erase chip timing */ +} EXTMEM_DRIVER_NOR_SFDP_InfoTypeDef; + + +/** + * @brief driver SFDP Object definition + */ +typedef struct +{ + struct + { + uint32_t MaxFreq; /*!< Maximum frequency supported by the memory. + @note If the value is zero, the parameter is ignored. */ + uint8_t DtrReadDummyCycle; /*!< Number of dummy cycles for DTR read command. + @note Used only for JEDEC basic with DTR option. */ + } sfdp_public; + struct + { + SAL_XSPI_ObjectTypeDef SALObject; /*!< Instance of the memory */ + EXTMEM_LinkConfig_TypeDef Config; /*!< Memory configuration */ + uint8_t ManuID; /*!< Manufacturer ID */ + uint8_t FlashSize; /*!< Flash size as a power of two */ + uint32_t PageSize; /*!< Page size */ + EXTMEM_DRIVER_NOR_SFDP_InfoTypeDef DriverInfo; /*!< Driver information */ + uint32_t Sfdp_table_mask; /*!< Sfdp table mask */ + uint32_t Reset_info; /*!< Copy of JEDEC Basic 16 Reset/Rescue info */ + uint8_t Sfdp_param_number; /*!< Number of parameters from the SFDP header table */ + uint8_t Sfdp_AccessProtocol; /*!< Access protocol type from the SFDP header table */ + } sfdp_private; +} EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef; + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** + * @addtogroup DRIVER_SFDP_Exported_Functions DRIVER SFDP exported functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SFDP_DRIVER_TYPE_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c b/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c new file mode 100644 index 0000000..b9eb211 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c @@ -0,0 +1,283 @@ +/** + ****************************************************************************** + * @file stm32_psram_driver.c + * @author MCD Application Team + * @brief This file implements the PSRAM driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem.h" +#include "stm32_extmem_conf.h" +#if EXTMEM_DRIVER_PSRAM == 1 +#if EXTMEM_SAL_XSPI == 1 +#include "../sal/stm32_sal_xspi_api.h" +#else +#error "the driver PSRAM requires the enable of EXTMEM_SAL_XSPI" +#endif /* EXTMEM_SAL_XSPI */ +#include "stm32_psram_driver_api.h" +#if EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) +#include +#endif /* EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && EXTMEM_MACRO_DEBUG */ + +/** @defgroup PSRAM PSRAM driver + * @ingroup EXTMEM_DRIVER + * @{ + */ + +/* Private Macro ------------------------------------------------------------*/ +/** @defgroup PSRAM_Private_Macro Private Macro + * @{ + */ + +/** + * @brief Default Timeout value (ms) + */ +#define DRIVER_DEFAULT_TIMEOUT 300 + +#if EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) +/** + * @brief Debug macro for a string + */ +#define DEBUG_STR(_STR_) { \ + EXTMEM_MACRO_DEBUG("\tPSRAM::"); \ + EXTMEM_MACRO_DEBUG(_STR_); \ + EXTMEM_MACRO_DEBUG("\n\r"); \ + } +#else +/** + * @brief Debug macro for a string + */ +#define DEBUG_STR(_STR_) +#endif /* EXTMEM_DRIVER_PSRAM_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) */ + +/** + * @} + */ + +/* Private typedefs ---------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup PSRAM_Private_Functions Private Functions + * @{ + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef PSRAM_ExecuteCommand(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject, uint8_t Index); +/** + * @} + */ + +/** @defgroup PSRAM_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the PSRAM driver. + * @param Peripheral Pointer to the peripheral handle. + * @param Config Link configuration. + * @param ClockInput Input clock frequency. + * @param PsramObject Pointer to the PSRAM driver object. + * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config, + uint32_t ClockInput, + EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject) +{ + EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; + uint32_t ClockOut; + SAL_XSPI_PhysicalLinkTypeDef linkvalue; + + /* Initialize the instance */ + DEBUG_STR("initialize the instance") + + /* Initialize XSPI low layer */ + (void)SAL_XSPI_Init(&PsramObject->psram_private.SALObject, Peripheral); + + /* Abort any ongoing XSPI action */ + (void)SAL_XSPI_DisableMapMode(&PsramObject->psram_private.SALObject); + + /* Set the frequency prescaler */ + DEBUG_STR("set memory speed according freqIn and freqMax supported by the memory") + if (HAL_OK != SAL_XSPI_SetClock(&PsramObject->psram_private.SALObject, ClockInput, PsramObject->psram_public.FreqMax, + &ClockOut)) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR; + goto error; + } + + /* Set the memory size */ + DEBUG_STR("set memory size according") + (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_FLASHSIZE, + &PsramObject->psram_public.MemorySize); + + /* Set the memory size */ + DEBUG_STR("set xspi link config") + linkvalue = PHY_LINK_RAM8; + (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_PHY_LINK, &linkvalue); + + /* Set the configuration to perform register operation */ + (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_DUMMY_CYCLES, + &PsramObject->psram_public.REG_DummyCycle); + + /* Execute the command sequence */ + for (uint8_t command_index = 0u; command_index < PsramObject->psram_public.NumberOfConfig; command_index++) + { + retr = PSRAM_ExecuteCommand(PsramObject, command_index); + if (retr != EXTMEM_DRIVER_PSRAM_OK) + { + goto error; + } + } + + switch (Config) + { + case EXTMEM_LINK_CONFIG_16LINES: + linkvalue = PHY_LINK_RAM16; + (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_PHY_LINK, &linkvalue); + break; + + case EXTMEM_LINK_CONFIG_8LINES: + linkvalue = PHY_LINK_RAM8; + (void)SAL_XSPI_MemoryConfig(&PsramObject->psram_private.SALObject, PARAM_PHY_LINK, &linkvalue); + break; + + default: + retr = EXTMEM_DRIVER_PSRAM_ERROR; + goto error; + break; + } + +error: + return retr; +} + +/** + * @brief Deinitializes the PSRAM driver. + * @param PsramObject Pointer to the PSRAM driver object. + * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_DeInit(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject) +{ + /* Abort any ongoing XSPI action */ + (void)SAL_XSPI_DisableMapMode(&PsramObject->psram_private.SALObject); + return EXTMEM_DRIVER_PSRAM_OK; +} + +/** + * @brief Enables memory-mapped mode for the PSRAM device. + * @param PsramObject Pointer to the PSRAM driver object. + * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Enable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef + *PsramObject) +{ + EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; + + /* Configure the read wrap mode */ + if (HAL_OK != SAL_XSPI_ConfigureWrappMode(&PsramObject->psram_private.SALObject, + PsramObject->psram_public.WrapRead_command, + PsramObject->psram_public.Write_DummyCycle)) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR_MAP_ENABLE; + } + + /* Enable memory mapped mode */ + if (HAL_OK != SAL_XSPI_EnableMapMode(&PsramObject->psram_private.SALObject, + PsramObject->psram_public.Read_command, + PsramObject->psram_public.Read_DummyCycle, + PsramObject->psram_public.Write_command, + PsramObject->psram_public.Write_DummyCycle)) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR_MAP_ENABLE; + } + return retr; +} + +/** + * @brief Disables memory-mapped mode for the PSRAM device. + * @param PsramObject Pointer to the PSRAM driver object. + * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Disable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef + *PsramObject) +{ + EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; + + /* Disable memory mapped mode */ + if (HAL_OK != SAL_XSPI_DisableMapMode(&PsramObject->psram_private.SALObject)) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR_MAP_DISABLE; + } + return retr; +} + +/** + * @} + */ + +/** @addtogroup PSRAM_Private_Functions + * @{ + */ + +/** + * @brief Executes a configuration command for the PSRAM device. + * + * @param PsramObject Pointer to the PSRAM driver object. + * @param Index Index of the command to execute. + * @retval @ref EXTMEM_DRIVER_PSRAM_StatusTypeDef + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef PSRAM_ExecuteCommand(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject, uint8_t Index) +{ + EXTMEM_DRIVER_PSRAM_StatusTypeDef retr = EXTMEM_DRIVER_PSRAM_OK; + uint8_t regval[2]; + + if (PsramObject->psram_public.ReadREGSize > 2u) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR_REGSIZE; + goto error; + } + + if (HAL_OK != SAL_XSPI_Read(&PsramObject->psram_private.SALObject, + PsramObject->psram_public.ReadREG, + PsramObject->psram_public.config[Index].REGAddress, + regval, PsramObject->psram_public.ReadREGSize)) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR_READREG; + goto error; + } + + MODIFY_REG(regval[0], + PsramObject->psram_public.config[Index].WriteMask, + PsramObject->psram_public.config[Index].WriteValue); + + if (HAL_OK != SAL_XSPI_Write(&PsramObject->psram_private.SALObject, + PsramObject->psram_public.WriteREG, + PsramObject->psram_public.config[Index].REGAddress, + regval, PsramObject->psram_public.ReadREGSize)) + { + retr = EXTMEM_DRIVER_PSRAM_ERROR_WRITEREG; + goto error; + } + +error: + return retr; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_api.h b/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_api.h new file mode 100644 index 0000000..91a20f8 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_api.h @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * @file stm32_psram_driver_api.h + * @author MCD Application Team + * @brief This file contains PSRAM driver API definitions. + ****************************************************************************** + * @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 __STM32_PSRAM_DRIVER_H +#define __STM32_PSRAM_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if EXTMEM_DRIVER_PSRAM == 1 + +/** @addtogroup PSRAM + * @ingroup EXTMEM_DRIVER + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup PSRAM_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Enumeration of error codes for the PSRAM driver. + */ +typedef enum +{ + EXTMEM_DRIVER_PSRAM_OK = 0, + EXTMEM_DRIVER_PSRAM_ERROR_READREG = -1, + EXTMEM_DRIVER_PSRAM_ERROR_WRITEREG = -2, + EXTEM_DRIVER_PSRAM_ERROR_READ = -3, + EXTEM_DRIVER_PSRAM_ERROR_WRITE = -4, + EXTMEM_DRIVER_PSRAM_ERROR_MAP_ENABLE = -5, + EXTMEM_DRIVER_PSRAM_ERROR_MAP_DISABLE = -6, + EXTMEM_DRIVER_PSRAM_ERROR_REGSIZE = -7, + EXTMEM_DRIVER_PSRAM_ERROR = -128, +} EXTMEM_DRIVER_PSRAM_StatusTypeDef; + +/* Exported functions --------------------------------------------------------*/ +/** + * @addtogroup PSRAM_Exported_Functions Exported Functions + * @{ + */ +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Init(void *Peripheral, EXTMEM_LinkConfig_TypeDef Config, + uint32_t ClockInput, + EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject); +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_DeInit(EXTMEM_DRIVER_PSRAM_ObjectTypeDef *PsramObject); +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Enable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef + *PsramObject); +EXTMEM_DRIVER_PSRAM_StatusTypeDef EXTMEM_DRIVER_PSRAM_Disable_MemoryMappedMode(EXTMEM_DRIVER_PSRAM_ObjectTypeDef + *PsramObject); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_PSRAM_DRIVER_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_type.h b/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_type.h new file mode 100644 index 0000000..61a76d8 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver_type.h @@ -0,0 +1,106 @@ +/** + ****************************************************************************** + * @file stm32_psram_driver_type.h + * @author MCD Application Team + * @brief This file contains PSRAM driver type definitions. + ****************************************************************************** + * @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 __STM32_PSRAM_TYPE_H +#define __STM32_PSRAM_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/** @addtogroup PSRAM + * @ingroup EXTMEM_DRIVER + * @{ + */ + +#if EXTMEM_DRIVER_PSRAM == 1 + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PSRAM_Exported_constants Exported constants + * @{ + */ + +/** + * @brief PSRAM driver maximum number of commands + */ +#define PSRAM_MAX_COMMAND 3u + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PSRAM_Exported_Types Exported Types + * @{ + */ + +/** + * @brief PSRAM driver object definition + */ +typedef struct +{ + struct + { + SAL_XSPI_ObjectTypeDef SALObject; /*!< SAL XSPI object. */ + } psram_private; /*!< Private data for the PSRAM driver object. */ + + struct + { + uint32_t MemorySize; /*!< Memory size (see @ref XSPI_MemorySize). */ + uint32_t FreqMax; /*!< Maximum supported memory frequency. */ + + /* Configuration */ + uint8_t NumberOfConfig; /*!< Number of configuration steps; each step performs a read and write operation. */ + struct + { + uint8_t WriteMask; /*!< Mask for write operation. */ + uint8_t WriteValue; /*!< Value to write. */ + uint8_t REGAddress; /*!< Address of the register. */ + } config[PSRAM_MAX_COMMAND]; + + /* Command REG */ + uint8_t ReadREG; + uint8_t WriteREG; + uint8_t ReadREGSize; + uint8_t REG_DummyCycle; + + /* Command Read and Write */ + uint8_t Write_command; + uint8_t Write_DummyCycle; + uint8_t Read_command; + uint8_t WrapRead_command; + uint8_t Read_DummyCycle; + } psram_public; /*!< Public data for the PSRAM driver object. */ +} EXTMEM_DRIVER_PSRAM_ObjectTypeDef; + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_PSRAM_TYPE_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c new file mode 100644 index 0000000..713b0ce --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c @@ -0,0 +1,236 @@ +/** + ****************************************************************************** + * @file stm32_sal_sd.c + * @author MCD Application Team + * @brief This file implements the software adaptation layer for SD. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem.h" +#include "stm32_extmem_conf.h" +#if EXTMEM_SAL_SD_DEBUG_LEVEL != 0 && defined(EXTMEM_MACRO_DEBUG) +#include +#endif /* EXTMEM_SAL_SD_DEBUG_LEVEL != 0 && EXTMEM_MACRO_DEBUG */ + +#if EXTMEM_SAL_SD == 1 +#include "stm32_sal_sd_type.h" +#include "stm32_sal_sd_api.h" + +/** @defgroup SAL_SD SAL_SD : Software adaptation layer for the HAL_SD + * @ingroup EXTMEM_SAL + * @{ + */ + +/** + * @brief Ready timeout value + */ +#define READY_TIMEOUT 1000u + +/* Private Macros ------------------------------------------------------------*/ + +/** @defgroup SAL_SD_Private_Macros SAL SD Private Macros + * @{ + */ +#if EXTMEM_SAL_SD_DEBUG_LEVEL == 0 || !defined(EXTMEM_MACRO_DEBUG) +#define DEBUG_PARAM_BEGIN() +#define DEBUG_PARAM_DATA(_STR_) +#define DEBUG_PARAM_INT(_INT_ ) +#define DEBUG_PARAM_END() +#else +/** + * @brief Trace header macro. + */ +#define DEBUG_PARAM_BEGIN() EXTMEM_MACRO_DEBUG("\t\tSALSD::"); + +/** + * @brief Trace data string macro. + */ +#define DEBUG_PARAM_DATA(_STR_) EXTMEM_MACRO_DEBUG(_STR_); + +/** + * @brief Trace data integer macro + */ +#define DEBUG_PARAM_INT(_INT_ ) { \ + char str[10]; \ + (void)snprintf(str, sizeof(str), "0x%x", _INT_);\ + EXTMEM_MACRO_DEBUG(str); \ + } +/** + * @brief Trace close macro + */ +#define DEBUG_PARAM_END() EXTMEM_MACRO_DEBUG("\n"); + +#endif /* EXTMEM_SFDP_DEBUG */ + +/** + * @} + */ + +/* Private typedefs ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SAL_SD_Private_Functions SAL XSP Private Functions + * @{ + */ + +/** + * @} + */ + +/* Exported variables ---------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup SAL_SD_Exported_Functions SAL XSP Exported Functions + * @{ + */ + +/** + * @brief This function initializes the SD SAL context + * @param SalSD SAL SD Object + * @param HALHandle HAL handle + * @param Info Information on the SD card + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_SD_Init(SAL_SD_ObjectTypeDef *SalSD, void *HALHandle, EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info) +{ + SalSD->hSD = (SD_HandleTypeDef *)HALHandle; + + Info->BlockNbr = SalSD->hSD->SdCard.BlockNbr; + Info->BlockSize = SalSD->hSD->SdCard.BlockSize; + + /* Switch to the highest Speed mode supported by the sd-card */ + return HAL_SD_ConfigSpeedBusOperation(SalSD->hSD, SDMMC_SPEED_MODE_AUTO); +} + +/** + * @brief This function un-initializes the SD SAL context + * @param SalSD SAL SD Object + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_SD_DeInit(SAL_SD_ObjectTypeDef *SalSD) +{ + SalSD->hSD->SdCard.BlockNbr = 0; + return HAL_OK; +} + +/** + * @brief This function reads data from the SD + * @param SalSD SAL SD Object + * @param BlockIdx Block index + * @param Data Data pointer + * @param NumberOfBlock Number of block + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_SD_ReadData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint8_t *Data, uint32_t NumberOfBlock) +{ + uint32_t timeout = 100UL * NumberOfBlock; + HAL_StatusTypeDef retr = HAL_SD_ReadBlocks(SalSD->hSD, (uint8_t *)Data, BlockIdx, NumberOfBlock, timeout); + if (HAL_OK == retr) + { + timeout = HAL_GetTick(); + /* Check the SD status */ + while (HAL_SD_GetCardState(SalSD->hSD) != HAL_SD_CARD_TRANSFER) + { + if ((HAL_GetTick() - timeout) > READY_TIMEOUT) + { + retr = HAL_TIMEOUT; + break; + } + } + } + return retr; +} + +/** + * @brief This function writes data on the SD + * @param SalSD SAL SD Object + * @param BlockIdx block index + * @param Data data pointer + * @param NumberOfBlock number of block + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_SD_WriteData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, const uint8_t *const Data, + uint32_t NumberOfBlock) +{ + uint32_t timeout = 100UL * NumberOfBlock; + HAL_StatusTypeDef retr; + + retr = HAL_SD_WriteBlocks(SalSD->hSD, Data, BlockIdx, NumberOfBlock, timeout); + if (HAL_OK == retr) + { + timeout = HAL_GetTick(); + /* Check the SD status */ + while (HAL_SD_GetCardState(SalSD->hSD) != HAL_SD_CARD_TRANSFER) + { + if ((HAL_GetTick() - timeout) > READY_TIMEOUT) + { + retr = HAL_TIMEOUT; + break; + } + } + } + return retr; +} + +/** + * @brief This function erases an amount of blocks on the SD + * @param SalSD SAL SD Object + * @param BlockIdx block index + * @param BlockCount number of block + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_SD_EraseBlock(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint32_t BlockCount) +{ + uint32_t timeout; + HAL_StatusTypeDef retr; + + retr = HAL_SD_Erase(SalSD->hSD, BlockIdx, BlockIdx + BlockCount); + if (HAL_OK == retr) + { + timeout = HAL_GetTick(); + /* Check the SD status */ + while (HAL_SD_GetCardState(SalSD->hSD) != HAL_SD_CARD_TRANSFER) + { + if ((HAL_GetTick() - timeout) > (READY_TIMEOUT * BlockCount)) + { + retr = HAL_TIMEOUT; + break; + } + } + } + return retr; +} + +/** + * @brief This function erases all the SD + * @param SalSD SAL SD Object + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_SD_MassErase(SAL_SD_ObjectTypeDef *SalSD) +{ + return SAL_SD_EraseBlock(SalSD, 0, SalSD->hSD->SdCard.BlockNbr); +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* EXTMEM_SAL_SD == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_api.h b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_api.h new file mode 100644 index 0000000..9fb5f50 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_api.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file stm32_sal_sd_api.h + * @author MCD Application Team + * @brief This file contains SAL SD function prototypes. + ****************************************************************************** + * @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 __STM32_SAL_SD_API_H +#define __STM32_SAL_SD_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup SAL_SD + * @ingroup EXTMEM_SAL + * @{ + */ + +/** @defgroup SAL_SD + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SAL_SD_Exported_types SAL SD exported types + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SAL_SD_Exported_Functions SAL SD Exported Functions + * @{ + */ + +HAL_StatusTypeDef SAL_SD_Init(SAL_SD_ObjectTypeDef *SalSD, void *HALHandle, EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info); +HAL_StatusTypeDef SAL_SD_DeInit(SAL_SD_ObjectTypeDef *SalSD); +HAL_StatusTypeDef SAL_SD_ReadData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint8_t *Data, + uint32_t NumberOfBlock); +HAL_StatusTypeDef SAL_SD_WriteData(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, const uint8_t *const Data, + uint32_t NumberOfBlock); +HAL_StatusTypeDef SAL_SD_EraseBlock(SAL_SD_ObjectTypeDef *SalSD, uint32_t BlockIdx, uint32_t BlockCount); +HAL_StatusTypeDef SAL_SD_MassErase(SAL_SD_ObjectTypeDef *SalSD); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SAL_SD_API_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_type.h b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_type.h new file mode 100644 index 0000000..464193c --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd_type.h @@ -0,0 +1,74 @@ +/** + ****************************************************************************** + * @file stm32_sal_sd_type.h + * @author MCD Application Team + * @brief This file contains SAL SD type definitions. + ****************************************************************************** + * @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 __STM32_SAL_SD_TYPE_H +#define __STM32_SAL_SD_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup SAL_SD + * @ingroup EXTMEM_SAL + * @{ + */ + +/** @defgroup SAL_SD + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SAL_SD_Exported_types SAL SD exported types + * @{ + */ + +typedef struct +{ + SD_HandleTypeDef *hSD; /*!< Pointer to the SD instance handle. */ +} SAL_SD_ObjectTypeDef; + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SAL_SD_Exported_Functions SAL XSP Exported Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SAL_SD_TYPE_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c new file mode 100644 index 0000000..c9eda4a --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c @@ -0,0 +1,1245 @@ +/** + ****************************************************************************** + * @file stm32_sal_xspi.c + * @author MCD Application Team + * @brief This file implements the software adaptation layer for XSPI. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem.h" +#include "stm32_extmem_conf.h" +#if EXTMEM_SAL_XSPI_DEBUG_LEVEL != 0 && defined(EXTMEM_MACRO_DEBUG) +#include +#endif /* EXTMEM_SAL_XSPI_DEBUG_LEVEL != 0 && EXTMEM_MACRO_DEBUG */ + +#if EXTMEM_SAL_XSPI == 1 + +#include "stm32_sal_xspi_type.h" +#include "stm32_sal_xspi_api.h" + +/** @defgroup SAL_XSPI SAL_XSPI : Software adaptation layer for XSPI + * @ingroup EXTMEM_SAL + * @{ + */ + +/* Private Macros ------------------------------------------------------------*/ +/** @defgroup SAL_XSPI_Private_Macros SAL XSPI Private Macros + * @{ + */ + +#if EXTMEM_SAL_XSPI_DEBUG_LEVEL == 0 || !defined(EXTMEM_MACRO_DEBUG) +#define DEBUG_PARAM_BEGIN() +#define DEBUG_PARAM_DATA(_STR_) +#define DEBUG_PARAM_INT(_INT_ ) +#define DEBUG_PARAM_INTD(_INT_ ) +#define DEBUG_PARAM_END() +#define DEBUG_AUTOPOLLING(_DR_,_MVAL_,_MMASK_) +#define STR_PHY_LINK(_PHY_) +#else +/** + * @brief Trace header macro. + */ +#define DEBUG_PARAM_BEGIN() EXTMEM_MACRO_DEBUG("\t\tSALXSPI::"); + +const uint8_t phylink_string[][17] = {"PHY_LINK_1S1S1S", + "PHY_LINK_1S1S2S", + "PHY_LINK_1S2S2S", + "PHY_LINK_1S1D1D", + "PHY_LINK_4S4S4S", + "PHY_LINK_4S4D4D", + "PHY_LINK_4D4D4D", + "PHY_LINK_1S8S8S", + "PHY_LINK_8S8D8D", + "PHY_LINK_8D8D8D", + "PHY_LINK_RAM8", +#if defined(HAL_XSPI_DATA_16_LINES) + "PHY_LINK_RAM16", +#endif /* HAL_XSPI_DATA_16_LINES */ + }; + +#define STR_PHY_LINK(_PHY_) phylink_string[_PHY_] + +/** + * @brief Trace data string macro. + */ +#define DEBUG_PARAM_DATA(_STR_) EXTMEM_MACRO_DEBUG(_STR_); + +/** + * @brief Trace data integer macro. + */ +#define DEBUG_PARAM_INT(_INT_) \ + { \ + char str[10]; \ + (void)snprintf(str, sizeof(str), "0x%x", _INT_); \ + EXTMEM_MACRO_DEBUG(str); \ + } + +#define DEBUG_PARAM_INTD(_INT_) \ + { \ + char str[15]; \ + (void)snprintf(str, sizeof(str), "%zu", _INT_); \ + EXTMEM_MACRO_DEBUG(str); \ + } + +/** + * @brief Trace close macro + */ +#define DEBUG_PARAM_END() EXTMEM_MACRO_DEBUG("\n"); + +#if EXTMEM_SAL_XSPI_DEBUG_LEVEL == 2 +#define DEBUG_AUTOPOLLING(_DR_,_MVAL_,_MMASK_) \ + { \ + char str[50]; \ + (void)snprintf(str, sizeof(str),"DR:0x%x::MVal:0x%x::MMask:0x%x\n\r", _DR_, _MVAL_, _MMASK_); \ + DEBUG_PARAM_BEGIN() \ + DEBUG_PARAM_DATA(str) \ + DEBUG_PARAM_END() \ + } +#else +#define DEBUG_AUTOPOLLING(_DR_,_MVAL_,_MMASK_) +#endif /* EXTMEM_SAL_XSPI_DEBUG_LEVEL == 2 */ +#endif /* EXTMEM_SAL_XSPI_DEBUG_LEVEL == 0 || !EXTMEM_MACRO_DEBUG */ + +/** + * @brief Default SAL timeout (100 ms) + */ + +#define SAL_XSPI_TIMEOUT_DEFAULT_VALUE (100U) + +/** + * @} + */ + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +/** @defgroup SAL_XSPI_Private_Transfer SAL XSPI Dma transfer management definition + * @{ + */ +/** + * @brief State of the transfer status + */ +typedef enum +{ + SALXSPI_TRANSFER_NONE, /*!< */ + SALXSPI_TRANSFER_OK, + SALXSPI_TRANSFER_ERROR +} SAL_XSPI_TRANSFER_STATUS; + +/** + * @brief Variable of the transfer status + */ +volatile SAL_XSPI_TRANSFER_STATUS salXSPI_status = SALXSPI_TRANSFER_NONE; + +/** + * @} + */ +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + +/* Private typedefs ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SAL_XSPI_Private_Functions SAL XSP Private Functions + * @{ + */ +uint16_t XSPI_FormatCommand(uint8_t CommandExtension, uint32_t InstructionWidth, uint8_t Command); +HAL_StatusTypeDef XSPI_Transmit(SAL_XSPI_ObjectTypeDef *SalXspi, const uint8_t *Data); +HAL_StatusTypeDef XSPI_Receive(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t *Data); +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +void SAL_XSPI_ErrorCallback(struct __XSPI_HandleTypeDef *hxspi); +void SAL_XSPI_CompleteCallback(struct __XSPI_HandleTypeDef *hxspi); +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported variables ---------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + + +/** @defgroup SAL_XSPI_Exported_Functions SAL XSP Exported Functions + * @{ + */ + +/** + * @brief This function sets the clock according the clock in and the expected clock + * @param SalXspi SAL XSPI handle + * @param ClockIn Clock in input + * @param ClockRequested Clock requested + * @param ClockReal Pointer on the value of the real clock used + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_SetClock(SAL_XSPI_ObjectTypeDef *SalXspi, uint32_t ClockIn, uint32_t ClockRequested, + uint32_t *ClockReal) +{ + HAL_StatusTypeDef retr = HAL_OK; + uint32_t divider; + + if (ClockRequested == 0u) + { + retr = HAL_ERROR; + } + else + { + divider = (ClockIn / ClockRequested); + if (divider >= 1u) + { + *ClockReal = ClockIn / divider; + if (*ClockReal <= ClockRequested) + { + divider--; + } + } + + /* Real clock calculation */ + *ClockReal = ClockIn / (divider + 1u); + + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::CLOCKDIV::"); + DEBUG_PARAM_INT(divider + 1); + DEBUG_PARAM_END(); + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::CLKFREQ::"); + DEBUG_PARAM_INTD(*ClockReal); + DEBUG_PARAM_END(); + MODIFY_REG(SalXspi->hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER, (uint32_t)divider << XSPI_DCR2_PRESCALER_Pos); + } + + return retr; +} + +/** + * @brief This function is used to configure the way to discuss with the memory + * @param SalXspi SAL XSPI handle + * @param HALHandle HAl XSPI handle used for memory access + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_Init(SAL_XSPI_ObjectTypeDef *SalXspi, void *HALHandle) +{ + XSPI_RegularCmdTypeDef s_commandbase = + { + .OperationType = HAL_XSPI_OPTYPE_COMMON_CFG, + .IOSelect = HAL_XSPI_SELECT_IO_7_0, + .InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE, + .Instruction = EXTMEM_READ_SFDP_COMMAND, + .InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS, + .InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE, + .AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE, + .AddressMode = HAL_XSPI_ADDRESS_1_LINE, + .AddressWidth = HAL_XSPI_ADDRESS_24_BITS, + .Address = 0x0, + .AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE, + .DataMode = HAL_XSPI_DATA_1_LINE, + .DataLength = 0x0, + .DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE, + .DummyCycles = EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_DEFAULT, + .DQSMode = HAL_XSPI_DQS_DISABLE, +#if defined(XSPI_CCR_SIOO) + .SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD, +#endif /* XSPI_CCR_SIOO */ + }; + + SalXspi->hxspi = (XSPI_HandleTypeDef *)HALHandle; + SalXspi->Commandbase = s_commandbase; + SalXspi->CommandExtension = 0; + SalXspi->PhyLink = PHY_LINK_1S1S1S; + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + /* Set completion call back */ + HAL_XSPI_RegisterCallback(SalXspi->hxspi, HAL_XSPI_RX_CPLT_CB_ID, SAL_XSPI_CompleteCallback); + HAL_XSPI_RegisterCallback(SalXspi->hxspi, HAL_XSPI_TX_CPLT_CB_ID, SAL_XSPI_CompleteCallback); + /* Set the error callback */ + HAL_XSPI_RegisterCallback(SalXspi->hxspi, HAL_XSPI_ERROR_CB_ID, SAL_XSPI_ErrorCallback); +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + + return HAL_OK; +} + +/** + * @brief This function sets a configuration parameter + * @param SalXspi SAL XSPI handle + * @param ParametersType @ref SAL_XSPI_MemParamTypeTypeDef + * @param ParamVal Pointer on the parameter value + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_MemoryConfig(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_MemParamTypeTypeDef ParametersType, + void *ParamVal) +{ + HAL_StatusTypeDef retr = HAL_OK; + XSPI_RegularCmdTypeDef s_commandbase = SalXspi->Commandbase; + + switch (ParametersType) + { + case PARAM_PHY_LINK: + { + SalXspi->PhyLink = *((SAL_XSPI_PhysicalLinkTypeDef *)ParamVal); + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::PARAM_PHY_LINK::"); + DEBUG_PARAM_DATA(STR_PHY_LINK(SalXspi->PhyLink)); + switch (SalXspi->PhyLink) + { + case PHY_LINK_1S1D1D: + case PHY_LINK_1S2S2S: + case PHY_LINK_1S1S2S: + case PHY_LINK_1S1S1S: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_1_LINE; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_24_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + s_commandbase.DataMode = HAL_XSPI_DATA_1_LINE; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_commandbase.DummyCycles = 8; + s_commandbase.DQSMode = HAL_XSPI_DQS_DISABLE; + break; + } + + case PHY_LINK_4S4D4D: + case PHY_LINK_4S4S4S: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_4_LINES; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_4_LINES; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_24_BITS; + s_commandbase.DataMode = HAL_XSPI_DATA_4_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_commandbase.DummyCycles = 6; + s_commandbase.DQSMode = HAL_XSPI_DQS_DISABLE; + break; + } + case PHY_LINK_4D4D4D: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_4_LINES; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_4_LINES; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_24_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_commandbase.DataMode = HAL_XSPI_DATA_4_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_commandbase.DummyCycles = 6; + s_commandbase.DQSMode = HAL_XSPI_DQS_DISABLE; + break; + } + case PHY_LINK_1S8S8S: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE; + s_commandbase.DataMode = HAL_XSPI_DATA_8_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_commandbase.DummyCycles = 8; + s_commandbase.DQSMode = HAL_XSPI_DQS_DISABLE; + break; + } + case PHY_LINK_8S8D8D: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_commandbase.DataMode = HAL_XSPI_DATA_8_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_commandbase.DummyCycles = 8; + s_commandbase.DQSMode = HAL_XSPI_DQS_ENABLE; + break; + } + + case PHY_LINK_8D8D8D: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_16_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_ENABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_commandbase.DataMode = HAL_XSPI_DATA_8_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_commandbase.DummyCycles = 20; + s_commandbase.DQSMode = HAL_XSPI_DQS_ENABLE; + break; + } + case PHY_LINK_RAM8: + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_commandbase.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_commandbase.DataMode = HAL_XSPI_DATA_8_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_commandbase.DummyCycles = 10; + s_commandbase.DQSMode = HAL_XSPI_DQS_ENABLE; + break; + } +#if defined(HAL_XSPI_DATA_16_LINES) + case PHY_LINK_RAM16 : + { + s_commandbase.InstructionMode = HAL_XSPI_INSTRUCTION_8_LINES; + s_commandbase.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS; + s_commandbase.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE; + s_commandbase.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_commandbase.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_commandbase.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE; + s_commandbase.DataMode = HAL_XSPI_DATA_16_LINES; + s_commandbase.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_commandbase.DummyCycles = 10; + s_commandbase.DQSMode = HAL_XSPI_DQS_ENABLE; + break; + } +#endif /* HAL_XSPI_DATA_16_LINES */ + default: + retr = HAL_ERROR; + break; + } + DEBUG_PARAM_END(); + break; + } + case PARAM_ADDRESS_4BYTES: + { + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::PARAM_ADDRESS_4BYTES"); + DEBUG_PARAM_END(); + s_commandbase.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + break; + } + case PARAM_FLASHSIZE: + { + uint8_t valParam = *((uint8_t *)ParamVal); + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::PARAM_FLASHSIZE::"); + DEBUG_PARAM_INT(valParam); + DEBUG_PARAM_END(); + MODIFY_REG(SalXspi->hxspi->Instance->DCR1, XSPI_DCR1_DEVSIZE, ((uint32_t)valParam) << XSPI_DCR1_DEVSIZE_Pos); + break; + } + case PARAM_DUMMY_CYCLES: + { + uint8_t valParam = *((uint8_t *)ParamVal); + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::PARAM_DUMMY_CYCLES::"); + DEBUG_PARAM_INT(valParam); + DEBUG_PARAM_END(); + s_commandbase.DummyCycles = valParam; + break; + } + default: + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::SAL_XSPI_MemoryConfig::ERROR"); + DEBUG_PARAM_END(); + retr = HAL_ERROR; + break; + } + SalXspi->Commandbase = s_commandbase; + return retr; +} + +/** + * @brief This function gets SFDP data + * @param SalXspi SAL XSPI handle + * @param Address Address to read the data + * @param Data Data pointer + * @param DataSize Size of the data to read + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_GetSFDP(SAL_XSPI_ObjectTypeDef *SalXspi, uint32_t Address, uint8_t *Data, uint32_t DataSize) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + + /* Initialize the read ID command */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, + EXTMEM_READ_SFDP_COMMAND); + + s_command.Address = Address; + s_command.DataLength = DataSize; + s_command.DummyCycles = SalXspi->SFDPDummyCycle; + + if ((s_command.AddressMode == HAL_XSPI_ADDRESS_1_LINE) || (s_command.AddressMode == HAL_XSPI_ADDRESS_4_LINES)) + { + s_command.AddressWidth = HAL_XSPI_ADDRESS_24_BITS; + } + + if (s_command.DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE) + { + s_command.DQSMode = HAL_XSPI_DQS_ENABLE; + } + else + { + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + } + + /* Configure the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + goto error; + } + + /* Reception of the data */ + retr = HAL_XSPI_Receive(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + +error: + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function reads the flash ID + * @param SalXspi SAL XSPI handle + * @param Data Data pointer where read ID should be stored + * @param DataSize Number of data to read + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_GetId(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t *Data, uint32_t DataSize) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + + /* Initialize the Read ID command */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, + EXTMEM_READ_JEDEC_ID_SPI_COMMAND); + + s_command.DataLength = DataSize; + + if (s_command.InstructionMode == HAL_XSPI_INSTRUCTION_1_LINE) + { + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.DummyCycles = 0; + /* This behavior is linked with micron memory to read ID in 1S8S8S */ + s_command.DataMode = HAL_XSPI_DATA_1_LINE; + } + else if (s_command.InstructionMode == HAL_XSPI_INSTRUCTION_4_LINES) + { + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.DummyCycles = 0; + /* This behavior is linked with ISSI memory to read ID in 4S4S4S */ + s_command.DataMode = HAL_XSPI_DATA_4_LINES; + } + else if (s_command.InstructionMode == HAL_XSPI_INSTRUCTION_8_LINES) + { + s_command.Address = 0; + + /* Specific case for Macronix memories : RDID is not Data DTR */ + if ((Data[0] == 0xC2) && (s_command.DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)) + { + s_command.DummyCycles = 4; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + } + /* Specific case for GigaDevice memories : RDID has no address even in Octal mode */ + else if ((Data[0] == 0xC8) && (s_command.DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)) + { + s_command.DummyCycles = 8; + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + } + else + { + s_command.DummyCycles = 8; + } + /* Required behavior to be confirmed on the other memories */ + } + else + { + s_command.Address = 0; + s_command.DummyCycles = 8; + } + + /* Configure the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + goto error; + } + + /* Reception of the data */ + retr = HAL_XSPI_Receive(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + +error: + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function reads data from the flash + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Address Address to read the data + * @param Data Data pointer + * @param DataSize Size of the data to read + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_Read(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address, uint8_t *Data, + uint32_t DataSize) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + + /* Initialize the read ID command */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + s_command.Address = Address; + s_command.DataLength = DataSize; + + /* DTR management for single/dual/quad */ + switch (SalXspi->PhyLink) + { + case PHY_LINK_4S4D4D : + s_command.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_ENABLE; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_ENABLE; + s_command.DummyCycles = SalXspi->DTRDummyCycle; + break; + + case PHY_LINK_1S2S2S : + s_command.AddressMode = HAL_XSPI_ADDRESS_2_LINES; + s_command.DataMode = HAL_XSPI_DATA_2_LINES; + break; + + case PHY_LINK_1S1S2S : + s_command.DataMode = HAL_XSPI_DATA_2_LINES; + break; + + default : + /* Keep default parameters */ + break; + } + + /* Configure the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + goto error; + } + + /* Read data */ + retr = XSPI_Receive(SalXspi, Data); + +error: + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function writes data at an Address + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Address Address to write the data + * @param Data Data pointer + * @param DataSize Size of the data to write + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_Write(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address, + const uint8_t *Data, uint32_t DataSize) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + + /* Initialize the read ID command */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + s_command.Address = Address; + s_command.DataLength = DataSize; + s_command.DummyCycles = 0u; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + /* Configure the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (HAL_OK != retr) + { + goto error; + } + + /* Transmit data */ + retr = XSPI_Transmit(SalXspi, Data); + +error: + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function sends a command and an address + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Address Address to write the data + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_CommandSendAddress(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint32_t Address) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + + /* Initialize the writing of status register */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + if (s_command.InstructionMode == HAL_XSPI_INSTRUCTION_1_LINE) + { + s_command.AddressMode = HAL_XSPI_ADDRESS_1_LINE; + } + + s_command.Address = Address; + s_command.DummyCycles = 0U; + s_command.DataMode = HAL_XSPI_DATA_NONE; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + /* Send the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function sends a command + data + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Data Data pointer + * @param DataSize Size of the data to write + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_CommandSendData(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint8_t *Data, uint16_t DataSize) +{ + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + HAL_StatusTypeDef retr; + + /* Initialize the writing of status register */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.DummyCycles = 0U; + s_command.DataLength = DataSize; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + if (DataSize == 0u) + { + s_command.DataMode = HAL_XSPI_DATA_NONE; + } + + /* Send the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + + if ((retr == HAL_OK) && (DataSize != 0u)) + { + retr = HAL_XSPI_Transmit(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + } + + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function sends a command to read the data + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Data Data pointer + * @param DataSize Size of the data to receive + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_SendReadCommand(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint8_t *Data, uint16_t DataSize) +{ + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + HAL_StatusTypeDef retr; + + /* Initialize the reading of status register */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + s_command.AddressMode = HAL_XSPI_ADDRESS_NONE; + s_command.DummyCycles = 0u; + s_command.DataLength = DataSize; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + if (DataSize == 0u) + { + s_command.DataMode = HAL_XSPI_DATA_NONE; + } + + /* Send the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + + if ((retr == HAL_OK) && (DataSize != 0u)) + { + /* Receive data */ + retr = HAL_XSPI_Receive(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + } + + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function sends a command with address and read the data + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Address Address value + * @param Data Data pointer + * @param DataSize Size of the data to read + * @param ManuId Manufacturer Identifier + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_CommandSendReadAddress(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint32_t Address, uint8_t *Data, uint16_t DataSize, + uint8_t ManuId) +{ + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + HAL_StatusTypeDef retr; + + /* Initialize the reading of status register */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + s_command.Address = Address; + s_command.DummyCycles = SalXspi->SFDPDummyCycle; + s_command.DataLength = DataSize; + /* Specific case for Macronix memories : RDID and RDCR are not Data DTR */ + if ((ManuId == EXTMEM_MANUFACTURER_MACRONIX) && (s_command.DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)) + { + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + } + /* Specific case for GigaDevice memories : Read Configuration Register are not Data DTR */ + else if ((ManuId == 0xC8) && (s_command.DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)) + { + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + } + else + { + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + } + + /* Send the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + + if (retr == HAL_OK) + { + /* Retrieve data */ + retr = HAL_XSPI_Receive(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + } + + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function controls the status register + * @param SalXspi SAL XSPI handle + * @param Command Command to execute + * @param Address Specify the address + * @param MatchValue Expected value + * @param MatchMask Mask used to control the expected value + * @param ManuId Manufacturer Identifier + * @param Timeout Timeout parameter + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_CheckStatusRegister(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address, + uint8_t MatchValue, uint8_t MatchMask, uint8_t ManuId, + uint32_t Timeout) +{ + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + XSPI_AutoPollingTypeDef s_config = + { + .MatchValue = MatchValue, + .MatchMask = MatchMask, + .MatchMode = HAL_XSPI_MATCH_MODE_AND, + .AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE, + .IntervalTime = 0x10 + }; + HAL_StatusTypeDef retr; + + /* Initialize the reading of status register */ + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, Command); + + s_command.DataLength = 1u; + s_command.DQSMode = HAL_XSPI_DQS_DISABLE; + + if (s_command.InstructionMode == HAL_XSPI_INSTRUCTION_1_LINE) + { + /* Specific behavior for Cypress to force 1 line on status read */ + s_command.DataMode = HAL_XSPI_DATA_1_LINE; + s_command.AddressMode = HAL_XSPI_DATA_NONE; + s_command.DummyCycles = 0u; + } + + /* Address is used only in 8 LINES format */ + if (s_command.DataMode == HAL_XSPI_DATA_8_LINES) + { + /* Specific case for Macronix memories : RDID and RDCR are not Data DTR */ + if ((ManuId == EXTMEM_MANUFACTURER_MACRONIX) && (s_command.DataDTRMode == HAL_XSPI_DATA_DTR_ENABLE)) + { + s_command.DQSMode = HAL_XSPI_DQS_ENABLE; + s_command.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE; + } + s_command.AddressMode = HAL_XSPI_ADDRESS_8_LINES; + s_command.AddressWidth = HAL_XSPI_ADDRESS_32_BITS; + s_command.Address = Address; + } + + /* Send the command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr == HAL_OK) + { + retr = HAL_XSPI_AutoPolling(SalXspi->hxspi, &s_config, Timeout); + DEBUG_AUTOPOLLING(SalXspi->hxspi->Instance->DR, s_config.MatchValue, s_config.MatchMask) + } + + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function enables the memory mapped mode + * @param SalXspi SAL XSPI handle + * @param WrapCommand Wrap command to execute in case of write operation + * @param WrapDummy Number of dummy cycle for the read operation + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_ConfigureWrappMode(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t WrapCommand, uint8_t WrapDummy) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + + /* Initialize the read ID command */ + s_command.OperationType = HAL_XSPI_OPTYPE_WRAP_CFG; + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, WrapCommand); + s_command.DummyCycles = WrapDummy; + /* Configure the read command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + goto error; + } + +error: + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function enables the memory mapped mode + * @param SalXspi SAL XSPI handle + * @param CommandRead command to execute in case of read operation + * @param DummyRead number of dummy cycle for the read operation + * @param CommandWrite command to execute in case of write operation + * @param DummyWrite number of dummy cycle for the read operation + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_EnableMapMode(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t CommandRead, uint8_t DummyRead, + uint8_t CommandWrite, uint8_t DummyWrite) +{ + HAL_StatusTypeDef retr; + XSPI_RegularCmdTypeDef s_command = SalXspi->Commandbase; + XSPI_MemoryMappedTypeDef sMemMappedCfg = {0}; + + /* Initialize the read ID command */ + s_command.OperationType = HAL_XSPI_OPTYPE_READ_CFG; + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, CommandRead); + s_command.DummyCycles = DummyRead; + /* Configure the read command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + goto error; + } + + /* Initialize the read ID command */ + s_command.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG; + s_command.Instruction = XSPI_FormatCommand(SalXspi->CommandExtension, s_command.InstructionWidth, CommandWrite); + s_command.DummyCycles = DummyWrite; + /* Configure the read command */ + retr = HAL_XSPI_Command(SalXspi->hxspi, &s_command, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + if (retr != HAL_OK) + { + goto error; + } + + /* Activation of memory-mapped mode */ + sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE; + sMemMappedCfg.TimeoutPeriodClock = 0x50; + retr = HAL_XSPI_MemoryMapped(SalXspi->hxspi, &sMemMappedCfg); + +error: + if (retr != HAL_OK) + { + /* Abort any ongoing transaction for the next action */ + (void)HAL_XSPI_Abort(SalXspi->hxspi); + } + return retr; +} + +/** + * @brief This function disables the memory mapped mode + * @param SalXspi SAL XSPI handle + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_DisableMapMode(SAL_XSPI_ObjectTypeDef *SalXspi) +{ + __DSB(); + return HAL_XSPI_Abort(SalXspi->hxspi); +} + +/** + * @brief This function updates the memory according the SFDP signature value + * @param SalXspi SAL XSPI handle + * @param DataOrder Selected data order + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_UpdateMemoryType(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_DataOrderTypeDef DataOrder) +{ + HAL_StatusTypeDef retr = HAL_OK; + + /* Read the memory type value */ + uint32_t memorytype = READ_REG(SalXspi->hxspi->Instance->DCR1) & XSPI_DCR1_MTYP; + + switch (DataOrder) + { + case SAL_XSPI_ORDERINVERTED : + if (memorytype == HAL_XSPI_MEMTYPE_MICRON) + { + memorytype = HAL_XSPI_MEMTYPE_MACRONIX; + } + else if (memorytype == HAL_XSPI_MEMTYPE_MACRONIX) + { + memorytype = HAL_XSPI_MEMTYPE_MICRON; + } + else + { + retr = HAL_ERROR; + } + MODIFY_REG(SalXspi->hxspi->Instance->DCR1, XSPI_DCR1_MTYP, memorytype); + break; + default : + return HAL_ERROR; + break; + } + + DEBUG_PARAM_BEGIN(); + DEBUG_PARAM_DATA("::SAL_XSPI_UpdateMemoryType::"); + DEBUG_PARAM_INT(memorytype); + DEBUG_PARAM_END(); + return retr; +} + +HAL_StatusTypeDef SAL_XSPI_Abort(SAL_XSPI_ObjectTypeDef *SalXspi) +{ + return HAL_XSPI_Abort(SalXspi->hxspi); +} + +/** + * @} + */ + +/** @defgroup SAL_XSPI_Private_Functions SAL XSP Private Functions + * @{ + */ +/** + * @brief This function return a formatted command + * + * @param CommandExtension Type of the command extension 0: the complement 1 : the same + * @param InstructionWidth Instruction width + * @param Command Command + * @return Formatted command + */ +uint16_t XSPI_FormatCommand(uint8_t CommandExtension, uint32_t InstructionWidth, uint8_t Command) +{ + uint16_t retr; + if (InstructionWidth == HAL_XSPI_INSTRUCTION_16_BITS) + { + /* 0b00 Command Extension is the same as the Command. + (Command / Command Extension has the same value for the whole clock period. */ + /* 0b01 Command Extension is the inverse of the Command. + Command Extension acts as a confirmation of the Command */ + /* 0b11 Command and Command Extension forms a 16 bit command word :: Not yet handled */ + retr = ((uint16_t)Command << 8u); + if (CommandExtension == 1u) + { + retr |= (uint8_t)(~Command & 0xFFu); + } + else + { + retr |= (uint8_t)(Command & 0xFFu); + } + } + else + { + retr = Command; + } + + return retr; +} + +/** + * @brief This function transmits the data + * + * @param SalXspi SAL XSPI Handle + * @param Data Data pointer + * @return Status of the command execution + */ +HAL_StatusTypeDef XSPI_Transmit(SAL_XSPI_ObjectTypeDef *SalXspi, const uint8_t *Data) +{ + HAL_StatusTypeDef retr; + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + if (SalXspi->hxspi->hdmatx == NULL) +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + { + /* Transmit data */ + retr = HAL_XSPI_Transmit(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + } +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + else + { + /* Set completion call back */ + salXSPI_status = SALXSPI_TRANSFER_NONE; + + /* Reception of the data */ + retr = HAL_XSPI_Transmit_DMA(SalXspi->hxspi, (uint8_t *)Data); + + if (retr == HAL_OK) + { + /* Wait data reception completion */ + while (salXSPI_status == SALXSPI_TRANSFER_NONE); + if (salXSPI_status == SALXSPI_TRANSFER_ERROR) + { + retr = HAL_ERROR; + } + } + } +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + + return retr; +} + +/** + * @brief Start data reception in polling mode or DMA + * + * @param SalXspi SAL XSPI Handle + * @param Data Data pointer + * @return Status of the command execution + */ +HAL_StatusTypeDef XSPI_Receive(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t *Data) +{ + HAL_StatusTypeDef retr; + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + if (SalXspi->hxspi->hdmarx == NULL) +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + { + /* Reception of the data */ + retr = HAL_XSPI_Receive(SalXspi->hxspi, Data, SAL_XSPI_TIMEOUT_DEFAULT_VALUE); + } +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + else + { + /* Set completion call back */ + salXSPI_status = SALXSPI_TRANSFER_NONE; + + /* Reception of the data */ + retr = HAL_XSPI_Receive_DMA(SalXspi->hxspi, Data); + + if (retr == HAL_OK) + { + /* Wait data completion */ + while (salXSPI_status == SALXSPI_TRANSFER_NONE); + if (salXSPI_status == SALXSPI_TRANSFER_ERROR) + { + retr = HAL_ERROR; + } + } + } +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + return retr; +} + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +/** + * @brief This callback is executed when a DMA transfer error occurs + * + * @param hxspi Handle on the XSPI peripheral + * @return none + */ +void SAL_XSPI_ErrorCallback(struct __XSPI_HandleTypeDef *hxspi) +{ + salXSPI_status = SALXSPI_TRANSFER_ERROR; +} + +/** + * @brief this callback is executed when a DMA transfer is complete + * + * @param hxspi Handle on the XSPI peripheral + * @return none + */ +void SAL_XSPI_CompleteCallback(struct __XSPI_HandleTypeDef *hxspi) +{ + salXSPI_status = SALXSPI_TRANSFER_OK; +} +#endif /* USE_HAL_XSPI_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* EXTMEM_SAL_XSPI == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_api.h b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_api.h new file mode 100644 index 0000000..d1c48df --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_api.h @@ -0,0 +1,100 @@ +/** + ****************************************************************************** + * @file stm32_sal_xspi_api.h + * @author MCD Application Team + * @brief This file contains SAL XSPI function prototypes. + ****************************************************************************** + * @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 __STM32_SAL_XSPI_API_H +#define __STM32_SAL_XSPI_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SAL_XSPI + * @ingroup EXTMEM_SAL + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SAL_XSPI_Exported_types SAL XSPI exported types + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SAL_XSPI_Exported_Functions SAL XSPI Exported Functions + * @{ + */ +HAL_StatusTypeDef SAL_XSPI_SetClock(SAL_XSPI_ObjectTypeDef *SalXspi, uint32_t ClockIn, uint32_t ClockRequested, + uint32_t *ClockReal); +HAL_StatusTypeDef SAL_XSPI_Init(SAL_XSPI_ObjectTypeDef *SalXspi, void *HALHandle); +HAL_StatusTypeDef SAL_XSPI_MemoryConfig(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_MemParamTypeTypeDef ParametersType, + void *ParamVal); +HAL_StatusTypeDef SAL_XSPI_GetSFDP(SAL_XSPI_ObjectTypeDef *SalXspi, uint32_t Address, + uint8_t *Data, uint32_t DataSize); +HAL_StatusTypeDef SAL_XSPI_GetId(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t *Data, uint32_t DataSize); +HAL_StatusTypeDef SAL_XSPI_Read(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address, uint8_t *Data, + uint32_t DataSize); +HAL_StatusTypeDef SAL_XSPI_Write(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address, + const uint8_t *Data, uint32_t DataSize); +HAL_StatusTypeDef SAL_XSPI_CommandSendAddress(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, uint32_t Address); +HAL_StatusTypeDef SAL_XSPI_CommandSendData(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint8_t *Data, uint16_t DataSize); +HAL_StatusTypeDef SAL_XSPI_SendReadCommand(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint8_t *Data, uint16_t DataSize); +HAL_StatusTypeDef SAL_XSPI_CommandSendReadAddress(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t Command, + uint32_t Address, uint8_t *Data, uint16_t DataSize, + uint8_t ManuId); +HAL_StatusTypeDef SAL_XSPI_CheckStatusRegister(SAL_XSPI_ObjectTypeDef *SalXspi, + uint8_t Command, uint32_t Address, uint8_t MatchValue, uint8_t MatchMask, + uint8_t ManuId, uint32_t Timeout); +HAL_StatusTypeDef SAL_XSPI_ConfigureWrappMode(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t WrapCommand, uint8_t WrapDummy); +HAL_StatusTypeDef SAL_XSPI_EnableMapMode(SAL_XSPI_ObjectTypeDef *SalXspi, uint8_t CommandRead, uint8_t DummyRead, + uint8_t CommandWrite, uint8_t DummyWrite); +HAL_StatusTypeDef SAL_XSPI_DisableMapMode(SAL_XSPI_ObjectTypeDef *SalXspi); +HAL_StatusTypeDef SAL_XSPI_UpdateMemoryType(SAL_XSPI_ObjectTypeDef *SalXspi, SAL_XSPI_DataOrderTypeDef DataOrder); + +/** + * @brief This function aborts the transaction + * @param SalXspi SAL XSPI handle + * @return @ref HAL_StatusTypeDef + **/ +HAL_StatusTypeDef SAL_XSPI_Abort(SAL_XSPI_ObjectTypeDef *SalXspi); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SAL_XSPI_API_H */ + diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_type.h b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_type.h new file mode 100644 index 0000000..969e3b3 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi_type.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file stm32_sal_xspi_type.h + * @author MCD Application Team + * @brief This file contains SAL XSPI type definitions. + ****************************************************************************** + * @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 __STM32_SAL_XSPI_TYPE_H +#define __STM32_SAL_XSPI_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup SAL_XSPI + * @ingroup EXTMEM_SAL + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + + +/** @defgroup SAL_XSPI_Exported_types SAL XSPI exported types + * @{ + */ + +/** + * @brief Data order information. + */ + +typedef enum +{ + SAL_XSPI_ORDERINVERTED = 0, +} SAL_XSPI_DataOrderTypeDef; + +/** + * @brief Enumeration of supported physical link configurations. + */ + +typedef enum +{ + PHY_LINK_1S1S1S, /*!< Physical link configure in 1S1S1S */ + PHY_LINK_1S1S2S, /*!< Physical link configure in 1S1S2S */ + PHY_LINK_1S2S2S, /*!< Physical link configure in 1S2S2S */ + PHY_LINK_1S1D1D, /*!< Physical link configure in 1S1D1D */ + PHY_LINK_4S4S4S, /*!< Physical link configure in 4S4S4S */ + PHY_LINK_4S4D4D, /*!< Physical link configure in 4S4D4D */ + PHY_LINK_4D4D4D, /*!< Physical link configure in 4D4D4D */ + PHY_LINK_1S8S8S, /*!< Physical link configure in 1S8S8S */ + PHY_LINK_8S8D8D, /*!< Physical link configure in 8S8D8D */ + PHY_LINK_8D8D8D, /*!< Physical link configure in 8D8D8D */ + + PHY_LINK_RAM8, /*!< Physical link configure for RAM 8lines of data */ +#if defined(HAL_XSPI_DATA_16_LINES) + PHY_LINK_RAM16, /*!< Physical link configure for RAM 16lines of data */ +#endif /* defined(HAL_XSPI_DATA_16_LINES) */ +} SAL_XSPI_PhysicalLinkTypeDef; + +typedef struct +{ + XSPI_HandleTypeDef *hxspi; /*!< Handle on the XSPI instance */ + XSPI_RegularCmdTypeDef Commandbase; /*!< Command base configuration */ + uint8_t CommandExtension; /*!< Flag on the 16-bit command extension 0 inverted 1 the same */ + uint8_t SFDPDummyCycle; /*!< SDPF dummy cycle */ + SAL_XSPI_PhysicalLinkTypeDef PhyLink; /*!< Only used for data Read in 4S4D4d 2S2D2D 1S1D1D */ + uint8_t DTRDummyCycle; /*!< Specify that DTR read only valid for data read using DTRDummyCycle value */ +} SAL_XSPI_ObjectTypeDef; + +/** + * @brief define the list of the parameter + */ +typedef enum +{ + PARAM_PHY_LINK, /*!< Physical link parameter */ + PARAM_DUMMY_CYCLES, /*!< Dummy cycle parameter */ + PARAM_ADDRESS_4BYTES, /*!< Address size parameter */ + PARAM_DATA_STROBE, /*!< Data strobe parameter */ + PARAM_FLASHSIZE, /*!< Flash size parameter */ +} SAL_XSPI_MemParamTypeTypeDef; +/** + * @} + */ + +/* Exported Macro ------------------------------------------------------------*/ + +#define SAL_XSPI_SET_DTRREADDUMMYCYLE(_OBJ_,_VAL_) (_OBJ_).DTRDummyCycle = (_VAL_) +#define SAL_XSPI_SET_SFDPDUMMYCYLE(_OBJ_,_VAL_) (_OBJ_).SFDPDummyCycle = (_VAL_) +#define SAL_XSPI_SET_COMMANDEXTENSION(_OBJ_,_VAL_) (_OBJ_).CommandExtension = (_VAL_) + +#define SAL_XSPI_FORMAT_COMMANDSEND(_PTR_, _CMD_) \ + _PTR_.CommandType = SAL_XSPI_COMMAND_SEND; \ + _PTR_.Command = _CMD_; + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SAL_XSPI_Exported_Functions SAL XSP Exported Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SAL_XSPI_TYPE_H */ + diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c b/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c new file mode 100644 index 0000000..ebbe4f6 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c @@ -0,0 +1,354 @@ +/** + ****************************************************************************** + * @file stm32_sdcard_driver.c + * @author MCD Application Team + * @brief This file implements the SDCARD driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem.h" +#include "stm32_extmem_conf.h" +#if EXTMEM_DRIVER_SDCARD == 1 +#if EXTMEM_SAL_SD == 1 +#include "../sal/stm32_sal_sd_api.h" +#endif /* EXTMEM_SAL_SD */ +#if EXTMEM_SAL_MMC == 1 +#include "../sal/stm32_sal_mmc_api.h" +#endif /* EXTMEM_SAL_MMC */ + +#include "stm32_sdcard_driver_api.h" +#if EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) +#include "string.h" +#include "stdio.h" +#endif /* EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 || defined(EXTMEM_MACRO_DEBUG) */ + +/** @defgroup SDCARD SDCARD driver + * @ingroup EXTMEM_DRIVER + * @{ + */ + +/* Private Macros ------------------------------------------------------------*/ +/** @defgroup SDCARD_Private_Macro Private Macro + * @{ + */ + +/** + * @brief Default Timeout value (ms) + */ +#define DRIVER_DEFAULT_TIMEOUT 300 + +/** + * @brief Debug macro for a string. + */ +#if EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 && defined(EXTMEM_MACRO_DEBUG) +#define SDCARD_DEBUG_STR(_STR_) { \ + EXTMEM_MACRO_DEBUG("\tSDCARD::"); \ + EXTMEM_MACRO_DEBUG(_STR_); \ + EXTMEM_MACRO_DEBUG("\n\r"); \ + } +#else +#define SDCARD_DEBUG_STR(_STR_) +#endif /* EXTMEM_DRIVER_SDCARD_DEBUG_LEVEL > 0 || defined(EXTMEM_MACRO_DEBUG) */ + +/** + * @} + */ + +/* Private typedefs ---------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SDCARD_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the SDCARD driver. + * @param Peripheral Pointer to the peripheral object. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Init(void *Peripheral, + EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject) +{ + EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK; + + /* initialize the instance */ + SDCARD_DEBUG_STR("initialize the instance") + switch (SDCARDObject->sdcard_public.Link) + { + case EXTMEM_DRIVER_SDCARD_LINKSD : + if (HAL_OK != SAL_SD_Init(&SDCARDObject->sdcard_private.SALObject.SDObject, Peripheral, + &SDCARDObject->sdcard_private.Info)) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + break; +#if EXTMEM_SAL_MMC == 1 + case EXTMEM_DRIVER_SDCARD_LINKMMC: + if (HAL_OK != SAL_MMC_Init(&SDCARDObject->SALObject.MMCObject, Peripheral)) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + break; +#endif /* EXTMEM_SAL_MMC == 1 */ + default : + retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE; + break; + } + + return retr; +} + +/** + * @brief Deinitializes the SDCARD driver. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_DeInit(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject) +{ + EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK; + SDCARDObject->sdcard_private.Info.BlockNbr = 0; + return retr; +} + +/** + * @brief Reads data from the SDCARD memory. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @param Address Memory address. + * @param Data Pointer to the data buffer to store the read data. + * @param Size Size of data to read (in bytes). + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Read(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + uint32_t Address, uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK; + HAL_StatusTypeDef hal_status = HAL_OK; + uint32_t block_size = SDCARDObject->sdcard_private.Info.BlockSize; + + if (block_size == 0u) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + else + { + uint32_t block_num = Address / block_size; + uint32_t block_count = Size / block_size; + + /* Check if Address and size are multiple of block size */ + if (((Address % block_size) != 0u) || ((Size % block_size) != 0u)) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM; + goto error; + } + + if (block_count > SDCARDObject->sdcard_private.Info.BlockNbr) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM; + goto error; + } + + switch (SDCARDObject->sdcard_public.Link) + { + case EXTMEM_DRIVER_SDCARD_LINKSD : + hal_status = SAL_SD_ReadData(&SDCARDObject->sdcard_private.SALObject.SDObject, block_num, Data, block_count); + break; +#if EXTMEM_SAL_MMC == 1 + case EXTMEM_DRIVER_SDCARD_LINKMMC: + hal_status = SAL_MMC_Read(&SDCARDObject->sdcard_private.SALObject.MMCObject, block_num, Data, block_count); + break; +#endif /* EXTMEM_SAL_MMC == 1 */ + default : + retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE; + break; + } + + if (HAL_OK != hal_status) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_READ; + } + } +error: + return retr; +} + +/** + * @brief Writes data to the SDCARD memory. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @param Address Memory address. + * @param Data Pointer to the data buffer to be written. + * @param Size Size of data to be written (in bytes). + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Write(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + uint32_t Address, const uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK; + HAL_StatusTypeDef hal_status = HAL_OK; + uint32_t block_size = SDCARDObject->sdcard_private.Info.BlockSize; + if (block_size == 0u) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + else + { + uint32_t block_num = Address / block_size; + uint32_t block_count = Size / block_size; + + /* Check if Address and size are multiple of block size */ + if (((Address % block_size) != 0u) || ((Size % block_size) != 0u)) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM; + goto error; + } + + if (block_count > SDCARDObject->sdcard_private.Info.BlockNbr) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM; + goto error; + } + + switch (SDCARDObject->sdcard_public.Link) + { + case EXTMEM_DRIVER_SDCARD_LINKSD : + hal_status = SAL_SD_WriteData(&SDCARDObject->sdcard_private.SALObject.SDObject, block_num, Data, block_count); + break; + case EXTMEM_DRIVER_SDCARD_LINKMMC: + default : + retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE; + break; + } + + if (HAL_OK != hal_status) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_WRITE; + } + } +error: + return retr; +} + +/** + * @brief Erases blocks in the SDCARD memory. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @param Address Memory address. + * @param Size Size of data to erase (in bytes). + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_EraseBlock(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + uint32_t Address, uint32_t Size) +{ + EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK; + HAL_StatusTypeDef hal_status = HAL_OK; + uint32_t block_size = SDCARDObject->sdcard_private.Info.BlockSize; + + if (block_size == 0u) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + else + { + uint32_t block_num = Address / block_size; + uint32_t block_count = Size / block_size; + + if ((Size % block_size) != 0u) + { + block_count = block_count + 1u; + } + + /* Check if Address is multiple of block size */ + if ((Address % block_size) != 0u) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM; + goto error; + } + + if (block_count > SDCARDObject->sdcard_private.Info.BlockNbr) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR_PARAM; + goto error; + } + + switch (SDCARDObject->sdcard_public.Link) + { + case EXTMEM_DRIVER_SDCARD_LINKSD : + hal_status = SAL_SD_EraseBlock(&SDCARDObject->sdcard_private.SALObject.SDObject, block_num, block_count); + break; + case EXTMEM_DRIVER_SDCARD_LINKMMC: + default : + retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE; + break; + } + + if (HAL_OK != hal_status) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + } +error: + return retr; +} + +/** + * @brief Performs a mass erase of the SDCARD memory. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Erase(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject) +{ + EXTMEM_DRIVER_SDCARD_StatusTypeDef retr = EXTMEM_DRIVER_SDCARD_OK; + HAL_StatusTypeDef hal_status = HAL_OK; + switch (SDCARDObject->sdcard_public.Link) + { + case EXTMEM_DRIVER_SDCARD_LINKSD : + hal_status = SAL_SD_MassErase(&SDCARDObject->sdcard_private.SALObject.SDObject); + break; + case EXTMEM_DRIVER_SDCARD_LINKMMC: + default : + retr = EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE; + break; + } + + if (HAL_OK != hal_status) + { + retr = EXTMEM_DRIVER_SDCARD_ERROR; + } + return retr; +} + +/** + * @brief Retrieves SDCARD information. + * @param SDCARDObject Pointer to the SDCARD driver object. + * @param Info Pointer to the SDCARD information structure to be filled. + * @retval @ref EXTMEM_DRIVER_SDCARD_StatusTypeDef + */ +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_GetInfo(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info) +{ + Info->BlockSize = SDCARDObject->sdcard_private.Info.BlockSize; + Info->BlockNbr = SDCARDObject->sdcard_private.Info.BlockNbr; + return EXTMEM_DRIVER_SDCARD_OK; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_api.h b/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_api.h new file mode 100644 index 0000000..fe6ee11 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_api.h @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * @file stm32_sdcard_driver_api.h + * @author MCD Application Team + * @brief This file contains SDCARD driver API definitions. + ****************************************************************************** + * @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 __STM32_SDCARD_DRIVER_API_H +#define __STM32_SDCARD_DRIVER_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if EXTMEM_DRIVER_SDCARD == 1 + +/** @addtogroup SDCARD + * @ingroup EXTMEM_DRIVER + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +/** @addtogroup SDCARD_Exported_Types + * @{ + */ + +/** + * @brief Enumeration of error codes for the SDCARD driver. + */ +typedef enum +{ + EXTMEM_DRIVER_SDCARD_OK = 0, /*!< status ok */ + EXTMEM_DRIVER_SDCARD_ERROR_LINKTYPE = -1, /*!< error on the link type */ + EXTMEM_DRIVER_SDCARD_ERROR_READ = -2, /*!< error on the read operation */ + EXTMEM_DRIVER_SDCARD_ERROR_WRITE = -3, /*!< error on the write operation */ + EXTMEM_DRIVER_SDCARD_ERROR_PARAM = -4, /*!< error on the parameter */ + EXTMEM_DRIVER_SDCARD_ERROR = -128, /*!< error */ +} EXTMEM_DRIVER_SDCARD_StatusTypeDef; + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** + * @addtogroup SDCARD_Exported_Functions Exported Functions + * @{ + */ + +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Init(void *Peripheral, + EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject); +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_DeInit(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject); +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Read(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + uint32_t Address, uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Write(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + uint32_t Address, const uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_EraseBlock(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + uint32_t Address, uint32_t Size); +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_Erase(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject); +EXTMEM_DRIVER_SDCARD_StatusTypeDef EXTMEM_DRIVER_SDCARD_GetInfo(EXTMEM_DRIVER_SDCARD_ObjectTypeDef *SDCARDObject, + EXTMEM_DRIVER_SDCARD_InfoTypeDef *Info); + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SDCARD_DRIVER_API_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_type.h b/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_type.h new file mode 100644 index 0000000..a89661a --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver_type.h @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * @file stm32_sdcard_type.h + * @author MCD Application Team + * @brief This file contains SDCARD driver type definitions. + ****************************************************************************** + * @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 __STM32_SDCARD_TYPE_H +#define __STM32_SDCARD_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if EXTMEM_DRIVER_SDCARD == 1 + +/** @addtogroup SDCARD + * @ingroup EXTMEM_DRIVER + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SDCARD_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Enumeration of physical link types for SDCARD communication. + */ +typedef enum +{ + EXTMEM_DRIVER_SDCARD_LINKSD, /*!< link SD card */ + EXTMEM_DRIVER_SDCARD_LINKMMC, /*!< link EMMC card */ + EXTMEM_DRIVER_SDCARD_LINKSPI /*!< link SPI card */ +} SDCardLinkTypeDef; + +/** + * @brief Driver SDCARD instance definition + */ +typedef struct +{ + struct + { + SDCardLinkTypeDef Link; /*!< Physical link type. */ + } sdcard_public; + + struct + { + EXTMEM_DRIVER_SDCARD_InfoTypeDef Info; /*!< SDCARD information. */ + union + { +#if EXTMEM_SAL_SD == 1 + SAL_SD_ObjectTypeDef SDObject; /*!< SAL SD object. */ +#endif /* EXTMEM_SAL_SD == 1 */ +#if EXTMEM_SAL_MMC == 1 + SAL_MMC_ObjectTypeDef MMCObject; /*!< SAL MMC object. */ +#endif /* EXTMEM_SAL_MMC == 1 */ + } SALObject; + } sdcard_private; + +} EXTMEM_DRIVER_SDCARD_ObjectTypeDef; + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_SDCARD_TYPE_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c b/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c new file mode 100644 index 0000000..e6dec55 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c @@ -0,0 +1,1189 @@ +/** + ****************************************************************************** + * @file stm32_extmem.c + * @author MCD Application Team + * @brief This file includes a driver for external memory support + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ +/** + * @brief Macro to get memory table definition + */ +#define EXTMEM_C + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem.h" +#include "stm32_extmem_conf.h" + +#if EXTMEM_DRIVER_NOR_SFDP == 1 +#include "nor_sfdp/stm32_sfdp_driver_api.h" +#endif /* EXTMEM_DRIVER_NOR_SFDP */ + +#if EXTMEM_DRIVER_PSRAM == 1 +#include "psram/stm32_psram_driver_api.h" +#endif /* EXTMEM_DRIVER_PSRAM */ + +#if EXTMEM_DRIVER_SDCARD == 1 +#include "sdcard/stm32_sdcard_driver_api.h" +#endif /* EXTMEM_DRIVER_SDCARD */ + +#if EXTMEM_DRIVER_CUSTOM == 1 +#include "custom/stm32_custom_driver_api.h" +#endif /* EXTMEM_DRIVER_CUSTOM */ + +#if EXTMEM_DRIVER_USER == 1 +#include "user/stm32_user_driver_api.h" +#endif /* EXTMEM_DRIVER_USER */ + +/** + * @defgroup EXTMEM_DRIVER + * @{ + */ + +/** + * @} + */ + +/** + * @defgroup EXTMEM_SAL + * @{ + */ + +/** + * @} + */ + +/** + * @defgroup EXTMEM + * @{ + */ + +/* Private Macros ------------------------------------------------------------*/ +/** + * @defgroup EXTMEM_Private_Macros External Memory Private Macros + * @{ + */ +/** + * @brief EXTMEM debug function + */ +/** + * @brief Macro used to trace EXTMEM function calls + */ + +#if defined(EXTMEM_DEBUG_LEVEL) && defined(EXTMEM_MACRO_DEBUG) +#if EXTMEM_DEBUG_LEVEL > 0 +#define EXTMEM_DEBUG(_MSG_) EXTMEM_MACRO_DEBUG(_MSG_) +#if EXTMEM_DEBUG_LEVEL > 1 +#define EXTMEM_FUNC_CALL() \ + do \ + { \ + EXTMEM_DEBUG(__func__); \ + EXTMEM_DEBUG("\n"); \ + } while (0); +#else +#define EXTMEM_FUNC_CALL() +#endif /* EXTMEM_DEBUG_LEVEL > 1 */ +#else +#define EXTMEM_DEBUG(_MSG_) +#define EXTMEM_FUNC_CALL() +#endif /* EXTMEM_DEBUG_LEVEL > 0 */ +#else +#define EXTMEM_DEBUG(_MSG_) +#define EXTMEM_FUNC_CALL() +#endif /* defined(EXTMEM_DEBUG_LEVEL) && defined(EXTMEM_MACRO_DEBUG) */ + +/** + * @brief Macro used to trace EXTMEM debug information + */ +#define EXTMEM_DEBUG_ENDL(_STRING_) \ + do \ + { \ + EXTMEM_DEBUG(_STRING_); \ + EXTMEM_DEBUG("\n"); \ + } while (0); + +/** + * @} + */ + +/* Private typedefs ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported variables ---------------------------------------------------------*/ + + +/** @defgroup EXTMEM_Exported_Functions External Memory Exported Functions + * @{ + */ + +/** + * @brief Initializes the external memory. + * @param MemId Memory identifier. + * @param ClockInput Clock input value for the memory. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_Init(uint32_t MemId, uint32_t ClockInput) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL(); + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Initialize the memory using NOR SFDP driver */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_Init(extmem_list_config[MemId].Handle, + extmem_list_config[MemId].ConfigType, + ClockInput, + &extmem_list_config[MemId].NorSfdpObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD: + { + /* Initialize the memory using SDCARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Init(extmem_list_config[MemId].Handle, + &extmem_list_config[MemId].SdCardObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + { + /* Initialize the memory using PSRAM driver */ + if (EXTMEM_DRIVER_PSRAM_OK != EXTMEM_DRIVER_PSRAM_Init(extmem_list_config[MemId].Handle, + extmem_list_config[MemId].ConfigType, + ClockInput, + &extmem_list_config[MemId].PsramObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Initialize the memory using CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_Init(extmem_list_config[MemId].Handle, + ClockInput, + &extmem_list_config[MemId].CustomObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Initialize the memory using USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status; + status = EXTMEM_DRIVER_USER_Init(MemId, + &extmem_list_config[MemId].UserObject); + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + { + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + } + case EXTMEM_DRIVER_USER_OK: + { + /* Nothing to do */ + retr = EXTMEM_OK; + break; + } + default: + { + retr = EXTMEM_ERROR_DRIVER; + break; + } + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Deinitializes the external memory. + * @param MemId Memory identifier. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_DeInit(uint32_t MemId) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL(); + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Uninitialize the memory using NOR SFDP driver */ + /* Return is always OK no need to test the returned value */ + (void)EXTMEM_DRIVER_NOR_SFDP_DeInit(&extmem_list_config[MemId].NorSfdpObject); + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD: + { + /* Uninitialize the memory using SDCARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_DeInit(&extmem_list_config[MemId].SdCardObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + { + /* Uninitialize the memory using PSRAM driver */ + /* Return is always OK no need to test the returned value */ + (void)EXTMEM_DRIVER_PSRAM_DeInit(&extmem_list_config[MemId].PsramObject); + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Uninitialize the memory using CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_DeInit(&extmem_list_config[MemId].CustomObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Uninitialize the memory using USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_DeInit(&extmem_list_config[MemId].UserObject); + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + case EXTMEM_DRIVER_USER_OK: + /* Nothing to do, the returned status is already set to EXTMEM_OK */ + break; + default: + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Reads data from the external memory. + * @param MemId Memory identifier. + * @param Address Address in memory to read from. + * @param Data Pointer to buffer where read data will be stored. + * @param Size Number of bytes to read. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_Read(uint32_t MemId, uint32_t Address, uint8_t *Data, uint32_t Size) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL() + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Perform the Read operation using the NOR SFDP driver */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_Read(&extmem_list_config[MemId].NorSfdpObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD: + { + /* Perform the Read operation using the SDCARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Read(&extmem_list_config[MemId].SdCardObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + { + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Perform the Read operation using the CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_Read(&extmem_list_config[MemId].CustomObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Perform the Read operation using the USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_Read(&extmem_list_config[MemId].UserObject, + Address, Data, Size); + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + case EXTMEM_DRIVER_USER_OK: + /* Nothing to do, the returned status is already set to EXTMEM_OK */ + break; + default: + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Writes data to the external memory. + * @param MemId Memory identifier. + * @param Address Address in memory to write to. + * @param Data Pointer to buffer containing data to be written. + * @param Size Number of bytes to write. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_Write(uint32_t MemId, uint32_t Address, const uint8_t *Data, uint32_t Size) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL() + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Perform the Write operation using the NOR SFDP driver */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_Write(&extmem_list_config[MemId].NorSfdpObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD: + { + /* Perform the Write operation using the SDCARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Write(&extmem_list_config[MemId].SdCardObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + { + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Perform the Write operation using the CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_Write(&extmem_list_config[MemId].CustomObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Perform the Write operation using the USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_Write(&extmem_list_config[MemId].UserObject, + Address, Data, Size); + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + case EXTMEM_DRIVER_USER_OK: + break; + default: + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Writes data to the external memory in mapped mode. + * @param MemId Memory identifier. + * @param Address Address in memory to write to. + * @param Data Pointer to buffer (must be 32-bit aligned) containing data to be written. + * @param Size Number of bytes to write. + * @retval EXTMEM_StatusTypeDef Status of the operation. + * + * @note This function performs write operations in mapped mode and requires specific processing due + * to write enable management when the memory is mapped. The operation splits the write into packets + * of page size, and for each packet, performs a write before entering mapped mode. + * + * @note To avoid issues during this process, it is mandatory that the targeted memory area has the following + * characteristics: the write region must be non-bufferable, non-shareable, and non-cacheable. + */ +EXTMEM_StatusTypeDef EXTMEM_WriteInMappedMode(uint32_t MemId, uint32_t Address, const uint8_t *const Data, + uint32_t Size) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL() + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + /* Perform the Write in mapped mode operation using the NOR SFDP driver */ + case EXTMEM_NOR_SFDP: + { + if (EXTMEM_DRIVER_NOR_SFDP_OK != + EXTMEM_DRIVER_NOR_SFDP_WriteInMappedMode(&extmem_list_config[MemId].NorSfdpObject, + Address, Data, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD : + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Erases a number of sectors in the external memory. + * @param MemId Memory identifier. + * @param Address Address in memory to start erase operation. + * @param Size Number of bytes to erase. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_EraseSector(uint32_t MemId, uint32_t Address, uint32_t Size) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL() + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Perform the Sector Erase operation using the NOR SFDP driver */ + const EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef *const object = &extmem_list_config[MemId].NorSfdpObject; + EXTMEM_DRIVER_NOR_SFDP_SectorTypeTypeDef sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1; + uint32_t local_address = Address; + uint32_t local_size = Size; + uint32_t sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType4Size; + + while (local_size != 0u) + { + /* if address is a modulo a sector size if sector */ + if ((object->sfdp_private.DriverInfo.EraseType4Size != 0u) + && (local_size >= sector_size) + && ((local_address % sector_size) == 0u)) + { + sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE4; + } + else + { + sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType3Size; + if ((object->sfdp_private.DriverInfo.EraseType3Size != 0u) + && (local_size >= sector_size) + && ((local_address % sector_size) == 0u)) + { + sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE3; + } + else + { + sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType2Size; + if ((object->sfdp_private.DriverInfo.EraseType2Size != 0u) + && (local_size >= sector_size) + && ((local_address % sector_size) == 0u)) + { + sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE2; + } + else + { + sector_size = (uint32_t)1u << object->sfdp_private.DriverInfo.EraseType1Size; + if ((object->sfdp_private.DriverInfo.EraseType1Size != 0u) + && ((local_address % sector_size) == 0u)) + { + sector_type = EXTMEM_DRIVER_NOR_SFDP_SECTOR_TYPE1; + } + else + { + retr = EXTMEM_ERROR_SECTOR_SIZE; + } + } + } + } + + if (retr == EXTMEM_OK) + { + if (EXTMEM_DRIVER_NOR_SFDP_OK != + EXTMEM_DRIVER_NOR_SFDP_SectorErase(&extmem_list_config[MemId].NorSfdpObject, + local_address, sector_type)) + { + retr = EXTMEM_ERROR_DRIVER; + } + } + + if (retr != EXTMEM_OK) + { + local_size = 0u; + } + else + { + local_address = local_address + sector_size; + if (sector_size > local_size) + { + local_size = 0u; + } + else + { + local_size = local_size - sector_size; + } + } + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD: + { + /* Perform the Sector Erase operation using the SDCARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_EraseBlock(&extmem_list_config[MemId].SdCardObject, + Address, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + { + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Perform the Sector Erase operation using the CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_EraseSector(&extmem_list_config[MemId].CustomObject, + Address, Size)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Perform the Sector Erase operation using the USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_EraseSector(&extmem_list_config[MemId].UserObject, + Address, Size); + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + case EXTMEM_DRIVER_USER_OK: + break; + default: + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Erases all sectors in the external memory. + * @param MemId Memory identifier. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_EraseAll(uint32_t MemId) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL() + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Perform the Mass Erase operation using the NOR SFDP driver */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != EXTMEM_DRIVER_NOR_SFDP_MassErase(&extmem_list_config[MemId].NorSfdpObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD: + { + /* Perform the Mass Erase operation using the SD CARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_Erase(&extmem_list_config[MemId].SdCardObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM: + { + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Perform the Mass Erase operation using the CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_MassErase(&extmem_list_config[MemId].CustomObject)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Perform the Mass Erase operation using the USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status = EXTMEM_DRIVER_USER_MassErase(&extmem_list_config[MemId].UserObject); + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + case EXTMEM_DRIVER_USER_OK: + break; + default: + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Returns information about the external memory. + * @param MemId Memory identifier. + * @param Info Pointer to structure to receive memory information. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_GetInfo(uint32_t MemId, void *Info) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL() + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Perform the Get Information operation using the NOR SFDP driver */ + EXTMEM_DRIVER_NOR_SFDP_GetFlashInfo(&extmem_list_config[MemId].NorSfdpObject, + (EXTMEM_NOR_SFDP_FlashInfoTypeDef *)Info); + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD : + { + /* Perform the Get Information operation using the SDCARD driver */ + if (EXTMEM_DRIVER_SDCARD_OK != EXTMEM_DRIVER_SDCARD_GetInfo(&extmem_list_config[MemId].SdCardObject, + (EXTMEM_DRIVER_SDCARD_InfoTypeDef *)Info)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Perform the Get Information operation using the CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_GetInfo(&extmem_list_config[MemId].CustomObject, + (EXTMEM_DRIVER_CUSTOM_MemInfoTypeDef *)Info)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Perform the Get Information operation using the USER driver */ + if (EXTMEM_DRIVER_USER_OK != EXTMEM_DRIVER_USER_GetInfo(&extmem_list_config[MemId].UserObject, + (EXTMEM_USER_MemInfoTypeDef *)Info)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Enables or disables the memory mapped mode. + * @param MemId Memory identifier. + * @param State Enable or disable state (@ref EXTMEM_StateTypeDef). + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_MemoryMappedMode(uint32_t MemId, EXTMEM_StateTypeDef State) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL(); + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + case EXTMEM_NOR_SFDP: + { + /* Perform the memory Map operation using the NOR SFDP driver */ + if (EXTMEM_ENABLE == State) + { + /* Start the memory mapped mode */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != + EXTMEM_DRIVER_NOR_SFDP_Enable_MemoryMappedMode(&extmem_list_config[MemId].NorSfdpObject)) + { + return EXTMEM_ERROR_DRIVER; + } + } + else + { + /* Stop the memory mapped mode */ + if (EXTMEM_DRIVER_NOR_SFDP_OK != + EXTMEM_DRIVER_NOR_SFDP_Disable_MemoryMappedMode(&extmem_list_config[MemId].NorSfdpObject)) + { + return EXTMEM_ERROR_DRIVER; + } + } + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM : + { + /* Perform the memory Map operation using the PSRAM driver */ + if (EXTMEM_ENABLE == State) + { + /* Start the memory mapped mode */ + if (EXTMEM_DRIVER_PSRAM_OK != + EXTMEM_DRIVER_PSRAM_Enable_MemoryMappedMode(&extmem_list_config[MemId].PsramObject)) + { + return EXTMEM_ERROR_DRIVER; + } + } + else + { + /* Stop the memory mapped mode */ + if (EXTMEM_DRIVER_PSRAM_OK != + EXTMEM_DRIVER_PSRAM_Disable_MemoryMappedMode(&extmem_list_config[MemId].PsramObject)) + { + return EXTMEM_ERROR_DRIVER; + } + } + break; + } +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM : + { + /* Perform the memory Map operation using the CUSTOM driver */ + if (EXTMEM_ENABLE == State) + { + /* Start the memory mapped mode */ + if (EXTMEM_DRV_CUSTOM_OK != + EXTMEM_DRIVER_CUSTOM_Enable_MemoryMappedMode(&extmem_list_config[MemId].CustomObject)) + { + return EXTMEM_ERROR_DRIVER; + } + } + else + { + /* Stop the memory mapped mode */ + if (EXTMEM_DRV_CUSTOM_OK != + EXTMEM_DRIVER_CUSTOM_Disable_MemoryMappedMode(&extmem_list_config[MemId].CustomObject)) + { + return EXTMEM_ERROR_DRIVER; + } + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER : + { + /* Perform the memory Map operation using the USER driver */ + EXTMEM_DRIVER_USER_StatusTypeDef status; + if (EXTMEM_ENABLE == State) + { + /* Start the memory mapped mode */ + status = EXTMEM_DRIVER_USER_Enable_MemoryMappedMode(&extmem_list_config[MemId].UserObject); + } + else + { + /* Stop the memory mapped mode */ + status = EXTMEM_DRIVER_USER_Disable_MemoryMappedMode(&extmem_list_config[MemId].UserObject); + } + switch (status) + { + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + case EXTMEM_DRIVER_USER_OK: + break; + default: + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD : + /* Functionality not supported in this driver */ + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ + /* Unknown type of EXTMEM driver */ + default: + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} + +/** + * @brief Gets the base address of the mapped external memory. + * @param MemId Memory identifier. + * @param BaseAddress Pointer to variable to receive the base address. + * @retval EXTMEM_StatusTypeDef Status of the operation. + */ +EXTMEM_StatusTypeDef EXTMEM_GetMapAddress(uint32_t MemId, uint32_t *BaseAddress) +{ + EXTMEM_StatusTypeDef retr = EXTMEM_ERROR_INVALID_ID; + EXTMEM_FUNC_CALL(); + + /* Check the memory ID */ + if (MemId < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef))) + { + retr = EXTMEM_OK; + + /* Check type of EXTMEM driver used to access memory */ + switch (extmem_list_config[MemId].MemType) + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 || EXTMEM_DRIVER_PSRAM == 1 + case EXTMEM_PSRAM: + case EXTMEM_NOR_SFDP: + { + /* Define Map address based on Instance used for memory access */ +#if defined(XSPI1) + if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == XSPI1) + { + *BaseAddress = XSPI1_BASE; + } +#if defined(XSPI2) + else if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == XSPI2) + { + *BaseAddress = XSPI2_BASE; + } +#if defined(XSPI3) + else if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == XSPI3) + { + *BaseAddress = XSPI3_BASE; + } +#endif /* XSPI3 */ +#endif /* XSPI2 */ +#else /* XSPI1 */ + if (((XSPI_HandleTypeDef *)extmem_list_config[MemId].Handle)->Instance == OCTOSPI1) + { + *BaseAddress = OCTOSPI1_BASE; + } +#endif /* XSPI1 */ + else + { + retr = EXTMEM_ERROR_DRIVER; + } + + break; + } +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 || EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + case EXTMEM_SDCARD : + { + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + } +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + case EXTMEM_CUSTOM: + { + /* Perform the Get Map Address operation using the CUSTOM driver */ + if (EXTMEM_DRV_CUSTOM_OK != EXTMEM_DRIVER_CUSTOM_GetMapAddress(&extmem_list_config[MemId].CustomObject, + BaseAddress)) + { + retr = EXTMEM_ERROR_DRIVER; + } + break; + } +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + case EXTMEM_USER: + { + /* Perform the Get Map Address operation using the USER driver */ + switch (EXTMEM_DRIVER_USER_GetMapAddress(&extmem_list_config[MemId].UserObject, BaseAddress)) + { + case EXTMEM_DRIVER_USER_OK: + break; + case EXTMEM_DRIVER_USER_NOTSUPPORTED: + retr = EXTMEM_ERROR_NOTSUPPORTED; + break; + default : + retr = EXTMEM_ERROR_DRIVER; + break; + } + break; + } +#endif /* EXTMEM_DRIVER_USER == 1 */ + /* Unknown type of EXTMEM driver */ + default : + { + EXTMEM_DEBUG("\terror : unknown memory type\n"); + retr = EXTMEM_ERROR_UNKNOWNMEMORY; + break; + } + } + } + return retr; +} +/** + * @} + */ + +/** + * @} + */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.h b/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.h new file mode 100644 index 0000000..2223a60 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.h @@ -0,0 +1,165 @@ +/** + ****************************************************************************** + * @file stm32_extmem.h + * @author MCD Application Team + * @brief This file contains the external memory functions prototypes. + ****************************************************************************** + * @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 __STM32_EXTMEM_H_ +#define __STM32_EXTMEM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup EXTMEM + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +#include + +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup EXTMEM_Exported_Types External Memory Exported Types + * @{ + */ + +/** + * @brief Middleware version number + */ +#define EXTMEM_VERSION 0x00010500 /* Version v1.5.0 */ + +/** + * @brief Types of supported memories + */ +typedef enum +{ + EXTMEM_NOR_SFDP, + EXTMEM_NOR_CFI, + EXTMEM_PSRAM, + EXTMEM_SDCARD, + EXTMEM_CUSTOM, + EXTMEM_USER +} EXTMEM_TypeTypeDef; + +/** + * @brief EXTMEM module function call return values + */ +typedef enum +{ + EXTMEM_OK, /*!< Action performed with a status ok */ + EXTMEM_ERROR_NOTSUPPORTED = -1, /*!< Action not supported by the memory type */ + EXTMEM_ERROR_UNKNOWNMEMORY = -2, /*!< Unknown memory type */ + EXTMEM_ERROR_DRIVER = -3, /*!< Error return by the driver layer */ + EXTMEM_ERROR_SECTOR_SIZE = -4, /*!< Inconsistency between the size and the sector size of the memory */ + EXTMEM_ERROR_INVALID_ID = -5, /*!< Invalid memory ID */ + EXTMEM_ERROR_PARAM = -6, /*!< Parameter value error */ +} EXTMEM_StatusTypeDef; + +/** + * @brief Enable/disable state of the module + */ +typedef enum +{ + EXTMEM_ENABLE, /*!< State enable */ + EXTMEM_DISABLE /*!< State disable */ +} EXTMEM_StateTypeDef; + +/** + * @brief NOR SFDP memory information structure + */ +typedef struct +{ + uint8_t FlashSize; /*!< Specifies the flash size as a power of 2 */ + uint32_t PageSize; /*!< Page size in bytes */ + uint32_t EraseType1Size; /*!< Erase Type 1 size */ + uint32_t EraseType2Size; /*!< Erase Type 2 size */ + uint32_t EraseType3Size; /*!< Erase Type 3 size */ + uint32_t EraseType4Size; /*!< Erase Type 4 size */ +} EXTMEM_NOR_SFDP_FlashInfoTypeDef; + + +/** + * @brief USER memory information structure + */ +typedef struct +{ + uint8_t MemSize; /*!< Specifies the memory size as a power of 2 */ + uint32_t MpuCache; /*!< MPU Cache */ +} EXTMEM_USER_MemInfoTypeDef; + +/** + * @brief SD card information structure + */ +typedef struct +{ + uint32_t CardType; /*!< Specifies the card type */ + uint32_t CardVersion; /*!< Specifies the card version */ + uint32_t Class; /*!< Specifies the card class */ + uint32_t RelCardAdd; /*!< Specifies the relative card address */ + uint32_t BlockNbr; /*!< Specifies the card capacity in blocks */ + uint32_t BlockSize; /*!< Specifies the block size in bytes */ + uint32_t LogBlockNbr; /*!< Specifies the card logical capacity in blocks */ + uint32_t LogBlockSize; /*!< Specifies the logical block size in bytes */ + uint32_t CardSpeed; /*!< Specifies the card speed */ +} EXTMEM_DRIVER_SDCARD_InfoTypeDef; + +/** + * @brief Number of physical I/O line(s) connected with the memory + */ +typedef enum +{ + EXTMEM_LINK_CONFIG_1LINE, /*!< Configuration using 1 line */ + EXTMEM_LINK_CONFIG_2LINES, /*!< Configuration using 2 lines */ + EXTMEM_LINK_CONFIG_4LINES, /*!< Configuration using 4 lines */ + EXTMEM_LINK_CONFIG_8LINES, /*!< Configuration using 8 lines */ + EXTMEM_LINK_CONFIG_16LINES, /*!< Configuration using 16 lines */ +} EXTMEM_LinkConfig_TypeDef; + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup EXTMEM_Exported_Functions External Memory Exported Functions + * @{ + */ + +EXTMEM_StatusTypeDef EXTMEM_Init(uint32_t MemId, uint32_t ClockInput); +EXTMEM_StatusTypeDef EXTMEM_DeInit(uint32_t MemId); +EXTMEM_StatusTypeDef EXTMEM_Read(uint32_t MemId, uint32_t Address, uint8_t *Data, uint32_t Size); +EXTMEM_StatusTypeDef EXTMEM_Write(uint32_t MemId, uint32_t Address, const uint8_t *Data, uint32_t Size); +EXTMEM_StatusTypeDef EXTMEM_WriteInMappedMode(uint32_t MemId, uint32_t Address, const uint8_t *const Data, + uint32_t Size); +EXTMEM_StatusTypeDef EXTMEM_EraseSector(uint32_t MemId, uint32_t Address, uint32_t Size); +EXTMEM_StatusTypeDef EXTMEM_EraseAll(uint32_t MemId); +EXTMEM_StatusTypeDef EXTMEM_GetInfo(uint32_t MemId, void *Info); +EXTMEM_StatusTypeDef EXTMEM_MemoryMappedMode(uint32_t MemId, EXTMEM_StateTypeDef State); +EXTMEM_StatusTypeDef EXTMEM_GetMapAddress(uint32_t MemId, uint32_t *BaseAddress); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_EXTMEM_H_ */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem_type.h b/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem_type.h new file mode 100644 index 0000000..03d4f4e --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem_type.h @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * @file stm32_extmem_type.h + * @author MCD Application Team + * @brief This file contains the external memory type definition. + ****************************************************************************** + * @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 __STM32_EXTMEM_TYPE_H_ +#define __STM32_EXTMEM_TYPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup EXTMEM + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +#if EXTMEM_SAL_XSPI == 1 +#include "sal/stm32_sal_xspi_type.h" +#endif /* EXTMEM_SAL_XSPI */ + +#if EXTMEM_SAL_SD == 1 +#include "sal/stm32_sal_sd_type.h" +#endif /* EXTMEM_SAL_SD */ + +#if EXTMEM_SAL_MMC == 1 +#include "sal/stm32_sal_mmc_type.h" +#endif /* EXTMEM_SAL_MMC */ + +#if EXTMEM_DRIVER_NOR_SFDP == 1 +#include "nor_sfdp/stm32_sfdp_driver_type.h" +#endif /* DRIVER_SFDP_ENABLED */ + +#if EXTMEM_DRIVER_SDCARD == 1 +#include "sdcard/stm32_sdcard_driver_type.h" +#endif /* DRIVER_SDCARD_ENABLED */ + +#if EXTMEM_DRIVER_PSRAM == 1 +#include "psram/stm32_psram_driver_type.h" +#endif /* DRIVER_PSRAM_ENABLED */ + +#if EXTMEM_DRIVER_CUSTOM == 1 +#include "custom/stm32_custom_driver_type.h" +#endif /* DRIVER_USER_ENABLED */ + +#if EXTMEM_DRIVER_USER == 1 +#include "user/stm32_user_driver_type.h" +#endif /* DRIVER_USER_ENABLED */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup EXTMEM_Exported_Macros External Memory Exported Macros + * @{ + */ +/** + * @brief Macro to get the minimum value + */ +#define EXTMEM_MIN(_A_,_B_) ((_A_)>(_B_))?(_B_):(_A_); +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup EXTMEM_Exported_Constants External Memory Exported Constants + * @{ + */ + +/** @defgroup EXTMEM_Manufacturer_IDs EXTMEM JEDEC Manufacturer IDs + * @{ + */ +#define EXTMEM_MANUFACTURER_MACRONIX (0xC2U) /*!< JEDEC ID for Macronix */ +#define EXTMEM_MANUFACTURER_GIGADEVICE (0xC8U) /*!< JEDEC ID for GigaDevice */ +#define EXTMEM_MANUFACTURER_ISSI (0x9DU) /*!< JEDEC ID for ISSI */ +/** + * @} + */ + +/** @defgroup EXTMEM_Common_JEDEC_Commands EXTMEM Common JEDEC commands identifiers + * @{ + */ +#define EXTMEM_READ_JEDEC_ID_SPI_COMMAND 0x9FU +#define EXTMEM_READ_JEDEC_ID_SIZE 0x04U + +#define EXTMEM_READ_SFDP_COMMAND 0x5AU +#define EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_DEFAULT 8U +#define EXTMEM_READ_SFDP_NB_DUMMY_CYCLES_OPI 20U + +#define EXTMEM_FAST_READ_NB_DUMMY_CYCLES_DEFAULT 8U + +/** + * @} + */ + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup EXTMEM_Exported_TypeDefinitions External Memory Exported Type Definitions + * @{ + */ + +/** + * @brief Definition of the memory + */ +typedef struct +{ + EXTMEM_TypeTypeDef MemType; /*!< Specifies the memory driver type */ + void *Handle; /*!< Pointer to HAL handle */ + EXTMEM_LinkConfig_TypeDef ConfigType; /*!< Specifies the physical link configuration */ + union + { +#if EXTMEM_DRIVER_NOR_SFDP == 1 + EXTMEM_DRIVER_NOR_SFDP_ObjectTypeDef NorSfdpObject; /*!< Object for NOR SFDP driver */ +#endif /* EXTMEM_DRIVER_NOR_SFDP == 1 */ +#if EXTMEM_DRIVER_SDCARD == 1 + EXTMEM_DRIVER_SDCARD_ObjectTypeDef SdCardObject; /*!< Object for SD Card driver */ +#endif /* EXTMEM_DRIVER_SDCARD == 1 */ +#if EXTMEM_DRIVER_PSRAM == 1 + EXTMEM_DRIVER_PSRAM_ObjectTypeDef PsramObject; /*!< Object for PSRAM driver */ +#endif /* EXTMEM_DRIVER_PSRAM == 1 */ +#if EXTMEM_DRIVER_CUSTOM == 1 + EXTMEM_DRIVER_CUSTOM_ObjectTypeDef CustomObject; /*!< Object for Custom driver */ +#endif /* EXTMEM_DRIVER_CUSTOM == 1 */ +#if EXTMEM_DRIVER_USER == 1 + EXTMEM_DRIVER_USER_ObjectTypeDef UserObject; /*!< Object for User driver */ +#endif /* EXTMEM_DRIVER_USER == 1 */ + }; +} EXTMEM_DefinitionTypeDef; + +/** + * @} + */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_EXTMEM_TYPE_H_ */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c b/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c new file mode 100644 index 0000000..65b1cc7 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c @@ -0,0 +1,212 @@ +/** + ****************************************************************************** + * @file stm32_user_driver.c + * @author MCD Application Team + * @brief This file implements the USER driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_extmem.h" +#include "stm32_extmem_conf.h" +#if EXTMEM_DRIVER_USER == 1 +#include "stm32_user_driver_api.h" +#include "stm32_user_driver_type.h" + +/** @defgroup USER USER driver + * @ingroup EXTMEM_DRIVER + * @{ + */ + +/* Private Macro ------------------------------------------------------------*/ +/** @defgroup USER_Private_Macro Private Macro + * @{ + */ + +/** + * @} + */ +/* Private typedefs ---------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup USER_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the USER driver. + * @param MemoryId Memory ID. + * @param UserObject Pointer to the USER driver object. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Init(uint32_t MemoryId, + EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + UserObject->MemID = MemoryId; /* Store the memory ID; can be used to control multiple user memories. */ + UserObject->PtrUserDriver = NULL; /* Can be used to link data with the memory ID. */ + return retr; +} + +/** + * @brief Deinitializes the USER driver. + * @param UserObject Pointer to the USER driver object. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_DeInit(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)UserObject; + return retr; +} + +/** + * @brief Reads data from the USER memory. + * @param UserObject Pointer to the USER driver object. + * @param Address Memory address. + * @param Data Pointer to the data buffer to store the read data. + * @param Size Size of data to read (in bytes). + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Read(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t Address, uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + (void)Address; + (void)Data; + (void)Size; + return retr; +} + +/** + * @brief Writes data to the USER memory. + * @param UserObject Pointer to the USER driver object. + * @param Address Memory address. + * @param Data Pointer to the data buffer to be written. + * @param Size Size of data to be written (in bytes). + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Write(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t Address, const uint8_t *Data, uint32_t Size) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + (void)Address; + (void)Data; + (void)Size; + return retr; +} + +/** + * @brief Erases sectors in the USER memory. + * @param UserObject Pointer to the USER driver object. + * @param Address Memory address. + * @param Size Size of data to erase (in bytes). + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_EraseSector(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t Address, uint32_t Size) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + (void)Address; + (void)Size; + return retr; +} + +/** + * @brief Performs a mass erase of the USER memory. + * @param UserObject Pointer to the USER driver object. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_MassErase(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + return retr; +} + +/** + * @brief Enables memory-mapped mode for the USER device. + * @param UserObject Pointer to the USER driver object. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Enable_MemoryMappedMode(EXTMEM_DRIVER_USER_ObjectTypeDef + *UserObject) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + return retr; +} + +/** + * @brief Disables memory-mapped mode for the USER device. + * @param UserObject Pointer to the USER driver object. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Disable_MemoryMappedMode( + EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + return retr; +} + +/** + * @brief Retrieves the mapped address. + * @param UserObject Pointer to the USER driver object. + * @param BaseAddress Pointer to store the mapped base address. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetMapAddress(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t *BaseAddress) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + (void)BaseAddress; + return retr; +} + +/** + * @brief Retrieves USER memory information. + * @param UserObject Pointer to the USER driver object. + * @param MemInfo Pointer to the USER memory information structure to be filled. + * @retval @ref EXTMEM_DRIVER_USER_StatusTypeDef + */ +__weak EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetInfo(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + EXTMEM_USER_MemInfoTypeDef *MemInfo) +{ + EXTMEM_DRIVER_USER_StatusTypeDef retr = EXTMEM_DRIVER_USER_NOTSUPPORTED; + (void)*UserObject; + (void)MemInfo; + return retr; +} + +/** + * @} + */ + +/** @addtogroup USER_Private_Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_USER == 1 */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_api.h b/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_api.h new file mode 100644 index 0000000..9f3d85f --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_api.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file stm32_user_driver_api.h + * @author MCD Application Team + * @brief This file contains USER driver API definitions. + ****************************************************************************** + * @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 __STM32_USER_DRIVER_API_H +#define __STM32_USER_DRIVER_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if EXTMEM_DRIVER_USER == 1 + +/** @addtogroup USER + * @ingroup EXTMEM_DRIVER + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup USER_Exported_Types Exported Types + * @{ + */ + +/** + * @brief Enumeration of error codes for the USER driver. + */ +typedef enum +{ + EXTMEM_DRIVER_USER_OK = 0, + EXTMEM_DRIVER_USER_ERROR_1 = -1, + EXTMEM_DRIVER_USER_ERROR_2 = -2, + EXTMEM_DRIVER_USER_ERROR_3 = -3, + EXTMEM_DRIVER_USER_ERROR_4 = -4, + EXTMEM_DRIVER_USER_ERROR_5 = -5, + EXTMEM_DRIVER_USER_ERROR_6 = -6, + EXTMEM_DRIVER_USER_ERROR_7 = -7, + EXTMEM_DRIVER_USER_ERROR_8 = -8, + EXTMEM_DRIVER_USER_ERROR_9 = -9, + EXTMEM_DRIVER_USER_ERROR_10 = -10, + + EXTMEM_DRIVER_USER_NOTSUPPORTED = -128 +} EXTMEM_DRIVER_USER_StatusTypeDef; + +/* Exported functions --------------------------------------------------------*/ +/** + * @addtogroup USER_Exported_Functions Exported functions + * @{ + */ + +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Init(uint32_t MemoryId, + EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_DeInit(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Read(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t Address, uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Write(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t Address, const uint8_t *Data, uint32_t Size); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_EraseSector(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t Address, uint32_t Size); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_MassErase(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Enable_MemoryMappedMode(EXTMEM_DRIVER_USER_ObjectTypeDef + *UserObject); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_Disable_MemoryMappedMode(EXTMEM_DRIVER_USER_ObjectTypeDef + *UserObject); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetMapAddress(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + uint32_t *BaseAddress); +EXTMEM_DRIVER_USER_StatusTypeDef EXTMEM_DRIVER_USER_GetInfo(EXTMEM_DRIVER_USER_ObjectTypeDef *UserObject, + EXTMEM_USER_MemInfoTypeDef *MemInfo); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_USER == 1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_USER_DRIVER_API_H */ diff --git a/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_type.h b/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_type.h new file mode 100644 index 0000000..470a035 --- /dev/null +++ b/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver_type.h @@ -0,0 +1,72 @@ +/** + ****************************************************************************** + * @file stm32_user_driver_type.h + * @author MCD Application Team + * @brief This file contains USER driver type definitions. + ****************************************************************************** + * @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 __STM32_USER_DRIVER_TYPE_H +#define __STM32_USER_DRIVER_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/** @addtogroup USER + * @ingroup EXTMEM_DRIVER + * @{ + */ + +#if EXTMEM_DRIVER_USER == 1 + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USER_Exported_constants Exported constants + * @{ + */ + + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup USER_Exported_Types Exported Types + * @{ + */ + +/** + * @brief USER driver object definition. + */ +typedef struct +{ + uint32_t MemID; /*!< Memory ID. */ + void *PtrUserDriver; /*!< Pointer to the user driver instance. */ +} EXTMEM_DRIVER_USER_ObjectTypeDef; + +/** + * @} + */ + +/** + * @} + */ +#endif /* EXTMEM_DRIVER_USER == 1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_USER_DRIVER_TYPE_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/LICENSE.md b/Middlewares/Third_Party/FreeRTOS/LICENSE.md new file mode 100644 index 0000000..28983bd --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/LICENSE.md @@ -0,0 +1,19 @@ +# MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h new file mode 100644 index 0000000..aae5229 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013-2019 ARM Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * ---------------------------------------------------------------------- + * + * $Date: 10. January 2017 + * $Revision: V2.1.0 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h FreeRTOS header file + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS_H_ +#define CMSIS_OS_H_ + +#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0]) + +#include "cmsis_os2.h" + +#endif // CMSIS_OS_H_ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c new file mode 100644 index 0000000..85d90fd --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c @@ -0,0 +1,2957 @@ +/* -------------------------------------------------------------------------- + * Copyright (c) 2013-2022 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * Name: cmsis_os2.c + * Purpose: CMSIS RTOS2 wrapper for FreeRTOS + * + *---------------------------------------------------------------------------*/ +#include + +#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core +#include "task.h" // ARM.FreeRTOS::RTOS:Core +#include "event_groups.h" // ARM.FreeRTOS::RTOS:Event Groups +#include "semphr.h" // ARM.FreeRTOS::RTOS:Core +#include "timers.h" // ARM.FreeRTOS::RTOS:Timers + +#include "freertos_mpool.h" // osMemoryPool definitions +#include "freertos_os2.h" // Configuration check and setup + +#include "cmsis_os2.h" // ::CMSIS:RTOS2 +#include "cmsis_compiler.h" // Compiler agnostic definitions + +/*---------------------------------------------------------------------------*/ +#ifndef __ARM_ARCH_6M__ + #define __ARM_ARCH_6M__ 0 +#endif +#ifndef __ARM_ARCH_7M__ + #define __ARM_ARCH_7M__ 0 +#endif +#ifndef __ARM_ARCH_7EM__ + #define __ARM_ARCH_7EM__ 0 +#endif +#ifndef __ARM_ARCH_8M_MAIN__ + #define __ARM_ARCH_8M_MAIN__ 0 +#endif +#ifndef __ARM_ARCH_7A__ + #define __ARM_ARCH_7A__ 0 +#endif + +#if ((__ARM_ARCH_7M__ == 1U) || \ + (__ARM_ARCH_7EM__ == 1U) || \ + (__ARM_ARCH_8M_MAIN__ == 1U)) +#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U)) +#elif (__ARM_ARCH_6M__ == 1U) +#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) +#elif (__ARM_ARCH_7A__ == 1U) +/* CPSR mask bits */ +#define CPSR_MASKBIT_I 0x80U + +#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U) +#else +#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) +#endif + +#if (__ARM_ARCH_7A__ == 1U) +/* CPSR mode bitmasks */ +#define CPSR_MODE_USER 0x10U +#define CPSR_MODE_SYSTEM 0x1FU + +#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM)) +#else +#define IS_IRQ_MODE() (__get_IPSR() != 0U) +#endif + +/* Limits */ +#define MAX_BITS_TASK_NOTIFY 31U +#define MAX_BITS_EVENT_GROUPS 24U + +#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U)) +#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U)) + +/* Kernel version and identification string definition (major.minor.rev: mmnnnrrrr dec) */ +#define KERNEL_VERSION (((uint32_t)tskKERNEL_VERSION_MAJOR * 10000000UL) | \ + ((uint32_t)tskKERNEL_VERSION_MINOR * 10000UL) | \ + ((uint32_t)tskKERNEL_VERSION_BUILD * 1UL)) + +#define KERNEL_ID ("FreeRTOS " tskKERNEL_VERSION_NUMBER) + +/* Timer callback information structure definition */ +typedef struct { + osTimerFunc_t func; + void *arg; +} TimerCallback_t; + +/* Kernel initialization state */ +static osKernelState_t KernelState = osKernelInactive; + +/* Get OS Tick count value */ +static uint32_t OS_Tick_GetCount (void); +#if (configUSE_TICKLESS_IDLE == 0) +/* Get OS Tick overflow status */ +static uint32_t OS_Tick_GetOverflow (void); +#endif +/* Get OS Tick interval */ +static uint32_t OS_Tick_GetInterval (void); + +/* + Heap region definition used by heap_5 variant + + Define configAPPLICATION_ALLOCATED_HEAP as nonzero value in FreeRTOSConfig.h if + heap regions are already defined and vPortDefineHeapRegions is called in application. + + Otherwise vPortDefineHeapRegions will be called by osKernelInitialize using + definition configHEAP_5_REGIONS as parameter. Overriding configHEAP_5_REGIONS + is possible by defining it globally or in FreeRTOSConfig.h. +*/ +#if defined(USE_FreeRTOS_HEAP_5) +#if (configAPPLICATION_ALLOCATED_HEAP == 0) + /* + FreeRTOS heap is not defined by the application. + Single region of size configTOTAL_HEAP_SIZE (defined in FreeRTOSConfig.h) + is provided by default. Define configHEAP_5_REGIONS to provide custom + HeapRegion_t array. + */ + #define HEAP_5_REGION_SETUP 1 + + #ifndef configHEAP_5_REGIONS + #define configHEAP_5_REGIONS xHeapRegions + + static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; + + static HeapRegion_t xHeapRegions[] = { + { ucHeap, configTOTAL_HEAP_SIZE }, + { NULL, 0 } + }; + #else + /* Global definition is provided to override default heap array */ + extern HeapRegion_t configHEAP_5_REGIONS[]; + #endif +#else + /* + The application already defined the array used for the FreeRTOS heap and + called vPortDefineHeapRegions to initialize heap. + */ + #define HEAP_5_REGION_SETUP 0 +#endif /* configAPPLICATION_ALLOCATED_HEAP */ +#endif /* USE_FreeRTOS_HEAP_5 */ + +#if defined(SysTick) +#undef SysTick_Handler + +/* CMSIS SysTick interrupt handler prototype */ +extern void SysTick_Handler (void); +/* FreeRTOS tick timer interrupt handler prototype */ +extern void xPortSysTickHandler (void); + +/* + SysTick handler implementation that also clears overflow flag. +*/ +#if (USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION == 0) +void SysTick_Handler (void) { +#if (configUSE_TICKLESS_IDLE == 0) + /* Clear overflow flag */ + SysTick->CTRL; +#endif + + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { + /* Call tick handler */ + xPortSysTickHandler(); + } +} +#endif +#endif /* SysTick */ + +/* + Setup SVC to reset value. +*/ +__STATIC_INLINE void SVC_Setup (void) { +#if (__ARM_ARCH_7A__ == 0U) + /* Service Call interrupt might be configured before kernel start */ + /* and when its priority is lower or equal to BASEPRI, svc instruction */ + /* causes a Hard Fault. */ + NVIC_SetPriority (SVCall_IRQn, 0U); +#endif +} + +/* + Function macro used to retrieve semaphore count from ISR +*/ +#ifndef uxSemaphoreGetCountFromISR +#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) ) +#endif + +/* + Determine if CPU executes from interrupt context or if interrupts are masked. +*/ +__STATIC_INLINE uint32_t IRQ_Context (void) { + uint32_t irq; + BaseType_t state; + + irq = 0U; + + if (IS_IRQ_MODE()) { + /* Called from interrupt context */ + irq = 1U; + } + else { + /* Get FreeRTOS scheduler state */ + state = xTaskGetSchedulerState(); + + if (state != taskSCHEDULER_NOT_STARTED) { + /* Scheduler was started */ + if (IS_IRQ_MASKED()) { + /* Interrupts are masked */ + irq = 1U; + } + } + } + + /* Return context, 0: thread context, 1: IRQ context */ + return (irq); +} + +/* Get OS Tick count value */ +static uint32_t OS_Tick_GetCount (void) { +#if (__ARM_ARCH_7A__ == 1U) + return (__get_CNTFRQ() - PL1_GetCurrentValue()); +#else + uint32_t load = SysTick->LOAD; + return (load - SysTick->VAL); +#endif /* __ARM_ARCH_7A__ */ +} + +#if (configUSE_TICKLESS_IDLE == 0) +/* Get OS Tick overflow status */ +static uint32_t OS_Tick_GetOverflow (void) { +#if (__ARM_ARCH_7A__ == 1U) + CNTP_CTL_Type cntp_ctl; + cntp_ctl.w = PL1_GetControl(); + return (cntp_ctl.b.ISTATUS); +#else + return ((SysTick->CTRL >> 16) & 1U); +#endif /* __ARM_ARCH_7A__ */ +} +#endif + +/* Get OS Tick interval */ +static uint32_t OS_Tick_GetInterval (void) { +#if (__ARM_ARCH_7A__ == 1U) + return (__get_CNTFRQ() + 1U); +#else + return (SysTick->LOAD + 1U); +#endif /* __ARM_ARCH_7A__ */ +} + +/* ==== Kernel Management Functions ==== */ + +/* + Initialize the RTOS Kernel. +*/ +osStatus_t osKernelInitialize (void) { + osStatus_t stat; + BaseType_t state; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else { + state = xTaskGetSchedulerState(); + + /* Initialize if scheduler not started and not initialized before */ + if ((state == taskSCHEDULER_NOT_STARTED) && (KernelState == osKernelInactive)) { + #if defined(USE_TRACE_EVENT_RECORDER) + /* Initialize the trace macro debugging output channel */ + EvrFreeRTOSSetup(0U); + #endif + #if defined(USE_FreeRTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1) + /* Initialize the memory regions when using heap_5 variant */ + vPortDefineHeapRegions (configHEAP_5_REGIONS); + #endif + KernelState = osKernelReady; + stat = osOK; + } else { + stat = osError; + } + } + + /* Return execution status */ + return (stat); +} + +/* + Get RTOS Kernel Information. +*/ +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size) { + + if (version != NULL) { + /* Version encoding is major.minor.rev: mmnnnrrrr dec */ + version->api = KERNEL_VERSION; + version->kernel = KERNEL_VERSION; + } + + if ((id_buf != NULL) && (id_size != 0U)) { + /* Buffer for retrieving identification string is provided */ + if (id_size > sizeof(KERNEL_ID)) { + id_size = sizeof(KERNEL_ID); + } + /* Copy kernel identification string into provided buffer */ + memcpy(id_buf, KERNEL_ID, id_size); + } + + /* Return execution status */ + return (osOK); +} + +/* + Get the current RTOS Kernel state. +*/ +osKernelState_t osKernelGetState (void) { + osKernelState_t state; + + switch (xTaskGetSchedulerState()) { + case taskSCHEDULER_RUNNING: + state = osKernelRunning; + break; + + case taskSCHEDULER_SUSPENDED: + state = osKernelLocked; + break; + + case taskSCHEDULER_NOT_STARTED: + default: + if (KernelState == osKernelReady) { + /* Ready, osKernelInitialize was already called */ + state = osKernelReady; + } else { + /* Not initialized */ + state = osKernelInactive; + } + break; + } + + /* Return current state */ + return (state); +} + +/* + Start the RTOS Kernel scheduler. +*/ +osStatus_t osKernelStart (void) { + osStatus_t stat; + BaseType_t state; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else { + state = xTaskGetSchedulerState(); + + /* Start scheduler if initialized and not started before */ + if ((state == taskSCHEDULER_NOT_STARTED) && (KernelState == osKernelReady)) { + /* Ensure SVC priority is at the reset value */ + SVC_Setup(); + /* Change state to ensure correct API flow */ + KernelState = osKernelRunning; + /* Start the kernel scheduler */ + vTaskStartScheduler(); + stat = osOK; + } else { + stat = osError; + } + } + + /* Return execution status */ + return (stat); +} + +/* + Lock the RTOS Kernel scheduler. +*/ +int32_t osKernelLock (void) { + int32_t lock; + + if (IRQ_Context() != 0U) { + lock = (int32_t)osErrorISR; + } + else { + switch (xTaskGetSchedulerState()) { + case taskSCHEDULER_SUSPENDED: + lock = 1; + break; + + case taskSCHEDULER_RUNNING: + vTaskSuspendAll(); + lock = 0; + break; + + case taskSCHEDULER_NOT_STARTED: + default: + lock = (int32_t)osError; + break; + } + } + + /* Return previous lock state */ + return (lock); +} + +/* + Unlock the RTOS Kernel scheduler. +*/ +int32_t osKernelUnlock (void) { + int32_t lock; + + if (IRQ_Context() != 0U) { + lock = (int32_t)osErrorISR; + } + else { + switch (xTaskGetSchedulerState()) { + case taskSCHEDULER_SUSPENDED: + lock = 1; + + if (xTaskResumeAll() != pdTRUE) { + if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) { + lock = (int32_t)osError; + } + } + break; + + case taskSCHEDULER_RUNNING: + lock = 0; + break; + + case taskSCHEDULER_NOT_STARTED: + default: + lock = (int32_t)osError; + break; + } + } + + /* Return previous lock state */ + return (lock); +} + +/* + Restore the RTOS Kernel scheduler lock state. +*/ +int32_t osKernelRestoreLock (int32_t lock) { + + if (IRQ_Context() != 0U) { + lock = (int32_t)osErrorISR; + } + else { + switch (xTaskGetSchedulerState()) { + case taskSCHEDULER_SUSPENDED: + case taskSCHEDULER_RUNNING: + if (lock == 1) { + vTaskSuspendAll(); + } + else { + if (lock != 0) { + lock = (int32_t)osError; + } + else { + if (xTaskResumeAll() != pdTRUE) { + if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { + lock = (int32_t)osError; + } + } + } + } + break; + + case taskSCHEDULER_NOT_STARTED: + default: + lock = (int32_t)osError; + break; + } + } + + /* Return new lock state */ + return (lock); +} + +/* + Get the RTOS kernel tick count. +*/ +uint32_t osKernelGetTickCount (void) { + TickType_t ticks; + + if (IRQ_Context() != 0U) { + ticks = xTaskGetTickCountFromISR(); + } else { + ticks = xTaskGetTickCount(); + } + + /* Return kernel tick count */ + return (ticks); +} + +/* + Get the RTOS kernel tick frequency. +*/ +uint32_t osKernelGetTickFreq (void) { + /* Return frequency in hertz */ + return (configTICK_RATE_HZ); +} + +/* + Get the RTOS kernel system timer count. +*/ +uint32_t osKernelGetSysTimerCount (void) { + uint32_t irqmask = IS_IRQ_MASKED(); + TickType_t ticks; + uint32_t val; +#if (configUSE_TICKLESS_IDLE != 0) + uint32_t val0; + + /* Low Power Tickless Idle controls timer overflow flag and therefore */ + /* OS_Tick_GetOverflow may be non-functional. As a workaround a reference */ + /* time is measured here before disabling interrupts. Timer value overflow */ + /* is then checked by comparing reference against latest time measurement. */ + /* Timer count value returned by this method is less accurate but if an */ + /* overflow is missed, an invalid timer count would be returned. */ + val0 = OS_Tick_GetCount(); +#endif + + __disable_irq(); + + ticks = xTaskGetTickCount(); + val = OS_Tick_GetCount(); + + /* Update tick count and timer value when timer overflows */ +#if (configUSE_TICKLESS_IDLE != 0) + if (val < val0) { + ticks++; + } +#else + if (OS_Tick_GetOverflow() != 0U) { + val = OS_Tick_GetCount(); + ticks++; + } +#endif + + val += ticks * OS_Tick_GetInterval(); + + if (irqmask == 0U) { + __enable_irq(); + } + + /* Return system timer count */ + return (val); +} + +/* + Get the RTOS kernel system timer frequency. +*/ +uint32_t osKernelGetSysTimerFreq (void) { + /* Return frequency in hertz */ + return (configCPU_CLOCK_HZ); +} + + +/* ==== Thread Management Functions ==== */ + +/* + Create a thread and add it to Active Threads. + + Limitations: + - The memory for control block and stack must be provided in the osThreadAttr_t + structure in order to allocate object statically. + - Attribute osThreadJoinable is not supported, NULL is returned if used. +*/ +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { + const char *name; + uint32_t stack; + TaskHandle_t hTask; + UBaseType_t prio; + int32_t mem; + + hTask = NULL; + + if ((IRQ_Context() == 0U) && (func != NULL)) { + stack = configMINIMAL_STACK_SIZE; + prio = (UBaseType_t)osPriorityNormal; + + name = NULL; + mem = -1; + + if (attr != NULL) { + if (attr->name != NULL) { + name = attr->name; + } + if (attr->priority != osPriorityNone) { + prio = (UBaseType_t)attr->priority; + } + + if ((prio < osPriorityIdle) || (prio > osPriorityISR) || ((attr->attr_bits & osThreadJoinable) == osThreadJoinable)) { + /* Invalid priority or unsupported osThreadJoinable attribute used */ + return (NULL); + } + + if (attr->stack_size > 0U) { + /* In FreeRTOS stack is not in bytes, but in sizeof(StackType_t) which is 4 on ARM ports. */ + /* Stack size should be therefore 4 byte aligned in order to avoid division caused side effects */ + stack = attr->stack_size / sizeof(StackType_t); + } + + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTask_t)) && + (attr->stack_mem != NULL) && (attr->stack_size > 0U)) { + /* The memory for control block and stack is provided, use static object */ + mem = 1; + } + else { + if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && (attr->stack_mem == NULL)) { + /* Control block and stack memory will be allocated from the dynamic pool */ + mem = 0; + } + } + } + else { + mem = 0; + } + + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem, + (StaticTask_t *)attr->cb_mem); + #endif + } + else { + if (mem == 0) { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + if (xTaskCreate ((TaskFunction_t)func, name, (configSTACK_DEPTH_TYPE)stack, argument, prio, &hTask) != pdPASS) { + hTask = NULL; + } + #endif + } + } + } + + /* Return thread ID */ + return ((osThreadId_t)hTask); +} + +/* + Get name of a thread. +*/ +const char *osThreadGetName (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + const char *name; + + if ((IRQ_Context() != 0U) || (hTask == NULL)) { + name = NULL; + } else { + name = pcTaskGetName (hTask); + } + + /* Return name as null-terminated string */ + return (name); +} + +/* + Return the thread ID of the current running thread. +*/ +osThreadId_t osThreadGetId (void) { + osThreadId_t id; + + id = (osThreadId_t)xTaskGetCurrentTaskHandle(); + + /* Return thread ID */ + return (id); +} + +/* + Get current thread state of a thread. +*/ +osThreadState_t osThreadGetState (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + osThreadState_t state; + + if ((IRQ_Context() != 0U) || (hTask == NULL)) { + state = osThreadError; + } + else { + switch (eTaskGetState (hTask)) { + case eRunning: state = osThreadRunning; break; + case eReady: state = osThreadReady; break; + case eBlocked: + case eSuspended: state = osThreadBlocked; break; + case eDeleted: + case eInvalid: + default: state = osThreadError; break; + } + } + + /* Return current thread state */ + return (state); +} + +/* + Get available stack space of a thread based on stack watermark recording during execution. +*/ +uint32_t osThreadGetStackSpace (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + uint32_t sz; + + if ((IRQ_Context() != 0U) || (hTask == NULL)) { + sz = 0U; + } else { + sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t)); + } + + /* Return remaining stack space in bytes */ + return (sz); +} + +/* + Change priority of a thread. +*/ +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if ((hTask == NULL) || (priority < osPriorityIdle) || (priority > osPriorityISR)) { + stat = osErrorParameter; + } + else { + stat = osOK; + vTaskPrioritySet (hTask, (UBaseType_t)priority); + } + + /* Return execution status */ + return (stat); +} + +/* + Get current priority of a thread. +*/ +osPriority_t osThreadGetPriority (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + osPriority_t prio; + + if ((IRQ_Context() != 0U) || (hTask == NULL)) { + prio = osPriorityError; + } else { + prio = (osPriority_t)((int32_t)uxTaskPriorityGet (hTask)); + } + + /* Return current thread priority */ + return (prio); +} + +/* + Pass control to next thread that is in state READY. +*/ +osStatus_t osThreadYield (void) { + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } else { + stat = osOK; + taskYIELD(); + } + + /* Return execution status */ + return (stat); +} + +#if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) +/* + Suspend execution of a thread. +*/ +osStatus_t osThreadSuspend (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hTask == NULL) { + stat = osErrorParameter; + } + else { + stat = osOK; + vTaskSuspend (hTask); + } + + /* Return execution status */ + return (stat); +} + +/* + Resume execution of a thread. +*/ +osStatus_t osThreadResume (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hTask == NULL) { + stat = osErrorParameter; + } + else { + stat = osOK; + vTaskResume (hTask); + } + + /* Return execution status */ + return (stat); +} +#endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */ + +/* + Terminate execution of current running thread. +*/ +__NO_RETURN void osThreadExit (void) { +#ifndef USE_FreeRTOS_HEAP_1 + vTaskDelete (NULL); +#endif + for (;;); +} + +/* + Terminate execution of a thread. +*/ +osStatus_t osThreadTerminate (osThreadId_t thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + osStatus_t stat; +#ifndef USE_FreeRTOS_HEAP_1 + eTaskState tstate; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hTask == NULL) { + stat = osErrorParameter; + } + else { + tstate = eTaskGetState (hTask); + + if (tstate != eDeleted) { + stat = osOK; + vTaskDelete (hTask); + } else { + stat = osErrorResource; + } + } +#else + stat = osError; +#endif + + /* Return execution status */ + return (stat); +} + +/* + Get number of active threads. +*/ +uint32_t osThreadGetCount (void) { + uint32_t count; + + if (IRQ_Context() != 0U) { + count = 0U; + } else { + count = uxTaskGetNumberOfTasks(); + } + + /* Return number of active threads */ + return (count); +} + +#if (configUSE_OS2_THREAD_ENUMERATE == 1) +/* + Enumerate active threads. +*/ +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) { + uint32_t i, count; + TaskStatus_t *task; + + if ((IRQ_Context() != 0U) || (thread_array == NULL) || (array_items == 0U)) { + count = 0U; + } else { + vTaskSuspendAll(); + + /* Allocate memory on heap to temporarily store TaskStatus_t information */ + count = uxTaskGetNumberOfTasks(); + task = pvPortMalloc (count * sizeof(TaskStatus_t)); + + if (task != NULL) { + /* Retrieve task status information */ + count = uxTaskGetSystemState (task, count, NULL); + + /* Copy handles from task status array into provided thread array */ + for (i = 0U; (i < count) && (i < array_items); i++) { + thread_array[i] = (osThreadId_t)task[i].xHandle; + } + count = i; + } + (void)xTaskResumeAll(); + + vPortFree (task); + } + + /* Return number of enumerated threads */ + return (count); +} +#endif /* (configUSE_OS2_THREAD_ENUMERATE == 1) */ + + +/* ==== Thread Flags Functions ==== */ + +#if (configUSE_OS2_THREAD_FLAGS == 1) +/* + Set the specified Thread Flags of a thread. +*/ +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + uint32_t rflags; + BaseType_t yield; + + if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) { + rflags = (uint32_t)osErrorParameter; + } + else { + rflags = (uint32_t)osError; + + if (IRQ_Context() != 0U) { + yield = pdFALSE; + + (void)xTaskNotifyFromISR (hTask, flags, eSetBits, &yield); + (void)xTaskNotifyAndQueryFromISR (hTask, 0, eNoAction, &rflags, NULL); + + portYIELD_FROM_ISR (yield); + } + else { + (void)xTaskNotify (hTask, flags, eSetBits); + (void)xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags); + } + } + /* Return flags after setting */ + return (rflags); +} + +/* + Clear the specified Thread Flags of current running thread. +*/ +uint32_t osThreadFlagsClear (uint32_t flags) { + TaskHandle_t hTask; + uint32_t rflags, cflags; + + if (IRQ_Context() != 0U) { + rflags = (uint32_t)osErrorISR; + } + else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { + rflags = (uint32_t)osErrorParameter; + } + else { + hTask = xTaskGetCurrentTaskHandle(); + + if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &cflags) == pdPASS) { + rflags = cflags; + cflags &= ~flags; + + if (xTaskNotify (hTask, cflags, eSetValueWithOverwrite) != pdPASS) { + rflags = (uint32_t)osError; + } + } + else { + rflags = (uint32_t)osError; + } + } + + /* Return flags before clearing */ + return (rflags); +} + +/* + Get the current Thread Flags of current running thread. +*/ +uint32_t osThreadFlagsGet (void) { + TaskHandle_t hTask; + uint32_t rflags; + + if (IRQ_Context() != 0U) { + rflags = (uint32_t)osErrorISR; + } + else { + hTask = xTaskGetCurrentTaskHandle(); + + if (xTaskNotifyAndQuery (hTask, 0, eNoAction, &rflags) != pdPASS) { + rflags = (uint32_t)osError; + } + } + + /* Return current flags */ + return (rflags); +} + +/* + Wait for one or more Thread Flags of the current running thread to become signaled. +*/ +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout) { + uint32_t rflags, nval; + uint32_t clear; + TickType_t t0, td, tout; + BaseType_t rval; + + if (IRQ_Context() != 0U) { + rflags = (uint32_t)osErrorISR; + } + else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { + rflags = (uint32_t)osErrorParameter; + } + else { + if ((options & osFlagsNoClear) == osFlagsNoClear) { + clear = 0U; + } else { + clear = flags; + } + + rflags = 0U; + tout = timeout; + + t0 = xTaskGetTickCount(); + do { + rval = xTaskNotifyWait (0, clear, &nval, tout); + + if (rval == pdPASS) { + rflags &= flags; + rflags |= nval; + + if ((options & osFlagsWaitAll) == osFlagsWaitAll) { + if ((flags & rflags) == flags) { + break; + } else { + if (timeout == 0U) { + rflags = (uint32_t)osErrorResource; + break; + } + } + } + else { + if ((flags & rflags) != 0) { + break; + } else { + if (timeout == 0U) { + rflags = (uint32_t)osErrorResource; + break; + } + } + } + + /* Update timeout */ + td = xTaskGetTickCount() - t0; + + if (td > timeout) { + tout = 0; + } else { + tout = timeout - td; + } + } + else { + if (timeout == 0) { + rflags = (uint32_t)osErrorResource; + } else { + rflags = (uint32_t)osErrorTimeout; + } + } + } + while (rval != pdFAIL); + } + + /* Return flags before clearing */ + return (rflags); +} +#endif /* (configUSE_OS2_THREAD_FLAGS == 1) */ + + +/* ==== Generic Wait Functions ==== */ + +/* + Wait for Timeout (Time Delay). +*/ +osStatus_t osDelay (uint32_t ticks) { + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else { + stat = osOK; + + if (ticks != 0U) { + vTaskDelay(ticks); + } + } + + /* Return execution status */ + return (stat); +} + +/* + Wait until specified time. +*/ +osStatus_t osDelayUntil (uint32_t ticks) { + TickType_t tcnt, delay; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else { + stat = osOK; + tcnt = xTaskGetTickCount(); + + /* Determine remaining number of ticks to delay */ + delay = (TickType_t)ticks - tcnt; + + /* Check if target tick has not expired */ + if((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) { + if (xTaskDelayUntil (&tcnt, delay) == pdFALSE) { + /* Did not delay */ + stat = osError; + } + } + else + { + /* No delay or already expired */ + stat = osErrorParameter; + } + } + + /* Return execution status */ + return (stat); +} + + +/* ==== Timer Management Functions ==== */ + +#if (configUSE_OS2_TIMER == 1) + +static void TimerCallback (TimerHandle_t hTimer) { + TimerCallback_t *callb; + + /* Retrieve pointer to callback function and argument */ + callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer); + + /* Remove dynamic allocation flag */ + callb = (TimerCallback_t *)((uint32_t)callb & ~1U); + + if (callb != NULL) { + callb->func (callb->arg); + } +} + +/* + Create and Initialize a timer. +*/ +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) { + const char *name; + TimerHandle_t hTimer; + TimerCallback_t *callb; + UBaseType_t reload; + int32_t mem; + uint32_t callb_dyn; + + hTimer = NULL; + + if ((IRQ_Context() == 0U) && (func != NULL)) { + callb = NULL; + callb_dyn = 0U; + + #if (configSUPPORT_STATIC_ALLOCATION == 1) + /* Static memory allocation is available: check if memory for control block */ + /* is provided and if it also contains space for callback and its argument */ + if ((attr != NULL) && (attr->cb_mem != NULL)) { + if (attr->cb_size >= (sizeof(StaticTimer_t) + sizeof(TimerCallback_t))) { + callb = (TimerCallback_t *)((uint32_t)attr->cb_mem + sizeof(StaticTimer_t)); + } + } + #endif + + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + /* Dynamic memory allocation is available: if memory for callback and */ + /* its argument is not provided, allocate it from dynamic memory pool */ + if (callb == NULL) { + callb = (TimerCallback_t *)pvPortMalloc (sizeof(TimerCallback_t)); + + if (callb != NULL) { + /* Callback memory was allocated from dynamic pool, set flag */ + callb_dyn = 1U; + } + } + #endif + + if (callb != NULL) { + callb->func = func; + callb->arg = argument; + + if (type == osTimerOnce) { + reload = pdFALSE; + } else { + reload = pdTRUE; + } + + mem = -1; + name = NULL; + + if (attr != NULL) { + if (attr->name != NULL) { + name = attr->name; + } + + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticTimer_t))) { + /* The memory for control block is provided, use static object */ + mem = 1; + } + else { + if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { + /* Control block will be allocated from the dynamic pool */ + mem = 0; + } + } + } + else { + mem = 0; + } + /* Store callback memory dynamic allocation flag */ + callb = (TimerCallback_t *)((uint32_t)callb | callb_dyn); + /* + TimerCallback function is always provided as a callback and is used to call application + specified function with its argument both stored in structure callb. + */ + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + hTimer = xTimerCreateStatic (name, 1, reload, callb, TimerCallback, (StaticTimer_t *)attr->cb_mem); + #endif + } + else { + if (mem == 0) { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + hTimer = xTimerCreate (name, 1, reload, callb, TimerCallback); + #endif + } + } + + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + if ((hTimer == NULL) && (callb != NULL) && (callb_dyn == 1U)) { + /* Failed to create a timer, release allocated resources */ + callb = (TimerCallback_t *)((uint32_t)callb & ~1U); + + vPortFree (callb); + } + #endif + } + } + + /* Return timer ID */ + return ((osTimerId_t)hTimer); +} + +/* + Get name of a timer. +*/ +const char *osTimerGetName (osTimerId_t timer_id) { + TimerHandle_t hTimer = (TimerHandle_t)timer_id; + const char *p; + + if ((IRQ_Context() != 0U) || (hTimer == NULL)) { + p = NULL; + } else { + p = pcTimerGetName (hTimer); + } + + /* Return name as null-terminated string */ + return (p); +} + +/* + Start or restart a timer. +*/ +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) { + TimerHandle_t hTimer = (TimerHandle_t)timer_id; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if ((hTimer == NULL) || (ticks == 0U)) { + stat = osErrorParameter; + } + else { + if (xTimerChangePeriod (hTimer, ticks, 0) == pdPASS) { + stat = osOK; + } else { + stat = osErrorResource; + } + } + + /* Return execution status */ + return (stat); +} + +/* + Stop a timer. +*/ +osStatus_t osTimerStop (osTimerId_t timer_id) { + TimerHandle_t hTimer = (TimerHandle_t)timer_id; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hTimer == NULL) { + stat = osErrorParameter; + } + else { + if (xTimerIsTimerActive (hTimer) == pdFALSE) { + stat = osErrorResource; + } + else { + if (xTimerStop (hTimer, 0) == pdPASS) { + stat = osOK; + } else { + stat = osError; + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Check if a timer is running. +*/ +uint32_t osTimerIsRunning (osTimerId_t timer_id) { + TimerHandle_t hTimer = (TimerHandle_t)timer_id; + uint32_t running; + + if ((IRQ_Context() != 0U) || (hTimer == NULL)) { + running = 0U; + } else { + running = (uint32_t)xTimerIsTimerActive (hTimer); + } + + /* Return 0: not running, 1: running */ + return (running); +} + +/* + Delete a timer. +*/ +osStatus_t osTimerDelete (osTimerId_t timer_id) { + TimerHandle_t hTimer = (TimerHandle_t)timer_id; + osStatus_t stat; +#ifndef USE_FreeRTOS_HEAP_1 +#if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + TimerCallback_t *callb; +#endif + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hTimer == NULL) { + stat = osErrorParameter; + } + else { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + callb = (TimerCallback_t *)pvTimerGetTimerID (hTimer); + #endif + + if (xTimerDelete (hTimer, 0) == pdPASS) { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + if ((uint32_t)callb & 1U) { + /* Callback memory was allocated from dynamic pool, clear flag */ + callb = (TimerCallback_t *)((uint32_t)callb & ~1U); + + /* Return allocated memory to dynamic pool */ + vPortFree (callb); + } + #endif + stat = osOK; + } else { + stat = osErrorResource; + } + } +#else + stat = osError; +#endif + + /* Return execution status */ + return (stat); +} +#endif /* (configUSE_OS2_TIMER == 1) */ + + +/* ==== Event Flags Management Functions ==== */ + +/* + Create and Initialize an Event Flags object. + + Limitations: + - Event flags are limited to 24 bits. +*/ +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr) { + EventGroupHandle_t hEventGroup; + int32_t mem; + + hEventGroup = NULL; + + if (IRQ_Context() == 0U) { + mem = -1; + + if (attr != NULL) { + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticEventGroup_t))) { + /* The memory for control block is provided, use static object */ + mem = 1; + } + else { + if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { + /* Control block will be allocated from the dynamic pool */ + mem = 0; + } + } + } + else { + mem = 0; + } + + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + hEventGroup = xEventGroupCreateStatic (attr->cb_mem); + #endif + } + else { + if (mem == 0) { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + hEventGroup = xEventGroupCreate(); + #endif + } + } + } + + /* Return event flags ID */ + return ((osEventFlagsId_t)hEventGroup); +} + +/* + Set the specified Event Flags. + + Limitations: + - Event flags are limited to 24 bits. +*/ +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags) { + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; + uint32_t rflags; + BaseType_t yield; + + if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) { + rflags = (uint32_t)osErrorParameter; + } + else if (IRQ_Context() != 0U) { + #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0) + (void)yield; + /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */ + rflags = (uint32_t)osErrorResource; + #else + yield = pdFALSE; + + if (xEventGroupSetBitsFromISR (hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) { + rflags = (uint32_t)osErrorResource; + } else { + /* Retrieve bits that are already set and add flags to be set in current call */ + rflags = xEventGroupGetBitsFromISR (hEventGroup); + rflags |= flags; + portYIELD_FROM_ISR (yield); + } + #endif + } + else { + rflags = xEventGroupSetBits (hEventGroup, (EventBits_t)flags); + } + + /* Return event flags after setting */ + return (rflags); +} + +/* + Clear the specified Event Flags. + + Limitations: + - Event flags are limited to 24 bits. +*/ +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags) { + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; + uint32_t rflags; + + if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) { + rflags = (uint32_t)osErrorParameter; + } + else if (IRQ_Context() != 0U) { + #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 0) + /* Enable timers and xTimerPendFunctionCall function to support osEventFlagsSet from ISR */ + rflags = (uint32_t)osErrorResource; + #else + rflags = xEventGroupGetBitsFromISR (hEventGroup); + + if (xEventGroupClearBitsFromISR (hEventGroup, (EventBits_t)flags) == pdFAIL) { + rflags = (uint32_t)osErrorResource; + } + else { + /* xEventGroupClearBitsFromISR only registers clear operation in the timer command queue. */ + /* Yield is required here otherwise clear operation might not execute in the right order. */ + /* See https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/93 for more info. */ + portYIELD_FROM_ISR (pdTRUE); + } + #endif + } + else { + rflags = xEventGroupClearBits (hEventGroup, (EventBits_t)flags); + } + + /* Return event flags before clearing */ + return (rflags); +} + +/* + Get the current Event Flags. + + Limitations: + - Event flags are limited to 24 bits. +*/ +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id) { + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; + uint32_t rflags; + + if (ef_id == NULL) { + rflags = 0U; + } + else if (IRQ_Context() != 0U) { + rflags = xEventGroupGetBitsFromISR (hEventGroup); + } + else { + rflags = xEventGroupGetBits (hEventGroup); + } + + /* Return current event flags */ + return (rflags); +} + +/* + Wait for one or more Event Flags to become signaled. + + Limitations: + - Event flags are limited to 24 bits. + - osEventFlagsWait cannot be called from an ISR. +*/ +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout) { + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; + BaseType_t wait_all; + BaseType_t exit_clr; + uint32_t rflags; + + if ((hEventGroup == NULL) || ((flags & EVENT_FLAGS_INVALID_BITS) != 0U)) { + rflags = (uint32_t)osErrorParameter; + } + else if (IRQ_Context() != 0U) { + if (timeout == 0U) { + /* Try semantic is not supported */ + rflags = (uint32_t)osErrorISR; + } else { + /* Calling osEventFlagsWait from ISR with non-zero timeout is invalid */ + rflags = (uint32_t)osFlagsErrorParameter; + } + } + else { + if (options & osFlagsWaitAll) { + wait_all = pdTRUE; + } else { + wait_all = pdFAIL; + } + + if (options & osFlagsNoClear) { + exit_clr = pdFAIL; + } else { + exit_clr = pdTRUE; + } + + rflags = xEventGroupWaitBits (hEventGroup, (EventBits_t)flags, exit_clr, wait_all, (TickType_t)timeout); + + if (options & osFlagsWaitAll) { + if ((flags & rflags) != flags) { + if (timeout > 0U) { + rflags = (uint32_t)osErrorTimeout; + } else { + rflags = (uint32_t)osErrorResource; + } + } + } + else { + if ((flags & rflags) == 0U) { + if (timeout > 0U) { + rflags = (uint32_t)osErrorTimeout; + } else { + rflags = (uint32_t)osErrorResource; + } + } + } + } + + /* Return event flags before clearing */ + return (rflags); +} + +/* + Delete an Event Flags object. +*/ +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id) { + EventGroupHandle_t hEventGroup = (EventGroupHandle_t)ef_id; + osStatus_t stat; + +#ifndef USE_FreeRTOS_HEAP_1 + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hEventGroup == NULL) { + stat = osErrorParameter; + } + else { + stat = osOK; + vEventGroupDelete (hEventGroup); + } +#else + stat = osError; +#endif + + /* Return execution status */ + return (stat); +} + + +/* ==== Mutex Management Functions ==== */ + +#if (configUSE_OS2_MUTEX == 1) +/* + Create and Initialize a Mutex object. + + Limitations: + - Priority inherit protocol is used by default, osMutexPrioInherit attribute is ignored. + - Robust mutex is not supported, NULL is returned if used. +*/ +osMutexId_t osMutexNew (const osMutexAttr_t *attr) { + SemaphoreHandle_t hMutex; + uint32_t type; + uint32_t rmtx; + int32_t mem; + + hMutex = NULL; + + if (IRQ_Context() == 0U) { + if (attr != NULL) { + type = attr->attr_bits; + } else { + type = 0U; + } + + if ((type & osMutexRecursive) == osMutexRecursive) { + rmtx = 1U; + } else { + rmtx = 0U; + } + + if ((type & osMutexRobust) != osMutexRobust) { + mem = -1; + + if (attr != NULL) { + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) { + /* The memory for control block is provided, use static object */ + mem = 1; + } + else { + if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { + /* Control block will be allocated from the dynamic pool */ + mem = 0; + } + } + } + else { + mem = 0; + } + + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + if (rmtx != 0U) { + #if (configUSE_RECURSIVE_MUTEXES == 1) + hMutex = xSemaphoreCreateRecursiveMutexStatic (attr->cb_mem); + #endif + } + else { + hMutex = xSemaphoreCreateMutexStatic (attr->cb_mem); + } + #endif + } + else { + if (mem == 0) { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + if (rmtx != 0U) { + #if (configUSE_RECURSIVE_MUTEXES == 1) + hMutex = xSemaphoreCreateRecursiveMutex (); + #endif + } else { + hMutex = xSemaphoreCreateMutex (); + } + #endif + } + } + + #if (configQUEUE_REGISTRY_SIZE > 0) + if (hMutex != NULL) { + if ((attr != NULL) && (attr->name != NULL)) { + /* Only non-NULL name objects are added to the Queue Registry */ + vQueueAddToRegistry (hMutex, attr->name); + } + } + #endif + + if ((hMutex != NULL) && (rmtx != 0U)) { + /* Set LSB as 'recursive mutex flag' */ + hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U); + } + } + } + + /* Return mutex ID */ + return ((osMutexId_t)hMutex); +} + +/* + Acquire a Mutex or timeout if it is locked. +*/ +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { + SemaphoreHandle_t hMutex; + osStatus_t stat; + uint32_t rmtx; + + hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); + + /* Extract recursive mutex flag */ + rmtx = (uint32_t)mutex_id & 1U; + + stat = osOK; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hMutex == NULL) { + stat = osErrorParameter; + } + else { + if (rmtx != 0U) { + #if (configUSE_RECURSIVE_MUTEXES == 1) + if (xSemaphoreTakeRecursive (hMutex, timeout) != pdPASS) { + if (timeout != 0U) { + stat = osErrorTimeout; + } else { + stat = osErrorResource; + } + } + #endif + } + else { + if (xSemaphoreTake (hMutex, timeout) != pdPASS) { + if (timeout != 0U) { + stat = osErrorTimeout; + } else { + stat = osErrorResource; + } + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Release a Mutex that was acquired by osMutexAcquire. +*/ +osStatus_t osMutexRelease (osMutexId_t mutex_id) { + SemaphoreHandle_t hMutex; + osStatus_t stat; + uint32_t rmtx; + + hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); + + /* Extract recursive mutex flag */ + rmtx = (uint32_t)mutex_id & 1U; + + stat = osOK; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hMutex == NULL) { + stat = osErrorParameter; + } + else { + if (rmtx != 0U) { + #if (configUSE_RECURSIVE_MUTEXES == 1) + if (xSemaphoreGiveRecursive (hMutex) != pdPASS) { + stat = osErrorResource; + } + #endif + } + else { + if (xSemaphoreGive (hMutex) != pdPASS) { + stat = osErrorResource; + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Get Thread which owns a Mutex object. +*/ +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) { + SemaphoreHandle_t hMutex; + osThreadId_t owner; + + hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); + + if ((IRQ_Context() != 0U) || (hMutex == NULL)) { + owner = NULL; + } else { + owner = (osThreadId_t)xSemaphoreGetMutexHolder (hMutex); + } + + /* Return owner thread ID */ + return (owner); +} + +/* + Delete a Mutex object. +*/ +osStatus_t osMutexDelete (osMutexId_t mutex_id) { + osStatus_t stat; +#ifndef USE_FreeRTOS_HEAP_1 + SemaphoreHandle_t hMutex; + + hMutex = (SemaphoreHandle_t)((uint32_t)mutex_id & ~1U); + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hMutex == NULL) { + stat = osErrorParameter; + } + else { + #if (configQUEUE_REGISTRY_SIZE > 0) + vQueueUnregisterQueue (hMutex); + #endif + stat = osOK; + vSemaphoreDelete (hMutex); + } +#else + stat = osError; +#endif + + /* Return execution status */ + return (stat); +} +#endif /* (configUSE_OS2_MUTEX == 1) */ + + +/* ==== Semaphore Management Functions ==== */ + +/* + Create and Initialize a Semaphore object. +*/ +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) { + SemaphoreHandle_t hSemaphore; + int32_t mem; + + hSemaphore = NULL; + + if ((IRQ_Context() == 0U) && (max_count > 0U) && (initial_count <= max_count)) { + mem = -1; + + if (attr != NULL) { + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticSemaphore_t))) { + /* The memory for control block is provided, use static object */ + mem = 1; + } + else { + if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { + /* Control block will be allocated from the dynamic pool */ + mem = 0; + } + } + } + else { + mem = 0; + } + + if (mem != -1) { + if (max_count == 1U) { + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + hSemaphore = xSemaphoreCreateBinaryStatic ((StaticSemaphore_t *)attr->cb_mem); + #endif + } + else { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + hSemaphore = xSemaphoreCreateBinary(); + #endif + } + + if ((hSemaphore != NULL) && (initial_count != 0U)) { + if (xSemaphoreGive (hSemaphore) != pdPASS) { + vSemaphoreDelete (hSemaphore); + hSemaphore = NULL; + } + } + } + else { + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + hSemaphore = xSemaphoreCreateCountingStatic (max_count, initial_count, (StaticSemaphore_t *)attr->cb_mem); + #endif + } + else { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + hSemaphore = xSemaphoreCreateCounting (max_count, initial_count); + #endif + } + } + + #if (configQUEUE_REGISTRY_SIZE > 0) + if (hSemaphore != NULL) { + if ((attr != NULL) && (attr->name != NULL)) { + /* Only non-NULL name objects are added to the Queue Registry */ + vQueueAddToRegistry (hSemaphore, attr->name); + } + } + #endif + } + } + + /* Return semaphore ID */ + return ((osSemaphoreId_t)hSemaphore); +} + +/* + Acquire a Semaphore token or timeout if no tokens are available. +*/ +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout) { + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; + osStatus_t stat; + BaseType_t yield; + + stat = osOK; + + if (hSemaphore == NULL) { + stat = osErrorParameter; + } + else if (IRQ_Context() != 0U) { + if (timeout != 0U) { + stat = osErrorParameter; + } + else { + yield = pdFALSE; + + if (xSemaphoreTakeFromISR (hSemaphore, &yield) != pdPASS) { + stat = osErrorResource; + } else { + portYIELD_FROM_ISR (yield); + } + } + } + else { + if (xSemaphoreTake (hSemaphore, (TickType_t)timeout) != pdPASS) { + if (timeout != 0U) { + stat = osErrorTimeout; + } else { + stat = osErrorResource; + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Release a Semaphore token up to the initial maximum count. +*/ +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id) { + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; + osStatus_t stat; + BaseType_t yield; + + stat = osOK; + + if (hSemaphore == NULL) { + stat = osErrorParameter; + } + else if (IRQ_Context() != 0U) { + yield = pdFALSE; + + if (xSemaphoreGiveFromISR (hSemaphore, &yield) != pdTRUE) { + stat = osErrorResource; + } else { + portYIELD_FROM_ISR (yield); + } + } + else { + if (xSemaphoreGive (hSemaphore) != pdPASS) { + stat = osErrorResource; + } + } + + /* Return execution status */ + return (stat); +} + +/* + Get current Semaphore token count. +*/ +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id) { + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; + uint32_t count; + + if (hSemaphore == NULL) { + count = 0U; + } + else if (IRQ_Context() != 0U) { + count = (uint32_t)uxSemaphoreGetCountFromISR (hSemaphore); + } else { + count = (uint32_t)uxSemaphoreGetCount (hSemaphore); + } + + /* Return number of tokens */ + return (count); +} + +/* + Delete a Semaphore object. +*/ +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id) { + SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)semaphore_id; + osStatus_t stat; + +#ifndef USE_FreeRTOS_HEAP_1 + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hSemaphore == NULL) { + stat = osErrorParameter; + } + else { + #if (configQUEUE_REGISTRY_SIZE > 0) + vQueueUnregisterQueue (hSemaphore); + #endif + + stat = osOK; + vSemaphoreDelete (hSemaphore); + } +#else + stat = osError; +#endif + + /* Return execution status */ + return (stat); +} + + +/* ==== Message Queue Management Functions ==== */ + +/* + Create and Initialize a Message Queue object. + + Limitations: + - The memory for control block and and message data must be provided in the + osThreadAttr_t structure in order to allocate object statically. +*/ +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { + QueueHandle_t hQueue; + int32_t mem; + + hQueue = NULL; + + if ((IRQ_Context() == 0U) && (msg_count > 0U) && (msg_size > 0U)) { + mem = -1; + + if (attr != NULL) { + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(StaticQueue_t)) && + (attr->mq_mem != NULL) && (attr->mq_size >= (msg_count * msg_size))) { + /* The memory for control block and message data is provided, use static object */ + mem = 1; + } + else { + if ((attr->cb_mem == NULL) && (attr->cb_size == 0U) && + (attr->mq_mem == NULL) && (attr->mq_size == 0U)) { + /* Control block will be allocated from the dynamic pool */ + mem = 0; + } + } + } + else { + mem = 0; + } + + if (mem == 1) { + #if (configSUPPORT_STATIC_ALLOCATION == 1) + hQueue = xQueueCreateStatic (msg_count, msg_size, attr->mq_mem, attr->cb_mem); + #endif + } + else { + if (mem == 0) { + #if (configSUPPORT_DYNAMIC_ALLOCATION == 1) + hQueue = xQueueCreate (msg_count, msg_size); + #endif + } + } + + #if (configQUEUE_REGISTRY_SIZE > 0) + if (hQueue != NULL) { + if ((attr != NULL) && (attr->name != NULL)) { + /* Only non-NULL name objects are added to the Queue Registry */ + vQueueAddToRegistry (hQueue, attr->name); + } + } + #endif + + } + + /* Return message queue ID */ + return ((osMessageQueueId_t)hQueue); +} + +/* + Put a Message into a Queue or timeout if Queue is full. + + Limitations: + - Message priority is ignored +*/ +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { + QueueHandle_t hQueue = (QueueHandle_t)mq_id; + osStatus_t stat; + BaseType_t yield; + + (void)msg_prio; /* Message priority is ignored */ + + stat = osOK; + + if (IRQ_Context() != 0U) { + if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { + stat = osErrorParameter; + } + else { + yield = pdFALSE; + + if (xQueueSendToBackFromISR (hQueue, msg_ptr, &yield) != pdTRUE) { + stat = osErrorResource; + } else { + portYIELD_FROM_ISR (yield); + } + } + } + else { + if ((hQueue == NULL) || (msg_ptr == NULL)) { + stat = osErrorParameter; + } + else { + if (xQueueSendToBack (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { + if (timeout != 0U) { + stat = osErrorTimeout; + } else { + stat = osErrorResource; + } + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Get a Message from a Queue or timeout if Queue is empty. + + Limitations: + - Message priority is ignored +*/ +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { + QueueHandle_t hQueue = (QueueHandle_t)mq_id; + osStatus_t stat; + BaseType_t yield; + + (void)msg_prio; /* Message priority is ignored */ + + stat = osOK; + + if (IRQ_Context() != 0U) { + if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { + stat = osErrorParameter; + } + else { + yield = pdFALSE; + + if (xQueueReceiveFromISR (hQueue, msg_ptr, &yield) != pdPASS) { + stat = osErrorResource; + } else { + portYIELD_FROM_ISR (yield); + } + } + } + else { + if ((hQueue == NULL) || (msg_ptr == NULL)) { + stat = osErrorParameter; + } + else { + if (xQueueReceive (hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { + if (timeout != 0U) { + stat = osErrorTimeout; + } else { + stat = osErrorResource; + } + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Get maximum number of messages in a Message Queue. +*/ +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) { + StaticQueue_t *mq = (StaticQueue_t *)mq_id; + uint32_t capacity; + + if (mq == NULL) { + capacity = 0U; + } else { + /* capacity = pxQueue->uxLength */ + capacity = mq->uxDummy4[1]; + } + + /* Return maximum number of messages */ + return (capacity); +} + +/* + Get maximum message size in a Message Queue. +*/ +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { + StaticQueue_t *mq = (StaticQueue_t *)mq_id; + uint32_t size; + + if (mq == NULL) { + size = 0U; + } else { + /* size = pxQueue->uxItemSize */ + size = mq->uxDummy4[2]; + } + + /* Return maximum message size */ + return (size); +} + +/* + Get number of queued messages in a Message Queue. +*/ +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) { + QueueHandle_t hQueue = (QueueHandle_t)mq_id; + UBaseType_t count; + + if (hQueue == NULL) { + count = 0U; + } + else if (IRQ_Context() != 0U) { + count = uxQueueMessagesWaitingFromISR (hQueue); + } + else { + count = uxQueueMessagesWaiting (hQueue); + } + + /* Return number of queued messages */ + return ((uint32_t)count); +} + +/* + Get number of available slots for messages in a Message Queue. +*/ +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) { + StaticQueue_t *mq = (StaticQueue_t *)mq_id; + uint32_t space; + uint32_t isrm; + + if (mq == NULL) { + space = 0U; + } + else if (IRQ_Context() != 0U) { + isrm = taskENTER_CRITICAL_FROM_ISR(); + + /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ + space = mq->uxDummy4[1] - mq->uxDummy4[0]; + + taskEXIT_CRITICAL_FROM_ISR(isrm); + } + else { + space = (uint32_t)uxQueueSpacesAvailable ((QueueHandle_t)mq); + } + + /* Return number of available slots */ + return (space); +} + +/* + Reset a Message Queue to initial empty state. +*/ +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) { + QueueHandle_t hQueue = (QueueHandle_t)mq_id; + osStatus_t stat; + + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hQueue == NULL) { + stat = osErrorParameter; + } + else { + stat = osOK; + (void)xQueueReset (hQueue); + } + + /* Return execution status */ + return (stat); +} + +/* + Delete a Message Queue object. +*/ +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) { + QueueHandle_t hQueue = (QueueHandle_t)mq_id; + osStatus_t stat; + +#ifndef USE_FreeRTOS_HEAP_1 + if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else if (hQueue == NULL) { + stat = osErrorParameter; + } + else { + #if (configQUEUE_REGISTRY_SIZE > 0) + vQueueUnregisterQueue (hQueue); + #endif + + stat = osOK; + vQueueDelete (hQueue); + } +#else + stat = osError; +#endif + + /* Return execution status */ + return (stat); +} + + +/* ==== Memory Pool Management Functions ==== */ + +#ifdef FREERTOS_MPOOL_H_ +/* Static memory pool functions */ +static void FreeBlock (MemPool_t *mp, void *block); +static void *AllocBlock (MemPool_t *mp); +static void *CreateBlock (MemPool_t *mp); + +/* + Create and Initialize a Memory Pool object. +*/ +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) { + MemPool_t *mp; + const char *name; + int32_t mem_cb, mem_mp; + uint32_t sz; + + if (IRQ_Context() != 0U) { + mp = NULL; + } + else if ((block_count == 0U) || (block_size == 0U)) { + mp = NULL; + } + else { + mp = NULL; + sz = MEMPOOL_ARR_SIZE (block_count, block_size); + + name = NULL; + mem_cb = -1; + mem_mp = -1; + + if (attr != NULL) { + if (attr->name != NULL) { + name = attr->name; + } + + if ((attr->cb_mem != NULL) && (attr->cb_size >= sizeof(MemPool_t))) { + /* Static control block is provided */ + mem_cb = 1; + } + else if ((attr->cb_mem == NULL) && (attr->cb_size == 0U)) { + /* Allocate control block memory on heap */ + mem_cb = 0; + } + + if ((attr->mp_mem == NULL) && (attr->mp_size == 0U)) { + /* Allocate memory array on heap */ + mem_mp = 0; + } + else { + if (attr->mp_mem != NULL) { + /* Check if array is 4-byte aligned */ + if (((uint32_t)attr->mp_mem & 3U) == 0U) { + /* Check if array big enough */ + if (attr->mp_size >= sz) { + /* Static memory pool array is provided */ + mem_mp = 1; + } + } + } + } + } + else { + /* Attributes not provided, allocate memory on heap */ + mem_cb = 0; + mem_mp = 0; + } + + if (mem_cb == 0) { + mp = pvPortMalloc (sizeof(MemPool_t)); + } else { + mp = attr->cb_mem; + } + + if (mp != NULL) { + /* Create a semaphore (max count == initial count == block_count) */ + #if (configSUPPORT_STATIC_ALLOCATION == 1) + mp->sem = xSemaphoreCreateCountingStatic (block_count, block_count, &mp->mem_sem); + #elif (configSUPPORT_DYNAMIC_ALLOCATION == 1) + mp->sem = xSemaphoreCreateCounting (block_count, block_count); + #else + mp->sem = NULL; + #endif + + if (mp->sem != NULL) { + /* Setup memory array */ + if (mem_mp == 0) { + mp->mem_arr = pvPortMalloc (sz); + } else { + mp->mem_arr = attr->mp_mem; + } + } + } + + if ((mp != NULL) && (mp->mem_arr != NULL)) { + /* Memory pool can be created */ + mp->head = NULL; + mp->mem_sz = sz; + mp->name = name; + mp->bl_sz = block_size; + mp->bl_cnt = block_count; + mp->n = 0U; + + /* Set heap allocated memory flags */ + mp->status = MPOOL_STATUS; + + if (mem_cb == 0) { + /* Control block on heap */ + mp->status |= 1U; + } + if (mem_mp == 0) { + /* Memory array on heap */ + mp->status |= 2U; + } + } + else { + /* Memory pool cannot be created, release allocated resources */ + if ((mem_cb == 0) && (mp != NULL)) { + /* Free control block memory */ + vPortFree (mp); + } + mp = NULL; + } + } + + /* Return memory pool ID */ + return (mp); +} + +/* + Get name of a Memory Pool object. +*/ +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) { + MemPool_t *mp = (osMemoryPoolId_t)mp_id; + const char *p; + + if (IRQ_Context() != 0U) { + p = NULL; + } + else if (mp_id == NULL) { + p = NULL; + } + else { + p = mp->name; + } + + /* Return name as null-terminated string */ + return (p); +} + +/* + Allocate a memory block from a Memory Pool. +*/ +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) { + MemPool_t *mp; + void *block; + uint32_t isrm; + + if (mp_id == NULL) { + /* Invalid input parameters */ + block = NULL; + } + else { + block = NULL; + + mp = (MemPool_t *)mp_id; + + if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) { + if (IRQ_Context() != 0U) { + if (timeout == 0U) { + if (xSemaphoreTakeFromISR (mp->sem, NULL) == pdTRUE) { + if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) { + isrm = taskENTER_CRITICAL_FROM_ISR(); + + /* Get a block from the free-list */ + block = AllocBlock(mp); + + if (block == NULL) { + /* List of free blocks is empty, 'create' new block */ + block = CreateBlock(mp); + } + + taskEXIT_CRITICAL_FROM_ISR(isrm); + } + } + } + } + else { + if (xSemaphoreTake (mp->sem, (TickType_t)timeout) == pdTRUE) { + if ((mp->status & MPOOL_STATUS) == MPOOL_STATUS) { + taskENTER_CRITICAL(); + + /* Get a block from the free-list */ + block = AllocBlock(mp); + + if (block == NULL) { + /* List of free blocks is empty, 'create' new block */ + block = CreateBlock(mp); + } + + taskEXIT_CRITICAL(); + } + } + } + } + } + + /* Return memory block address */ + return (block); +} + +/* + Return an allocated memory block back to a Memory Pool. +*/ +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) { + MemPool_t *mp; + osStatus_t stat; + uint32_t isrm; + BaseType_t yield; + + if ((mp_id == NULL) || (block == NULL)) { + /* Invalid input parameters */ + stat = osErrorParameter; + } + else { + mp = (MemPool_t *)mp_id; + + if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) { + /* Invalid object status */ + stat = osErrorResource; + } + else if ((block < (void *)&mp->mem_arr[0]) || (block > (void*)&mp->mem_arr[mp->mem_sz-1])) { + /* Block pointer outside of memory array area */ + stat = osErrorParameter; + } + else { + stat = osOK; + + if (IRQ_Context() != 0U) { + if (uxSemaphoreGetCountFromISR (mp->sem) == mp->bl_cnt) { + stat = osErrorResource; + } + else { + isrm = taskENTER_CRITICAL_FROM_ISR(); + + /* Add block to the list of free blocks */ + FreeBlock(mp, block); + + taskEXIT_CRITICAL_FROM_ISR(isrm); + + yield = pdFALSE; + xSemaphoreGiveFromISR (mp->sem, &yield); + portYIELD_FROM_ISR (yield); + } + } + else { + if (uxSemaphoreGetCount (mp->sem) == mp->bl_cnt) { + stat = osErrorResource; + } + else { + taskENTER_CRITICAL(); + + /* Add block to the list of free blocks */ + FreeBlock(mp, block); + + taskEXIT_CRITICAL(); + + xSemaphoreGive (mp->sem); + } + } + } + } + + /* Return execution status */ + return (stat); +} + +/* + Get maximum number of memory blocks in a Memory Pool. +*/ +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) { + MemPool_t *mp; + uint32_t n; + + if (mp_id == NULL) { + /* Invalid input parameters */ + n = 0U; + } + else { + mp = (MemPool_t *)mp_id; + + if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) { + /* Invalid object status */ + n = 0U; + } + else { + n = mp->bl_cnt; + } + } + + /* Return maximum number of memory blocks */ + return (n); +} + +/* + Get memory block size in a Memory Pool. +*/ +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) { + MemPool_t *mp; + uint32_t sz; + + if (mp_id == NULL) { + /* Invalid input parameters */ + sz = 0U; + } + else { + mp = (MemPool_t *)mp_id; + + if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) { + /* Invalid object status */ + sz = 0U; + } + else { + sz = mp->bl_sz; + } + } + + /* Return memory block size in bytes */ + return (sz); +} + +/* + Get number of memory blocks used in a Memory Pool. +*/ +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) { + MemPool_t *mp; + uint32_t n; + + if (mp_id == NULL) { + /* Invalid input parameters */ + n = 0U; + } + else { + mp = (MemPool_t *)mp_id; + + if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) { + /* Invalid object status */ + n = 0U; + } + else { + if (IRQ_Context() != 0U) { + n = uxSemaphoreGetCountFromISR (mp->sem); + } else { + n = uxSemaphoreGetCount (mp->sem); + } + + n = mp->bl_cnt - n; + } + } + + /* Return number of memory blocks used */ + return (n); +} + +/* + Get number of memory blocks available in a Memory Pool. +*/ +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) { + MemPool_t *mp; + uint32_t n; + + if (mp_id == NULL) { + /* Invalid input parameters */ + n = 0U; + } + else { + mp = (MemPool_t *)mp_id; + + if ((mp->status & MPOOL_STATUS) != MPOOL_STATUS) { + /* Invalid object status */ + n = 0U; + } + else { + if (IRQ_Context() != 0U) { + n = uxSemaphoreGetCountFromISR (mp->sem); + } else { + n = uxSemaphoreGetCount (mp->sem); + } + } + } + + /* Return number of memory blocks available */ + return (n); +} + +/* + Delete a Memory Pool object. +*/ +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) { + MemPool_t *mp; + osStatus_t stat; + + if (mp_id == NULL) { + /* Invalid input parameters */ + stat = osErrorParameter; + } + else if (IRQ_Context() != 0U) { + stat = osErrorISR; + } + else { + mp = (MemPool_t *)mp_id; + + taskENTER_CRITICAL(); + + /* Invalidate control block status */ + mp->status = mp->status & 3U; + + /* Wake-up tasks waiting for pool semaphore */ + while (xSemaphoreGive (mp->sem) == pdTRUE); + + mp->head = NULL; + mp->bl_sz = 0U; + mp->bl_cnt = 0U; + + if ((mp->status & 2U) != 0U) { + /* Memory pool array allocated on heap */ + vPortFree (mp->mem_arr); + } + if ((mp->status & 1U) != 0U) { + /* Memory pool control block allocated on heap */ + vPortFree (mp); + } + + taskEXIT_CRITICAL(); + + stat = osOK; + } + + /* Return execution status */ + return (stat); +} + +/* + Create new block given according to the current block index. +*/ +static void *CreateBlock (MemPool_t *mp) { + MemPoolBlock_t *p = NULL; + + if (mp->n < mp->bl_cnt) { + /* Unallocated blocks exist, set pointer to new block */ + p = (void *)(mp->mem_arr + (mp->bl_sz * mp->n)); + + /* Increment block index */ + mp->n += 1U; + } + + return (p); +} + +/* + Allocate a block by reading the list of free blocks. +*/ +static void *AllocBlock (MemPool_t *mp) { + MemPoolBlock_t *p = NULL; + + if (mp->head != NULL) { + /* List of free block exists, get head block */ + p = mp->head; + + /* Head block is now next on the list */ + mp->head = p->next; + } + + return (p); +} + +/* + Free block by putting it to the list of free blocks. +*/ +static void FreeBlock (MemPool_t *mp, void *block) { + MemPoolBlock_t *p = block; + + /* Store current head into block memory space */ + p->next = mp->head; + + /* Store current block as new head */ + mp->head = p; +} +#endif /* FREERTOS_MPOOL_H_ */ +/*---------------------------------------------------------------------------*/ + +/* Callback function prototypes */ +extern void vApplicationIdleHook (void); +extern void vApplicationMallocFailedHook (void); +extern void vApplicationDaemonTaskStartupHook (void); + +/** + Dummy implementation of the callback function vApplicationIdleHook(). +*/ +#if (configUSE_IDLE_HOOK == 1) +__WEAK void vApplicationIdleHook (void){} +#endif + +/** + Dummy implementation of the callback function vApplicationTickHook(). +*/ +#if (configUSE_TICK_HOOK == 1) + __WEAK void vApplicationTickHook (void){} +#endif + +/** + Dummy implementation of the callback function vApplicationMallocFailedHook(). +*/ +#if (configUSE_MALLOC_FAILED_HOOK == 1) +__WEAK void vApplicationMallocFailedHook (void) { + /* Assert when malloc failed hook is enabled but no application defined function exists */ + configASSERT(0); +} +#endif + +/** + Dummy implementation of the callback function vApplicationDaemonTaskStartupHook(). +*/ +#if (configUSE_DAEMON_TASK_STARTUP_HOOK == 1) +__WEAK void vApplicationDaemonTaskStartupHook (void){} +#endif + +/** + Dummy implementation of the callback function vApplicationStackOverflowHook(). +*/ +#if (configCHECK_FOR_STACK_OVERFLOW > 0) +__WEAK void vApplicationStackOverflowHook (TaskHandle_t xTask, char *pcTaskName) { + (void)xTask; + (void)pcTaskName; + + /* Assert when stack overflow is enabled but no application defined function exists */ + configASSERT(0); +} +#endif + +/*---------------------------------------------------------------------------*/ +#if (configSUPPORT_STATIC_ALLOCATION == 1) +/* + vApplicationGetIdleTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION + equals to 1 and is required for static memory allocation support. +*/ +__WEAK void vApplicationGetIdleTaskMemory (StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { + /* Idle task control block and stack */ + static StaticTask_t Idle_TCB; + static StackType_t Idle_Stack[configMINIMAL_STACK_SIZE]; + + *ppxIdleTaskTCBBuffer = &Idle_TCB; + *ppxIdleTaskStackBuffer = &Idle_Stack[0]; + *pulIdleTaskStackSize = (uint32_t)configMINIMAL_STACK_SIZE; +} + +/* + vApplicationGetTimerTaskMemory gets called when configSUPPORT_STATIC_ALLOCATION + equals to 1 and is required for static memory allocation support. +*/ +__WEAK void vApplicationGetTimerTaskMemory (StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) { + /* Timer task control block and stack */ + static StaticTask_t Timer_TCB; + static StackType_t Timer_Stack[configTIMER_TASK_STACK_DEPTH]; + + *ppxTimerTaskTCBBuffer = &Timer_TCB; + *ppxTimerTaskStackBuffer = &Timer_Stack[0]; + *pulTimerTaskStackSize = (uint32_t)configTIMER_TASK_STACK_DEPTH; +} +#endif diff --git a/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h new file mode 100644 index 0000000..cea5017 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_mpool.h @@ -0,0 +1,63 @@ +/* -------------------------------------------------------------------------- + * Copyright (c) 2013-2020 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * Name: freertos_mpool.h + * Purpose: CMSIS RTOS2 wrapper for FreeRTOS + * + *---------------------------------------------------------------------------*/ + +#ifndef FREERTOS_MPOOL_H_ +#define FREERTOS_MPOOL_H_ + +#include +#include "FreeRTOS.h" +#include "semphr.h" + +/* Memory Pool implementation definitions */ +#define MPOOL_STATUS 0x5EED0000U + +/* Memory Block header */ +typedef struct { + void *next; /* Pointer to next block */ +} MemPoolBlock_t; + +/* Memory Pool control block */ +typedef struct MemPoolDef_t { + MemPoolBlock_t *head; /* Pointer to head block */ + SemaphoreHandle_t sem; /* Pool semaphore handle */ + uint8_t *mem_arr; /* Pool memory array */ + uint32_t mem_sz; /* Pool memory array size */ + const char *name; /* Pointer to name string */ + uint32_t bl_sz; /* Size of a single block */ + uint32_t bl_cnt; /* Number of blocks */ + uint32_t n; /* Block allocation index */ + volatile uint32_t status; /* Object status flags */ +#if (configSUPPORT_STATIC_ALLOCATION == 1) + StaticSemaphore_t mem_sem; /* Semaphore object memory */ +#endif +} MemPool_t; + +/* No need to hide static object type, just align to coding style */ +#define StaticMemPool_t MemPool_t + +/* Define memory pool control block size */ +#define MEMPOOL_CB_SIZE (sizeof(StaticMemPool_t)) + +/* Define size of the byte array required to create count of blocks of given size */ +#define MEMPOOL_ARR_SIZE(bl_count, bl_size) (((((bl_size) + (4 - 1)) / 4) * 4)*(bl_count)) + +#endif /* FREERTOS_MPOOL_H_ */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h new file mode 100644 index 0000000..ddb4aa1 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/freertos_os2.h @@ -0,0 +1,310 @@ +/* -------------------------------------------------------------------------- + * Copyright (c) 2013-2021 Arm Limited. All rights reserved. + * + * SPDX-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 + * + * 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. + * + * Name: freertos_os2.h + * Purpose: CMSIS RTOS2 wrapper for FreeRTOS + * + *---------------------------------------------------------------------------*/ + +#ifndef FREERTOS_OS2_H_ +#define FREERTOS_OS2_H_ + +#include +#include + +#include "FreeRTOS.h" // ARM.FreeRTOS::RTOS:Core + +#include CMSIS_device_header + + /* + CMSIS-RTOS2 FreeRTOS image size optimization definitions. + + Note: Definitions configUSE_OS2 can be used to optimize FreeRTOS image size when + certain functionality is not required when using CMSIS-RTOS2 API. + In general optimization decisions are left to the tool chain but in cases + when coding style prevents it to optimize the code following optional + definitions can be used. +*/ + +/* + Option to exclude CMSIS-RTOS2 functions osThreadSuspend and osThreadResume from + the application image. +*/ +#ifndef configUSE_OS2_THREAD_SUSPEND_RESUME +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#endif + +/* + Option to exclude CMSIS-RTOS2 function osThreadEnumerate from the application image. +*/ +#ifndef configUSE_OS2_THREAD_ENUMERATE +#define configUSE_OS2_THREAD_ENUMERATE 1 +#endif + +/* + Option to disable CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear + operation from ISR. +*/ +#ifndef configUSE_OS2_EVENTFLAGS_FROM_ISR +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#endif + +/* + Option to exclude CMSIS-RTOS2 Thread Flags API functions from the application image. +*/ +#ifndef configUSE_OS2_THREAD_FLAGS +#define configUSE_OS2_THREAD_FLAGS configUSE_TASK_NOTIFICATIONS +#endif + +/* + Option to exclude CMSIS-RTOS2 Timer API functions from the application image. +*/ +#ifndef configUSE_OS2_TIMER +#define configUSE_OS2_TIMER configUSE_TIMERS +#endif + +/* + Option to exclude CMSIS-RTOS2 Mutex API functions from the application image. +*/ +#ifndef configUSE_OS2_MUTEX +#define configUSE_OS2_MUTEX configUSE_MUTEXES +#endif + + +/* + CMSIS-RTOS2 FreeRTOS configuration check (FreeRTOSConfig.h). + + Note: CMSIS-RTOS API requires functions included by using following definitions. + In case if certain API function is not used compiler will optimize it away. +*/ +#if (INCLUDE_xSemaphoreGetMutexHolder == 0) + /* + CMSIS-RTOS2 function osMutexGetOwner uses FreeRTOS function xSemaphoreGetMutexHolder. In case if + osMutexGetOwner is not used in the application image, compiler will optimize it away. + Set #define INCLUDE_xSemaphoreGetMutexHolder 1 to fix this error. + */ + #error "Definition INCLUDE_xSemaphoreGetMutexHolder must equal 1 to implement Mutex Management API." +#endif +#if (INCLUDE_vTaskDelay == 0) + /* + CMSIS-RTOS2 function osDelay uses FreeRTOS function vTaskDelay. In case if + osDelay is not used in the application image, compiler will optimize it away. + Set #define INCLUDE_vTaskDelay 1 to fix this error. + */ + #error "Definition INCLUDE_vTaskDelay must equal 1 to implement Generic Wait Functions API." +#endif +#if (INCLUDE_xTaskDelayUntil == 0) + /* + CMSIS-RTOS2 function osDelayUntil uses FreeRTOS function xTaskDelayUntil. In case if + osDelayUntil is not used in the application image, compiler will optimize it away. + Set #define INCLUDE_xTaskDelayUntil 1 to fix this error. + */ + #error "Definition INCLUDE_xTaskDelayUntil must equal 1 to implement Generic Wait Functions API." +#endif +#if (INCLUDE_vTaskDelete == 0) + /* + CMSIS-RTOS2 function osThreadTerminate and osThreadExit uses FreeRTOS function + vTaskDelete. In case if they are not used in the application image, compiler + will optimize them away. + Set #define INCLUDE_vTaskDelete 1 to fix this error. + */ + #error "Definition INCLUDE_vTaskDelete must equal 1 to implement Thread Management API." +#endif +#if (INCLUDE_xTaskGetCurrentTaskHandle == 0) + /* + CMSIS-RTOS2 API uses FreeRTOS function xTaskGetCurrentTaskHandle to implement + functions osThreadGetId, osThreadFlagsClear and osThreadFlagsGet. In case if these + functions are not used in the application image, compiler will optimize them away. + Set #define INCLUDE_xTaskGetCurrentTaskHandle 1 to fix this error. + */ + #error "Definition INCLUDE_xTaskGetCurrentTaskHandle must equal 1 to implement Thread Management API." +#endif +#if (INCLUDE_xTaskGetSchedulerState == 0) + /* + CMSIS-RTOS2 API uses FreeRTOS function xTaskGetSchedulerState to implement Kernel + tick handling and therefore it is vital that xTaskGetSchedulerState is included into + the application image. + Set #define INCLUDE_xTaskGetSchedulerState 1 to fix this error. + */ + #error "Definition INCLUDE_xTaskGetSchedulerState must equal 1 to implement Kernel Information and Control API." +#endif +#if (INCLUDE_uxTaskGetStackHighWaterMark == 0) + /* + CMSIS-RTOS2 function osThreadGetStackSpace uses FreeRTOS function uxTaskGetStackHighWaterMark. + In case if osThreadGetStackSpace is not used in the application image, compiler will + optimize it away. + Set #define INCLUDE_uxTaskGetStackHighWaterMark 1 to fix this error. + */ + #error "Definition INCLUDE_uxTaskGetStackHighWaterMark must equal 1 to implement Thread Management API." +#endif +#if (INCLUDE_uxTaskPriorityGet == 0) + /* + CMSIS-RTOS2 function osThreadGetPriority uses FreeRTOS function uxTaskPriorityGet. In case if + osThreadGetPriority is not used in the application image, compiler will optimize it away. + Set #define INCLUDE_uxTaskPriorityGet 1 to fix this error. + */ + #error "Definition INCLUDE_uxTaskPriorityGet must equal 1 to implement Thread Management API." +#endif +#if (INCLUDE_vTaskPrioritySet == 0) + /* + CMSIS-RTOS2 function osThreadSetPriority uses FreeRTOS function vTaskPrioritySet. In case if + osThreadSetPriority is not used in the application image, compiler will optimize it away. + Set #define INCLUDE_vTaskPrioritySet 1 to fix this error. + */ + #error "Definition INCLUDE_vTaskPrioritySet must equal 1 to implement Thread Management API." +#endif +#if (INCLUDE_eTaskGetState == 0) + /* + CMSIS-RTOS2 API uses FreeRTOS function vTaskDelayUntil to implement functions osThreadGetState + and osThreadTerminate. In case if these functions are not used in the application image, + compiler will optimize them away. + Set #define INCLUDE_eTaskGetState 1 to fix this error. + */ + #error "Definition INCLUDE_eTaskGetState must equal 1 to implement Thread Management API." +#endif +#if (INCLUDE_vTaskSuspend == 0) + /* + CMSIS-RTOS2 API uses FreeRTOS functions vTaskSuspend and vTaskResume to implement + functions osThreadSuspend and osThreadResume. In case if these functions are not + used in the application image, compiler will optimize them away. + Set #define INCLUDE_vTaskSuspend 1 to fix this error. + + Alternatively, if the application does not use osThreadSuspend and + osThreadResume they can be excluded from the image code by setting: + #define configUSE_OS2_THREAD_SUSPEND_RESUME 0 (in FreeRTOSConfig.h) + */ + #if (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) + #error "Definition INCLUDE_vTaskSuspend must equal 1 to implement Kernel Information and Control API." + #endif +#endif +#if (INCLUDE_xTimerPendFunctionCall == 0) + /* + CMSIS-RTOS2 function osEventFlagsSet and osEventFlagsClear, when called from + the ISR, call FreeRTOS functions xEventGroupSetBitsFromISR and + xEventGroupClearBitsFromISR which are only enabled if timers are operational and + xTimerPendFunctionCall in enabled. + Set #define INCLUDE_xTimerPendFunctionCall 1 and #define configUSE_TIMERS 1 + to fix this error. + + Alternatively, if the application does not use osEventFlagsSet and osEventFlagsClear + from the ISR their operation from ISR can be restricted by setting: + #define configUSE_OS2_EVENTFLAGS_FROM_ISR 0 (in FreeRTOSConfig.h) + */ + #if (configUSE_OS2_EVENTFLAGS_FROM_ISR == 1) + #error "Definition INCLUDE_xTimerPendFunctionCall must equal 1 to implement Event Flags API." + #endif +#endif + +#if (configUSE_TIMERS == 0) + /* + CMSIS-RTOS2 Timer Management API functions use FreeRTOS timer functions to implement + timer management. In case if these functions are not used in the application image, + compiler will optimize them away. + Set #define configUSE_TIMERS 1 to fix this error. + + Alternatively, if the application does not use timer functions they can be + excluded from the image code by setting: + #define configUSE_OS2_TIMER 0 (in FreeRTOSConfig.h) + */ + #if (configUSE_OS2_TIMER == 1) + #error "Definition configUSE_TIMERS must equal 1 to implement Timer Management API." + #endif +#endif + +#if (configUSE_MUTEXES == 0) + /* + CMSIS-RTOS2 Mutex Management API functions use FreeRTOS mutex functions to implement + mutex management. In case if these functions are not used in the application image, + compiler will optimize them away. + Set #define configUSE_MUTEXES 1 to fix this error. + + Alternatively, if the application does not use mutex functions they can be + excluded from the image code by setting: + #define configUSE_OS2_MUTEX 0 (in FreeRTOSConfig.h) + */ + #if (configUSE_OS2_MUTEX == 1) + #error "Definition configUSE_MUTEXES must equal 1 to implement Mutex Management API." + #endif +#endif + +#if (configUSE_COUNTING_SEMAPHORES == 0) + /* + CMSIS-RTOS2 Memory Pool functions use FreeRTOS function xSemaphoreCreateCounting + to implement memory pools. In case if these functions are not used in the application image, + compiler will optimize them away. + Set #define configUSE_COUNTING_SEMAPHORES 1 to fix this error. + */ + #error "Definition configUSE_COUNTING_SEMAPHORES must equal 1 to implement Memory Pool API." +#endif +#if (configUSE_TASK_NOTIFICATIONS == 0) + /* + CMSIS-RTOS2 Thread Flags API functions use FreeRTOS Task Notification functions to implement + thread flag management. In case if these functions are not used in the application image, + compiler will optimize them away. + Set #define configUSE_TASK_NOTIFICATIONS 1 to fix this error. + + Alternatively, if the application does not use thread flags functions they can be + excluded from the image code by setting: + #define configUSE_OS2_THREAD_FLAGS 0 (in FreeRTOSConfig.h) + */ + #if (configUSE_OS2_THREAD_FLAGS == 1) + #error "Definition configUSE_TASK_NOTIFICATIONS must equal 1 to implement Thread Flags API." + #endif +#endif + +#if (configUSE_TRACE_FACILITY == 0) + /* + CMSIS-RTOS2 function osThreadEnumerate requires FreeRTOS function uxTaskGetSystemState + which is only enabled if configUSE_TRACE_FACILITY == 1. + Set #define configUSE_TRACE_FACILITY 1 to fix this error. + + Alternatively, if the application does not use osThreadEnumerate it can be + excluded from the image code by setting: + #define configUSE_OS2_THREAD_ENUMERATE 0 (in FreeRTOSConfig.h) + */ + #if (configUSE_OS2_THREAD_ENUMERATE == 1) + #error "Definition configUSE_TRACE_FACILITY must equal 1 to implement osThreadEnumerate." + #endif +#endif + +#if (configUSE_16_BIT_TICKS == 1) + /* + CMSIS-RTOS2 wrapper for FreeRTOS relies on 32-bit tick timer which is also optimal on + a 32-bit CPU architectures. + Set #define configUSE_16_BIT_TICKS 0 to fix this error. + */ + #error "Definition configUSE_16_BIT_TICKS must be zero to implement CMSIS-RTOS2 API." +#endif + +#if (configMAX_PRIORITIES != 56) + /* + CMSIS-RTOS2 defines 56 different priorities (see osPriority_t) and portable CMSIS-RTOS2 + implementation should implement the same number of priorities. + Set #define configMAX_PRIORITIES 56 to fix this error. + */ + #error "Definition configMAX_PRIORITIES must equal 56 to implement Thread Management API." +#endif +#if (configUSE_PORT_OPTIMISED_TASK_SELECTION != 0) + /* + CMSIS-RTOS2 requires handling of 56 different priorities (see osPriority_t) while FreeRTOS port + optimised selection for Cortex core only handles 32 different priorities. + Set #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 to fix this error. + */ + #error "Definition configUSE_PORT_OPTIMISED_TASK_SELECTION must be zero to implement Thread Management API." +#endif + +#endif /* FREERTOS_OS2_H_ */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/LICENSE b/Middlewares/Third_Party/FreeRTOS/Source/LICENSE new file mode 100644 index 0000000..9cf1062 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/LICENSE @@ -0,0 +1,19 @@ +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Middlewares/Third_Party/FreeRTOS/Source/croutine.c b/Middlewares/Third_Party/FreeRTOS/Source/croutine.c new file mode 100644 index 0000000..559276c --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/croutine.c @@ -0,0 +1,363 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Remove the whole file is co-routines are not being used. */ +#if ( configUSE_CO_ROUTINES != 0 ) + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ + #ifdef portREMOVE_STATIC_QUALIFIER + #define static + #endif + + +/* Lists for ready and blocked co-routines. --------------------*/ + static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ + static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ + static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ + static List_t * pxDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used. */ + static List_t * pxOverflowDelayedCoRoutineList = NULL; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ + static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ + CRCB_t * pxCurrentCoRoutine = NULL; + static UBaseType_t uxTopCoRoutineReadyPriority = 0; + static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ + #define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ + #define prvAddCoRoutineToReadyQueue( pxCRCB ) \ + do { \ + if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \ + } while( 0 ) + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ + static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ + static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ + static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + + BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, + UBaseType_t uxPriority, + UBaseType_t uxIndex ) + { + BaseType_t xReturn; + CRCB_t * pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + * be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + * This is so we can get back to the containing CRCB from a generic item + * in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + * list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, + List_t * pxEventList ) + { + TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + * not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + * ourselves to the blocked list as the same list item is used for + * both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + * overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + * current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + * function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } + } +/*-----------------------------------------------------------*/ + + static void prvCheckPendingReadyList( void ) + { + /* Are there any co-routines waiting to get moved to the ready list? These + * are co-routines that have been readied by an ISR. The ISR cannot access + * the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t * pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } + } +/*-----------------------------------------------------------*/ + + static void prvCheckDelayedList( void ) + { + CRCB_t * pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + * any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + * section. If this is the case then the generic list item will + * have been moved to the pending ready list and the following + * line is still valid. Also the pvContainer parameter will have + * been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pxContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; + } +/*-----------------------------------------------------------*/ + + void vCoRoutineSchedule( void ) + { + /* Only run a co-routine after prvInitialiseCoRoutineLists() has been + * called. prvInitialiseCoRoutineLists() is called automatically when a + * co-routine is created. */ + if( pxDelayedCoRoutineList != NULL ) + { + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + * of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + } + } +/*-----------------------------------------------------------*/ + + static void prvInitialiseCoRoutineLists( void ) + { + UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + * pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; + } +/*-----------------------------------------------------------*/ + + BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ) + { + CRCB_t * pxUnblockedCRCB; + BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + * event lists and the pending ready list. This function assumes that a + * check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES == 0 */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c b/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c new file mode 100644 index 0000000..e337f13 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c @@ -0,0 +1,799 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "event_groups.h" + +/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified + * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined + * for the header files above, but not in this file, in order to generate the + * correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ + +typedef struct EventGroupDef_t +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */ + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif +} EventGroup_t; + +/*-----------------------------------------------------------*/ + +/* + * Test the bits set in uxCurrentEventBits to see if the wait condition is met. + * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is + * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor + * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the + * wait condition is met if any of the bits set in uxBitsToWait for are also set + * in uxCurrentEventBits. + */ +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) + { + EventGroup_t * pxEventBits; + + /* A StaticEventGroup_t object must be provided. */ + configASSERT( pxEventGroupBuffer ); + + #if ( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + * variable of type StaticEventGroup_t equals the size of the real + * event group structure. */ + volatile size_t xSize = sizeof( StaticEventGroup_t ); + configASSERT( xSize == sizeof( EventGroup_t ) ); + } /*lint !e529 xSize is referenced if configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + /* The user has provided a statically allocated event group - use it. */ + pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note that + * this event group was created statically in case the event group + * is later deleted. */ + pxEventBits->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + /* xEventGroupCreateStatic should only ever be called with + * pxEventGroupBuffer pointing to a pre-allocated (compile time + * allocated) StaticEventGroup_t variable. */ + traceEVENT_GROUP_CREATE_FAILED(); + } + + return pxEventBits; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreate( void ) + { + EventGroup_t * pxEventBits; + + /* Allocate the event group. Justification for MISRA deviation as + * follows: pvPortMalloc() always ensures returned memory blocks are + * aligned per the requirements of the MCU stack. In this case + * pvPortMalloc() must return a pointer that is guaranteed to meet the + * alignment requirements of the EventGroup_t structure - which (if you + * follow it through) is the alignment requirements of the TickType_t type + * (EventBits_t being of TickType_t itself). Therefore, whenever the + * stack alignment requirements are greater than or equal to the + * TickType_t alignment requirements the cast is safe. In other cases, + * where the natural word size of the architecture is less than + * sizeof( TickType_t ), the TickType_t variables will be accessed in two + * or more reads operations, and the alignment requirements is only that + * of each individual read. */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note this + * event group was allocated statically in case the event group is + * later deleted. */ + pxEventBits->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ + } + + return pxEventBits; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) +{ + EventBits_t uxOriginalBitValue, uxReturn; + EventGroup_t * pxEventBits = xEventGroup; + BaseType_t xAlreadyYielded; + BaseType_t xTimeoutOccurred = pdFALSE; + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + * already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + * task's event list item so the kernel knows when a match is + * found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + * the task unblocks, but some compilers mistakenly generate a + * warning about uxReturn being returned without being set if the + * assignment is omitted. */ + uxReturn = 0; + } + else + { + /* The rendezvous bits were not set, but no block time was + * specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + xTimeoutOccurred = pdTRUE; + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + * point either the required bits were set or the block time expired. If + * the required bits were set they will have been stored in the task's + * event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + /* The task timed out, just return the current event bit value. */ + taskENTER_CRITICAL(); + { + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + * bits it was waiting for were set, it is possible that since it + * unblocked another task has set the bits. If this is the case + * then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + * returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) +{ + EventGroup_t * pxEventBits = xEventGroup; + EventBits_t uxReturn, uxControlBits = 0; + BaseType_t xWaitConditionMet, xAlreadyYielded; + BaseType_t xTimeoutOccurred = pdFALSE; + + /* Check the user is not attempting to wait on the bits used by the kernel + * itself, and that at least one bit is being requested. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + * block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + * specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task is going to block to wait for its required bits to be + * set. uxControlBits are used to remember the specified behaviour of + * this call to xEventGroupWaitBits() - for use when the event bits + * unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWaitForAllBits != pdFALSE ) + { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + * task's event list item so the kernel knows when a match is + * found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + * some compilers mistakenly generate a warning about the variable + * being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + * point either the required bits were set or the block time expired. If + * the required bits were set they will have been stored in the task's + * event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + * task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xTimeoutOccurred = pdTRUE; + } + taskEXIT_CRITICAL(); + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) +{ + EventGroup_t * pxEventBits = xEventGroup; + EventBits_t uxReturn; + + /* Check the user is not attempting to clear the bits used by the kernel + * itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + * cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) +{ + UBaseType_t uxSavedInterruptStatus; + EventGroup_t const * const pxEventBits = xEventGroup; + EventBits_t uxReturn; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return uxReturn; +} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) +{ + ListItem_t * pxListItem; + ListItem_t * pxNext; + ListItem_t const * pxListEnd; + List_t const * pxList; + EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; + EventGroup_t * pxEventBits = xEventGroup; + BaseType_t xMatchFound = pdFALSE; + + /* Check the user is not attempting to set the bits used by the kernel + * itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ + xMatchFound = pdTRUE; + } + else + { + /* Need all bits to be set, but not all the bits were set. */ + } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + * item before removing the task from the event list. The + * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + * that is was unblocked due to its required bits matching, rather + * than because it timed out. */ + vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + * used here as the list item may have been removed from the event list + * and inserted into the ready/pending reading list. */ + pxListItem = pxNext; + } + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + * bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + ( void ) xTaskResumeAll(); + + return pxEventBits->uxEventBits; +} +/*-----------------------------------------------------------*/ + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ + EventGroup_t * pxEventBits = xEventGroup; + const List_t * pxTasksWaitingForBits; + + configASSERT( pxEventBits ); + + pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) + { + /* Unblock the task, returning 0 as the event list is being deleted + * and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + } + ( void ) xTaskResumeAll(); + + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The event group can only have been allocated dynamically - free + * it again. */ + vPortFree( pxEventBits ); + } + #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The event group could have been allocated statically or + * dynamically, so check before attempting to free the memory. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxEventBits ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) + { + BaseType_t xReturn; + EventGroup_t * pxEventBits = xEventGroup; + + configASSERT( pxEventBits ); + configASSERT( ppxEventGroupBuffer ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Check if the event group was statically allocated. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) + { + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* configSUPPORT_DYNAMIC_ALLOCATION */ + { + /* Event group must have been statically allocated. */ + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'set bits' command that was pended from + * an interrupt. */ +void vEventGroupSetBitsCallback( void * pvEventGroup, + const uint32_t ulBitsToSet ) +{ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'clear bits' command that was pended from + * an interrupt. */ +void vEventGroupClearBitsCallback( void * pvEventGroup, + const uint32_t ulBitsToClear ) +{ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xWaitForAllBits ) +{ + BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) + { + /* Task only has to wait for one bit within uxBitsToWaitFor to be + * set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + * Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xWaitConditionMet; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) + { + ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h b/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h new file mode 100644 index 0000000..4a19f93 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h @@ -0,0 +1,1460 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +#include /* READ COMMENT ABOVE. */ + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/* Acceptable values for configTICK_TYPE_WIDTH_IN_BITS. */ +#define TICK_TYPE_WIDTH_16_BITS 0 +#define TICK_TYPE_WIDTH_32_BITS 1 +#define TICK_TYPE_WIDTH_64_BITS 2 + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +#if !defined( configUSE_16_BIT_TICKS ) && !defined( configTICK_TYPE_WIDTH_IN_BITS ) + #error Missing definition: One of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if defined( configUSE_16_BIT_TICKS ) && defined( configTICK_TYPE_WIDTH_IN_BITS ) + #error Only one of configUSE_16_BIT_TICKS and configTICK_TYPE_WIDTH_IN_BITS must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +/* Define configTICK_TYPE_WIDTH_IN_BITS according to the + * value of configUSE_16_BIT_TICKS for backward compatibility. */ +#ifndef configTICK_TYPE_WIDTH_IN_BITS + #if ( configUSE_16_BIT_TICKS == 1 ) + #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_16_BITS + #else + #define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS + #endif +#endif + +/* Set configUSE_MPU_WRAPPERS_V1 to 1 to use MPU wrappers v1. */ +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#endif + +/* Set configENABLE_ACCESS_CONTROL_LIST to 1 to enable access control list support. */ +#ifndef configENABLE_ACCESS_CONTROL_LIST + #define configENABLE_ACCESS_CONTROL_LIST 0 +#endif + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + + #include "newlib-freertos.h" + +#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */ + +/* Must be defaulted before configUSE_PICOLIBC_TLS is used below. */ +#ifndef configUSE_PICOLIBC_TLS + #define configUSE_PICOLIBC_TLS 0 +#endif + +#if ( configUSE_PICOLIBC_TLS == 1 ) + + #include "picolibc-freertos.h" + +#endif /* if ( configUSE_PICOLIBC_TLS == 1 ) */ + +#ifndef configUSE_C_RUNTIME_TLS_SUPPORT + #define configUSE_C_RUNTIME_TLS_SUPPORT 0 +#endif + +#if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + + #ifndef configTLS_BLOCK_TYPE + #error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif + + #ifndef configINIT_TLS_BLOCK + #error Missing definition: configINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif + + #ifndef configSET_TLS_BLOCK + #error Missing definition: configSET_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif + + #ifndef configDEINIT_TLS_BLOCK + #error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif +#endif /* if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) */ + +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configMAX_PRIORITIES < 1 + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if ( ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_16_BITS ) && \ + ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_32_BITS ) && \ + ( configTICK_TYPE_WIDTH_IN_BITS != TICK_TYPE_WIDTH_64_BITS ) ) + #error Macro configTICK_TYPE_WIDTH_IN_BITS is defined to incorrect value. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete + #define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend + #define INCLUDE_vTaskSuspend 0 +#endif + +#ifdef INCLUDE_xTaskDelayUntil + #ifdef INCLUDE_vTaskDelayUntil + +/* INCLUDE_vTaskDelayUntil was replaced by INCLUDE_xTaskDelayUntil. Backward + * compatibility is maintained if only one or the other is defined, but + * there is a conflict if both are defined. */ + #error INCLUDE_vTaskDelayUntil and INCLUDE_xTaskDelayUntil are both defined. INCLUDE_vTaskDelayUntil is no longer required and should be removed + #endif +#endif + +#ifndef INCLUDE_xTaskDelayUntil + #ifdef INCLUDE_vTaskDelayUntil + +/* If INCLUDE_vTaskDelayUntil is set but INCLUDE_xTaskDelayUntil is not then + * the project's FreeRTOSConfig.h probably pre-dates the introduction of + * xTaskDelayUntil and setting INCLUDE_xTaskDelayUntil to whatever + * INCLUDE_vTaskDelayUntil is set to will ensure backward compatibility. + */ + #define INCLUDE_xTaskDelayUntil INCLUDE_vTaskDelayUntil + #endif +#endif + +#ifndef INCLUDE_xTaskDelayUntil + #define INCLUDE_xTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay + #define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay + #define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle + #define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark2 + #define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 1 +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +/* configPRECONDITION should be defined as configASSERT. + * The CBMC proofs need a way to track assumptions and assertions. + * A configPRECONDITION statement should express an implicit invariant or + * assumption made. A configASSERT statement should express an invariant that must + * hold explicit before calling the code. */ +#ifndef configPRECONDITION + #define configPRECONDITION( X ) configASSERT( X ) + #define configPRECONDITION_DEFINED 0 +#else + #define configPRECONDITION_DEFINED 1 +#endif + +#ifndef portMEMORY_BARRIER + #define portMEMORY_BARRIER() +#endif + +#ifndef portSOFTWARE_BARRIER + #define portSOFTWARE_BARRIER() +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue ) +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) ( pxTCB ) +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) ( pxTCB ) +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) + #define pcQueueGetName( xQueue ) +#endif + +#ifndef configUSE_MINI_LIST_ITEM + #define configUSE_MINI_LIST_ITEM 1 +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + +/* Used to perform any necessary initialisation - for example, open a file + * into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + +/* Use to close a trace, for example close a file into which trace has been + * written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + +/* Called after a task has been selected to run. pxCurrentTCB holds a pointer + * to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + +/* Called before stepping the tick count after waking from tickless idle + * sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + +/* Called before a task has been selected to run. pxCurrentTCB holds a pointer + * to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + +/* Called when a task attempts to take a mutex that is already held by a + * lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + * that holds the mutex. uxInheritedPriority is the priority the mutex holder + * will inherit (the priority of the task that is attempting to obtain the + * muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + +/* Called when a task releases a mutex, the holding of which had resulted in + * the task inheriting the priority of a higher priority task. + * pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + * mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + +/* Task is about to block because it cannot read from a + * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + * upon which the read was attempted. pxCurrentTCB points to the TCB of the + * task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_PEEK + +/* Task is about to block because it cannot read from a + * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + * upon which the read was attempted. pxCurrentTCB points to the TCB of the + * task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + +/* Task is about to block because it cannot write to a + * queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + * upon which the write was attempted. pxCurrentTCB points to the TCB of the + * task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 0 +#endif + +#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H + #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE + #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SET_SEND + #define traceQUEUE_SET_SEND traceQUEUE_SEND +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) ( xTimeoutOccurred ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) ( xTimeoutOccurred ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, ret ) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, ret ) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWait ) +#endif + +#ifndef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE( uxIndexToWait ) +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK + #define traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait ) +#endif + +#ifndef traceTASK_NOTIFY_WAIT + #define traceTASK_NOTIFY_WAIT( uxIndexToWait ) +#endif + +#ifndef traceTASK_NOTIFY + #define traceTASK_NOTIFY( uxIndexToNotify ) +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR + #define traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify ) +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING + #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef portALLOCATE_SECURE_CONTEXT + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) +#endif + +#ifndef portDONT_DISCARD + #define portDONT_DISCARD +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY + #define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP + #define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS + #define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef configTASK_NOTIFICATION_ARRAY_ENTRIES + #define configTASK_NOTIFICATION_ARRAY_ENTRIES 1 +#endif + +#if configTASK_NOTIFICATION_ARRAY_ENTRIES < 1 + #error configTASK_NOTIFICATION_ARRAY_ENTRIES must be at least 1 +#endif + +#ifndef configUSE_POSIX_ERRNO + #define configUSE_POSIX_ERRNO 0 +#endif + +#ifndef configUSE_SB_COMPLETED_CALLBACK + +/* By default per-instance callbacks are not enabled for stream buffer or message buffer. */ + #define configUSE_SB_COMPLETED_CALLBACK 0 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC + #define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#if ( ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION != 1 ) ) + #error configUSE_STATS_FORMATTING_FUNCTIONS cannot be used without dynamic allocation, but configSUPPORT_DYNAMIC_ALLOCATION is not set to 1. +#endif + +#if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) + #if ( ( configUSE_TRACE_FACILITY != 1 ) && ( configGENERATE_RUN_TIME_STATS != 1 ) ) + #error configUSE_STATS_FORMATTING_FUNCTIONS is 1 but the functions it enables are not used because neither configUSE_TRACE_FACILITY or configGENERATE_RUN_TIME_STATS are 1. Set configUSE_STATS_FORMATTING_FUNCTIONS to 0 in FreeRTOSConfig.h. + #endif +#endif + +#ifndef configSTACK_DEPTH_TYPE + +/* Defaults to uint16_t for backward compatibility, but can be overridden + * in FreeRTOSConfig.h if uint16_t is too restrictive. */ + #define configSTACK_DEPTH_TYPE uint16_t +#endif + +#ifndef configRUN_TIME_COUNTER_TYPE + +/* Defaults to uint32_t for backward compatibility, but can be overridden in + * FreeRTOSConfig.h if uint32_t is too restrictive. */ + + #define configRUN_TIME_COUNTER_TYPE uint32_t +#endif + +#ifndef configMESSAGE_BUFFER_LENGTH_TYPE + +/* Defaults to size_t for backward compatibility, but can be overridden + * in FreeRTOSConfig.h if lengths will always be less than the number of bytes + * in a size_t. */ + #define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#endif + +/* Sanity check the configuration. */ +#if ( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if ( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) + #error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#ifndef configINITIAL_TICK_COUNT + #define configINITIAL_TICK_COUNT 0 +#endif + +#if ( portTICK_TYPE_IS_ATOMIC == 0 ) + +/* Either variables of tick type cannot be read atomically, or + * portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when + * the tick count is returned to the standard critical section macros. */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else + +/* The tick type can be read atomically, so critical sections used when the + * tick count is returned can be defined away. */ + #define portTICK_TYPE_ENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) ( x ) +#endif /* if ( portTICK_TYPE_IS_ATOMIC == 0 ) */ + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to + * V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#ifndef configPRINTF + +/* configPRINTF() was not defined, so define it away to nothing. To use + * configPRINTF() then define it as follows (where MyPrintFunction() is + * provided by the application writer): + * + * void MyPrintFunction(const char *pcFormat, ... ); + #define configPRINTF( X ) MyPrintFunction X + * + * Then call like a standard printf() function, but placing brackets around + * all parameters so they are passed as a single parameter. For example: + * configPRINTF( ("Value = %d", MyVariable) ); */ + #define configPRINTF( X ) +#endif + +#ifndef configMAX + +/* The application writer has not provided their own MAX macro, so define + * the following generic implementation. */ + #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef configMIN + +/* The application writer has not provided their own MIN macro, so define + * the following generic implementation. */ + #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + #define pcTaskGetTaskName pcTaskGetName + #define pcTimerGetTimerName pcTimerGetName + #define pcQueueGetQueueName pcQueueGetName + #define vTaskGetTaskInfo vTaskGetInfo + #define xTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter + +/* Backward compatibility within the scheduler code only - these definitions + * are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t + +/* For libraries that break the list data hiding, and access list structure + * members directly (which is not supposed to be done). */ + #define pxContainer pvContainer +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if ( configUSE_ALTERNATIVE_API != 0 ) + #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even + * if floating point hardware is otherwise supported by the FreeRTOS port in use. + * This constant is not supported by all FreeRTOS ports that include floating + * point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT + #define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is + * currently used in ARMv8M ports. */ +#ifndef configENABLE_MPU + #define configENABLE_MPU 0 +#endif + +/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is + * currently used in ARMv8M ports. */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 1 +#endif + +/* Set configENABLE_MVE to 1 to enable MVE support and 0 to disable it. This is + * currently used in ARMv8M ports. */ +#ifndef configENABLE_MVE + #define configENABLE_MVE 0 +#endif + +/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. + * This is currently used in ARMv8M ports. */ +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE 1 +#endif + +/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on + * the Secure Side only. */ +#ifndef configRUN_FREERTOS_SECURE_ONLY + #define configRUN_FREERTOS_SECURE_ONLY 0 +#endif + +#ifndef configRUN_ADDITIONAL_TESTS + #define configRUN_ADDITIONAL_TESTS 0 +#endif + + +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using + * dynamically allocated RAM, in which case when any task is deleted it is known + * that both the task's stack and TCB need to be freed. Sometimes the + * FreeRTOSConfig.h settings only allow a task to be created using statically + * allocated RAM, in which case when any task is deleted it is known that neither + * the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h + * settings allow a task to be created using either statically or dynamically + * allocated RAM, in which case a member of the TCB is used to record whether the + * stack and/or TCB were allocated statically or dynamically, so when a task is + * deleted the RAM that was allocated dynamically is freed again and no attempt is + * made to free the RAM that was allocated statically. + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a + * task to be created using either statically or dynamically allocated RAM. Note + * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with + * a statically allocated stack and a dynamically allocated TCB. + * + * The following table lists various combinations of portUSING_MPU_WRAPPERS, + * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and + * when it is possible to have both static and dynamic allocation: + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free | + * | | | | | | Static Possible | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | | + * | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE \ + ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ + ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be known. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void * pvDummy3[ 4 ]; + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy4; + #endif +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +#if ( configUSE_MINI_LIST_ITEM == 1 ) + /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ + struct xSTATIC_MINI_LIST_ITEM + { + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void * pvDummy3[ 2 ]; + }; + typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; +#else /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ + typedef struct xSTATIC_LIST_ITEM StaticMiniListItem_t; +#endif /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + UBaseType_t uxDummy2; + void * pvDummy3; + StaticMiniListItem_t xDummy4; + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy5; + #endif +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be known. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void * pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void * pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void * pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void * pxDummy14; + #endif + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + configRUN_TIME_COUNTER_TYPE ulDummy16; + #endif + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + configTLS_BLOCK_TYPE xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + uint8_t ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + #endif + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t uxDummy20; + #endif + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; + #endif + #if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; + #endif +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be known. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void * pvDummy1[ 3 ]; + + union + { + void * pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void * pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be known. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void * pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + void * pvDummy5; + TaskFunction_t pvDummy6; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; + #endif + uint8_t ucDummy8; +} StaticTimer_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the stream buffer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a stream buffer then the size of the stream buffer object needs to be + * known. The StaticStreamBuffer_t structure below is provided for this + * purpose. Its size and alignment requirements are guaranteed to match those + * of the genuine structure, no matter which architecture is being used, and + * no matter how the values in FreeRTOSConfig.h are set. Its contents are + * somewhat obfuscated in the hope users will recognise that it would be unwise + * to make direct use of the structure members. + */ +typedef struct xSTATIC_STREAM_BUFFER +{ + size_t uxDummy1[ 4 ]; + void * pvDummy2[ 3 ]; + uint8_t ucDummy3; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; + #endif + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + void * pvDummy5[ 2 ]; + #endif +} StaticStreamBuffer_t; + +/* Message buffers are built on stream buffers. */ +typedef StaticStreamBuffer_t StaticMessageBuffer_t; + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* INC_FREERTOS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h b/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h new file mode 100644 index 0000000..006068c --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h @@ -0,0 +1,34 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#ifndef _MSC_VER /* Visual Studio doesn't support #warning. */ + #warning The name of this file has changed to stack_macros.h. Please update your code accordingly. This source file (which has the original name) will be removed in a future release. +#endif + +#include "stack_macros.h" diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h b/Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h new file mode 100644 index 0000000..033edce --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/atomic.h @@ -0,0 +1,419 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * @file atomic.h + * @brief FreeRTOS atomic operation support. + * + * This file implements atomic functions by disabling interrupts globally. + * Implementations with architecture specific atomic instructions can be + * provided under each compiler directory. + */ + +#ifndef ATOMIC_H +#define ATOMIC_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include atomic.h" +#endif + +/* Standard includes. */ +#include + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/* + * Port specific definitions -- entering/exiting critical section. + * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h + * + * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with + * ATOMIC_ENTER_CRITICAL(). + * + */ +#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) + +/* Nested interrupt scheme is supported in this port. */ + #define ATOMIC_ENTER_CRITICAL() \ + UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR() + + #define ATOMIC_EXIT_CRITICAL() \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType ) + +#else + +/* Nested interrupt scheme is NOT supported in this port. */ + #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL() + #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL() + +#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */ + +/* + * Port specific definition -- "always inline". + * Inline is compiler specific, and may not always get inlined depending on your + * optimization level. Also, inline is considered as performance optimization + * for atomic. Thus, if portFORCE_INLINE is not provided by portmacro.h, + * instead of resulting error, simply define it away. + */ +#ifndef portFORCE_INLINE + #define portFORCE_INLINE +#endif + +#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */ +#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */ + +/*----------------------------- Swap && CAS ------------------------------*/ + +/** + * Atomic compare-and-swap + * + * @brief Performs an atomic compare-and-swap operation on the specified values. + * + * @param[in, out] pulDestination Pointer to memory location from where value is + * to be loaded and checked. + * @param[in] ulExchange If condition meets, write this value to memory. + * @param[in] ulComparand Swap condition. + * + * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. + * + * @note This function only swaps *pulDestination with ulExchange, if previous + * *pulDestination value equals ulComparand. + */ +static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination, + uint32_t ulExchange, + uint32_t ulComparand ) +{ + uint32_t ulReturnValue; + + ATOMIC_ENTER_CRITICAL(); + { + if( *pulDestination == ulComparand ) + { + *pulDestination = ulExchange; + ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; + } + else + { + ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; + } + } + ATOMIC_EXIT_CRITICAL(); + + return ulReturnValue; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic swap (pointers) + * + * @brief Atomically sets the address pointed to by *ppvDestination to the value + * of *pvExchange. + * + * @param[in, out] ppvDestination Pointer to memory location from where a pointer + * value is to be loaded and written back to. + * @param[in] pvExchange Pointer value to be written to *ppvDestination. + * + * @return The initial value of *ppvDestination. + */ +static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination, + void * pvExchange ) +{ + void * pReturnValue; + + ATOMIC_ENTER_CRITICAL(); + { + pReturnValue = *ppvDestination; + *ppvDestination = pvExchange; + } + ATOMIC_EXIT_CRITICAL(); + + return pReturnValue; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic compare-and-swap (pointers) + * + * @brief Performs an atomic compare-and-swap operation on the specified pointer + * values. + * + * @param[in, out] ppvDestination Pointer to memory location from where a pointer + * value is to be loaded and checked. + * @param[in] pvExchange If condition meets, write this value to memory. + * @param[in] pvComparand Swap condition. + * + * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped. + * + * @note This function only swaps *ppvDestination with pvExchange, if previous + * *ppvDestination value equals pvComparand. + */ +static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination, + void * pvExchange, + void * pvComparand ) +{ + uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE; + + ATOMIC_ENTER_CRITICAL(); + { + if( *ppvDestination == pvComparand ) + { + *ppvDestination = pvExchange; + ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS; + } + } + ATOMIC_EXIT_CRITICAL(); + + return ulReturnValue; +} + + +/*----------------------------- Arithmetic ------------------------------*/ + +/** + * Atomic add + * + * @brief Atomically adds count to the value of the specified pointer points to. + * + * @param[in,out] pulAddend Pointer to memory location from where value is to be + * loaded and written back to. + * @param[in] ulCount Value to be added to *pulAddend. + * + * @return previous *pulAddend value. + */ +static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend, + uint32_t ulCount ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulAddend; + *pulAddend += ulCount; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic subtract + * + * @brief Atomically subtracts count from the value of the specified pointer + * pointers to. + * + * @param[in,out] pulAddend Pointer to memory location from where value is to be + * loaded and written back to. + * @param[in] ulCount Value to be subtract from *pulAddend. + * + * @return previous *pulAddend value. + */ +static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend, + uint32_t ulCount ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulAddend; + *pulAddend -= ulCount; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic increment + * + * @brief Atomically increments the value of the specified pointer points to. + * + * @param[in,out] pulAddend Pointer to memory location from where value is to be + * loaded and written back to. + * + * @return *pulAddend value before increment. + */ +static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulAddend; + *pulAddend += 1; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic decrement + * + * @brief Atomically decrements the value of the specified pointer points to + * + * @param[in,out] pulAddend Pointer to memory location from where value is to be + * loaded and written back to. + * + * @return *pulAddend value before decrement. + */ +static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulAddend; + *pulAddend -= 1; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} + +/*----------------------------- Bitwise Logical ------------------------------*/ + +/** + * Atomic OR + * + * @brief Performs an atomic OR operation on the specified values. + * + * @param [in, out] pulDestination Pointer to memory location from where value is + * to be loaded and written back to. + * @param [in] ulValue Value to be ORed with *pulDestination. + * + * @return The original value of *pulDestination. + */ +static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination, + uint32_t ulValue ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulDestination; + *pulDestination |= ulValue; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic AND + * + * @brief Performs an atomic AND operation on the specified values. + * + * @param [in, out] pulDestination Pointer to memory location from where value is + * to be loaded and written back to. + * @param [in] ulValue Value to be ANDed with *pulDestination. + * + * @return The original value of *pulDestination. + */ +static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination, + uint32_t ulValue ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulDestination; + *pulDestination &= ulValue; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic NAND + * + * @brief Performs an atomic NAND operation on the specified values. + * + * @param [in, out] pulDestination Pointer to memory location from where value is + * to be loaded and written back to. + * @param [in] ulValue Value to be NANDed with *pulDestination. + * + * @return The original value of *pulDestination. + */ +static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination, + uint32_t ulValue ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulDestination; + *pulDestination = ~( ulCurrent & ulValue ); + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} +/*-----------------------------------------------------------*/ + +/** + * Atomic XOR + * + * @brief Performs an atomic XOR operation on the specified values. + * + * @param [in, out] pulDestination Pointer to memory location from where value is + * to be loaded and written back to. + * @param [in] ulValue Value to be XORed with *pulDestination. + * + * @return The original value of *pulDestination. + */ +static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination, + uint32_t ulValue ) +{ + uint32_t ulCurrent; + + ATOMIC_ENTER_CRITICAL(); + { + ulCurrent = *pulDestination; + *pulDestination ^= ulValue; + } + ATOMIC_EXIT_CRITICAL(); + + return ulCurrent; +} + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* ATOMIC_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h b/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h new file mode 100644 index 0000000..df50f87 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h @@ -0,0 +1,755 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/* Used to hide the implementation of the co-routine control block. The + * control block structure however has to be included in the header due to + * the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t, + UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /**< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /**< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /**< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /**< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /**< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + * @code{c} + * BaseType_t xCoRoutineCreate( + * crCOROUTINE_CODE pxCoRoutineCode, + * UBaseType_t uxPriority, + * UBaseType_t uxIndex + * ); + * @endcode + * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * // This may not be necessary for const variables. + * static const char cLedToFlash[ 2 ] = { 5, 6 }; + * static const TickType_t uxFlashRates[ 2 ] = { 200, 400 }; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // This co-routine just delays for a fixed period, then toggles + * // an LED. Two co-routines are created using this function, so + * // the uxIndex parameter is used to tell the co-routine which + * // LED to flash and how int32_t to delay. This assumes xQueue has + * // already been created. + * vParTestToggleLED( cLedToFlash[ uxIndex ] ); + * crDELAY( xHandle, uxFlashRates[ uxIndex ] ); + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * + * // Function that creates two co-routines. + * void vOtherFunction( void ) + * { + * uint8_t ucParameterToPass; + * TaskHandle_t xHandle; + * + * // Create two co-routines at priority 0. The first is given index 0 + * // so (from the code above) toggles LED 5 every 200 ticks. The second + * // is given index 1 so toggles LED 6 every 400 ticks. + * for( uxIndex = 0; uxIndex < 2; uxIndex++ ) + * { + * xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex ); + * } + * } + * @endcode + * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, + UBaseType_t uxPriority, + UBaseType_t uxIndex ); + + +/** + * croutine. h + * @code{c} + * void vCoRoutineSchedule( void ); + * @endcode + * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: + * @code{c} + * // This idle task hook will schedule a co-routine each time it is called. + * // The rest of the idle task will execute between co-routine calls. + * void vApplicationIdleHook( void ) + * { + * vCoRoutineSchedule(); + * } + * + * // Alternatively, if you do not require any other part of the idle task to + * // execute, the idle task hook can call vCoRoutineSchedule() within an + * // infinite loop. + * void vApplicationIdleHook( void ) + * { + * for( ;; ) + * { + * vCoRoutineSchedule(); + * } + * } + * @endcode + * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + * @code{c} + * crSTART( CoRoutineHandle_t xHandle ); + * @endcode + * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static int32_t ulAVariable; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Co-routine functionality goes here. + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * @endcode + * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) \ + switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \ + case 0: + +/** + * croutine. h + * @code{c} + * crEND(); + * @endcode + * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static int32_t ulAVariable; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Co-routine functionality goes here. + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * @endcode + * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) \ + ( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \ + case ( __LINE__ * 2 ): +#define crSET_STATE1( xHandle ) \ + ( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \ + case ( ( __LINE__ * 2 ) + 1 ): + +/** + * croutine. h + * @code{c} + * crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay ); + * @endcode + * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: + * @code{c} + * // Co-routine to be created. + * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * // This may not be necessary for const variables. + * // We are to delay for 200ms. + * static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS; + * + * // Must start every co-routine with a call to crSTART(); + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Delay for 200ms. + * crDELAY( xHandle, xDelayTime ); + * + * // Do something here. + * } + * + * // Must end every co-routine with a call to crEND(); + * crEND(); + * } + * @endcode + * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + do { \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); \ + } while( 0 ) + +/** + * @code{c} + * crQUEUE_SEND( + * CoRoutineHandle_t xHandle, + * QueueHandle_t pxQueue, + * void *pvItemToQueue, + * TickType_t xTicksToWait, + * BaseType_t *pxResult + * ) + * @endcode + * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: + * @code{c} + * // Co-routine function that blocks for a fixed period then posts a number onto + * // a queue. + * static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static BaseType_t xNumberToPost = 0; + * static BaseType_t xResult; + * + * // Co-routines must begin with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // This assumes the queue has already been created. + * crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult ); + * + * if( xResult != pdPASS ) + * { + * // The message was not posted! + * } + * + * // Increment the number to be posted onto the queue. + * xNumberToPost++; + * + * // Delay for 100 ticks. + * crDELAY( xHandle, 100 ); + * } + * + * // Co-routines must end with a call to crEND(). + * crEND(); + * } + * @endcode + * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ + do { \ + *( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ + } while( 0 ) + +/** + * croutine. h + * @code{c} + * crQUEUE_RECEIVE( + * CoRoutineHandle_t xHandle, + * QueueHandle_t pxQueue, + * void *pvBuffer, + * TickType_t xTicksToWait, + * BaseType_t *pxResult + * ) + * @endcode + * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: + * @code{c} + * // A co-routine receives the number of an LED to flash from a queue. It + * // blocks on the queue until the number is received. + * static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // Variables in co-routines must be declared static if they must maintain value across a blocking call. + * static BaseType_t xResult; + * static UBaseType_t uxLEDToFlash; + * + * // All co-routines must start with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Wait for data to become available on the queue. + * crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + * + * if( xResult == pdPASS ) + * { + * // We received the LED to flash - flash it! + * vParTestToggleLED( uxLEDToFlash ); + * } + * } + * + * crEND(); + * } + * @endcode + * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ + do { \ + *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ + } while( 0 ) + +/** + * croutine. h + * @code{c} + * crQUEUE_SEND_FROM_ISR( + * QueueHandle_t pxQueue, + * void *pvItemToQueue, + * BaseType_t xCoRoutinePreviouslyWoken + * ) + * @endcode + * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: + * @code{c} + * // A co-routine that blocks on a queue waiting for characters to be received. + * static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * char cRxedChar; + * BaseType_t xResult; + * + * // All co-routines must start with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Wait for data to become available on the queue. This assumes the + * // queue xCommsRxQueue has already been created! + * crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + * + * // Was a character received? + * if( xResult == pdPASS ) + * { + * // Process the character here. + * } + * } + * + * // All co-routines must end with a call to crEND(). + * crEND(); + * } + * + * // An ISR that uses a queue to send characters received on a serial port to + * // a co-routine. + * void vUART_ISR( void ) + * { + * char cRxedChar; + * BaseType_t xCRWokenByPost = pdFALSE; + * + * // We loop around reading characters until there are none left in the UART. + * while( UART_RX_REG_NOT_EMPTY() ) + * { + * // Obtain the character from the UART. + * cRxedChar = UART_RX_REG; + * + * // Post the character onto a queue. xCRWokenByPost will be pdFALSE + * // the first time around the loop. If the post causes a co-routine + * // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE. + * // In this manner we can ensure that if more than one co-routine is + * // blocked on the queue only one is woken by this ISR no matter how + * // many characters are posted to the queue. + * xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost ); + * } + * } + * @endcode + * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) \ + xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + * @code{c} + * crQUEUE_SEND_FROM_ISR( + * QueueHandle_t pxQueue, + * void *pvBuffer, + * BaseType_t * pxCoRoutineWoken + * ) + * @endcode + * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: + * @code{c} + * // A co-routine that posts a character to a queue then blocks for a fixed + * // period. The character is incremented each time. + * static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) + * { + * // cChar holds its value while this co-routine is blocked and must therefore + * // be declared static. + * static char cCharToTx = 'a'; + * BaseType_t xResult; + * + * // All co-routines must start with a call to crSTART(). + * crSTART( xHandle ); + * + * for( ;; ) + * { + * // Send the next character to the queue. + * crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult ); + * + * if( xResult == pdPASS ) + * { + * // The character was successfully posted to the queue. + * } + * else + * { + * // Could not post the character to the queue. + * } + * + * // Enable the UART Tx interrupt to cause an interrupt in this + * // hypothetical UART. The interrupt will obtain the character + * // from the queue and send it. + * ENABLE_RX_INTERRUPT(); + * + * // Increment to the next character then block for a fixed period. + * // cCharToTx will maintain its value across the delay as it is + * // declared static. + * cCharToTx++; + * if( cCharToTx > 'x' ) + * { + * cCharToTx = 'a'; + * } + * crDELAY( 100 ); + * } + * + * // All co-routines must end with a call to crEND(). + * crEND(); + * } + * + * // An ISR that uses a queue to receive characters to send on a UART. + * void vUART_ISR( void ) + * { + * char cCharToTx; + * BaseType_t xCRWokenByPost = pdFALSE; + * + * while( UART_TX_REG_EMPTY() ) + * { + * // Are there any characters in the queue waiting to be sent? + * // xCRWokenByPost will automatically be set to pdTRUE if a co-routine + * // is woken by the post - ensuring that only a single co-routine is + * // woken no matter how many times we go around this loop. + * if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) ) + * { + * SEND_CHARACTER( cCharToTx ); + * } + * } + * } + * @endcode + * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) \ + xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, + List_t * pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ); + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* CO_ROUTINE_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h b/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h new file mode 100644 index 0000000..6a25d06 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h @@ -0,0 +1,281 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a + * pre-processor definition was used to ensure the pre-processor found the correct + * portmacro.h file for the port being used. That scheme was deprecated in favour + * of setting the compiler's include path such that it found the correct + * portmacro.h file - removing the need for the constant and allowing the + * portmacro.h file to be located anywhere in relation to the port being used. The + * definitions below remain in the code for backward compatibility only. New + * projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far * pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far * pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + +/* A short file name has to be used in place of the normal + * FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far * pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + +/* A short file name has to be used in place of the normal + * FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far * pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h b/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h new file mode 100644 index 0000000..a5c723d --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h @@ -0,0 +1,827 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +/* The following bit fields convey control information in a task's event list + * item value. It is important they don't clash with the + * taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U + #define eventWAIT_FOR_ALL_BITS 0x0400U + #define eventEVENT_BITS_CONTROL_BYTES 0xff00U +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL + #define eventWAIT_FOR_ALL_BITS 0x04000000UL + #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100000000000000ULL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200000000000000ULL + #define eventWAIT_FOR_ALL_BITS 0x0400000000000000ULL + #define eventEVENT_BITS_CONTROL_BYTES 0xff00000000000000ULL +#endif /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */ + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +struct EventGroupDef_t; +typedef struct EventGroupDef_t * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configTICK_TYPE_WIDTH_IN_BITS (16 bits if set to 0, + * 32 bits if set to 1, 64 bits if set to 2. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + * @code{c} + * EventGroupHandle_t xEventGroupCreate( void ); + * @endcode + * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGroupCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see https://www.FreeRTOS.org/a00111.html). If an event group is created + * using xEventGroupCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h. If + * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has + * 24 usable bits (bit 0 to bit 23). If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then + * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type + * is used to store event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html + * + * Example usage: + * @code{c} + * // Declare a variable to hold the created event group. + * EventGroupHandle_t xCreatedEventGroup; + * + * // Attempt to create the event group. + * xCreatedEventGroup = xEventGroupCreate(); + * + * // Was the event group created successfully? + * if( xCreatedEventGroup == NULL ) + * { + * // The event group was not created because there was insufficient + * // FreeRTOS heap available. + * } + * else + * { + * // The event group was created. + * } + * @endcode + * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + * @code{c} + * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer ); + * @endcode + * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGroupCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see https://www.FreeRTOS.org/a00111.html). If an event group is created + * using xEventGroupCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h. If + * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has + * 24 usable bits (bit 0 to bit 23). If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then + * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type + * is used to store event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: + * @code{c} + * // StaticEventGroup_t is a publicly accessible structure that has the same + * // size and alignment requirements as the real event group structure. It is + * // provided as a mechanism for applications to know the size of the event + * // group (which is dependent on the architecture and configuration file + * // settings) without breaking the strict data hiding policy by exposing the + * // real event group internals. This StaticEventGroup_t variable is passed + * // into the xSemaphoreCreateEventGroupStatic() function and is used to store + * // the event group's data structures + * StaticEventGroup_t xEventGroupBuffer; + * + * // Create the event group without dynamically allocating any memory. + * xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); + * @endcode + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + * @code{c} + * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + * const EventBits_t uxBitsToWaitFor, + * const BaseType_t xClearOnExit, + * const BaseType_t xWaitForAllBits, + * const TickType_t xTicksToWait ); + * @endcode + * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. A value of portMAX_DELAY can be used to block + * indefinitely (provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: + * @code{c} + * #define BIT_0 ( 1 << 0 ) + * #define BIT_4 ( 1 << 4 ) + * + * void aFunction( EventGroupHandle_t xEventGroup ) + * { + * EventBits_t uxBits; + * const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; + * + * // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within + * // the event group. Clear the bits before exiting. + * uxBits = xEventGroupWaitBits( + * xEventGroup, // The event group being tested. + * BIT_0 | BIT_4, // The bits within the event group to wait for. + * pdTRUE, // BIT_0 and BIT_4 should be cleared before returning. + * pdFALSE, // Don't wait for both bits, either bit will do. + * xTicksToWait ); // Wait a maximum of 100ms for either bit to be set. + * + * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) + * { + * // xEventGroupWaitBits() returned because both bits were set. + * } + * else if( ( uxBits & BIT_0 ) != 0 ) + * { + * // xEventGroupWaitBits() returned because just BIT_0 was set. + * } + * else if( ( uxBits & BIT_4 ) != 0 ) + * { + * // xEventGroupWaitBits() returned because just BIT_4 was set. + * } + * else + * { + * // xEventGroupWaitBits() returned because xTicksToWait ticks passed + * // without either BIT_0 or BIT_4 becoming set. + * } + * } + * @endcode + * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + * @code{c} + * EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); + * @endcode + * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: + * @code{c} + * #define BIT_0 ( 1 << 0 ) + * #define BIT_4 ( 1 << 4 ) + * + * void aFunction( EventGroupHandle_t xEventGroup ) + * { + * EventBits_t uxBits; + * + * // Clear bit 0 and bit 4 in xEventGroup. + * uxBits = xEventGroupClearBits( + * xEventGroup, // The event group being updated. + * BIT_0 | BIT_4 );// The bits being cleared. + * + * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) + * { + * // Both bit 0 and bit 4 were set before xEventGroupClearBits() was + * // called. Both will now be clear (not set). + * } + * else if( ( uxBits & BIT_0 ) != 0 ) + * { + * // Bit 0 was set before xEventGroupClearBits() was called. It will + * // now be clear. + * } + * else if( ( uxBits & BIT_4 ) != 0 ) + * { + * // Bit 4 was set before xEventGroupClearBits() was called. It will + * // now be clear. + * } + * else + * { + * // Neither bit 0 nor bit 4 were set in the first place. + * } + * } + * @endcode + * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + * @code{c} + * BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); + * @endcode + * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @note If this function returns pdPASS then the timer task is ready to run + * and a portYIELD_FROM_ISR(pdTRUE) should be executed to perform the needed + * clear on the event group. This behavior is different from + * xEventGroupSetBitsFromISR because the parameter xHigherPriorityTaskWoken is + * not present. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: + * @code{c} + * #define BIT_0 ( 1 << 0 ) + * #define BIT_4 ( 1 << 4 ) + * + * // An event group which it is assumed has already been created by a call to + * // xEventGroupCreate(). + * EventGroupHandle_t xEventGroup; + * + * void anInterruptHandler( void ) + * { + * // Clear bit 0 and bit 4 in xEventGroup. + * xResult = xEventGroupClearBitsFromISR( + * xEventGroup, // The event group being updated. + * BIT_0 | BIT_4 ); // The bits being set. + * + * if( xResult == pdPASS ) + * { + * // The message was posted successfully. + * portYIELD_FROM_ISR(pdTRUE); + * } + * } + * @endcode + * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \ + xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL ) +#endif + +/** + * event_groups.h + * @code{c} + * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); + * @endcode + * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: + * @code{c} + * #define BIT_0 ( 1 << 0 ) + * #define BIT_4 ( 1 << 4 ) + * + * void aFunction( EventGroupHandle_t xEventGroup ) + * { + * EventBits_t uxBits; + * + * // Set bit 0 and bit 4 in xEventGroup. + * uxBits = xEventGroupSetBits( + * xEventGroup, // The event group being updated. + * BIT_0 | BIT_4 );// The bits being set. + * + * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) + * { + * // Both bit 0 and bit 4 remained set when the function returned. + * } + * else if( ( uxBits & BIT_0 ) != 0 ) + * { + * // Bit 0 remained set when the function returned, but bit 4 was + * // cleared. It might be that bit 4 was cleared automatically as a + * // task that was waiting for bit 4 was removed from the Blocked + * // state. + * } + * else if( ( uxBits & BIT_4 ) != 0 ) + * { + * // Bit 4 remained set when the function returned, but bit 0 was + * // cleared. It might be that bit 0 was cleared automatically as a + * // task that was waiting for bit 0 was removed from the Blocked + * // state. + * } + * else + * { + * // Neither bit 0 nor bit 4 remained set. It might be that a task + * // was waiting for both of the bits to be set, and the bits were + * // cleared as the task left the Blocked state. + * } + * } + * @endcode + * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + * @code{c} + * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: + * @code{c} + * #define BIT_0 ( 1 << 0 ) + * #define BIT_4 ( 1 << 4 ) + * + * // An event group which it is assumed has already been created by a call to + * // xEventGroupCreate(). + * EventGroupHandle_t xEventGroup; + * + * void anInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken, xResult; + * + * // xHigherPriorityTaskWoken must be initialised to pdFALSE. + * xHigherPriorityTaskWoken = pdFALSE; + * + * // Set bit 0 and bit 4 in xEventGroup. + * xResult = xEventGroupSetBitsFromISR( + * xEventGroup, // The event group being updated. + * BIT_0 | BIT_4 // The bits being set. + * &xHigherPriorityTaskWoken ); + * + * // Was the message posted successfully? + * if( xResult == pdPASS ) + * { + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and + * // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - + * // refer to the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * } + * @endcode + * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \ + xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) ) +#endif + +/** + * event_groups.h + * @code{c} + * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, + * const EventBits_t uxBitsToSet, + * const EventBits_t uxBitsToWaitFor, + * TickType_t xTicksToWait ); + * @endcode + * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: + * @code{c} + * // Bits used by the three tasks. + * #define TASK_0_BIT ( 1 << 0 ) + * #define TASK_1_BIT ( 1 << 1 ) + * #define TASK_2_BIT ( 1 << 2 ) + * + * #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) + * + * // Use an event group to synchronise three tasks. It is assumed this event + * // group has already been created elsewhere. + * EventGroupHandle_t xEventBits; + * + * void vTask0( void *pvParameters ) + * { + * EventBits_t uxReturn; + * TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; + * + * for( ;; ) + * { + * // Perform task functionality here. + * + * // Set bit 0 in the event flag to note this task has reached the + * // sync point. The other two tasks will set the other two bits defined + * // by ALL_SYNC_BITS. All three tasks have reached the synchronisation + * // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms + * // for this to happen. + * uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); + * + * if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) + * { + * // All three tasks reached the synchronisation point before the call + * // to xEventGroupSync() timed out. + * } + * } + * } + * + * void vTask1( void *pvParameters ) + * { + * for( ;; ) + * { + * // Perform task functionality here. + * + * // Set bit 1 in the event flag to note this task has reached the + * // synchronisation point. The other two tasks will set the other two + * // bits defined by ALL_SYNC_BITS. All three tasks have reached the + * // synchronisation point when all the ALL_SYNC_BITS are set. Wait + * // indefinitely for this to happen. + * xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); + * + * // xEventGroupSync() was called with an indefinite block time, so + * // this task will only reach here if the synchronisation was made by all + * // three tasks, so there is no need to test the return value. + * } + * } + * + * void vTask2( void *pvParameters ) + * { + * for( ;; ) + * { + * // Perform task functionality here. + * + * // Set bit 2 in the event flag to note this task has reached the + * // synchronisation point. The other two tasks will set the other two + * // bits defined by ALL_SYNC_BITS. All three tasks have reached the + * // synchronisation point when all the ALL_SYNC_BITS are set. Wait + * // indefinitely for this to happen. + * xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); + * + * // xEventGroupSync() was called with an indefinite block time, so + * // this task will only reach here if the synchronisation was made by all + * // three tasks, so there is no need to test the return value. + * } + * } + * + * @endcode + * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + * @code{c} + * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); + * @endcode + * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( ( xEventGroup ), 0 ) + +/** + * event_groups.h + * @code{c} + * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); + * @endcode + * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + * @code{c} + * void xEventGroupDelete( EventGroupHandle_t xEventGroup ); + * @endcode + * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + * @code{c} + * BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + * StaticEventGroup_t ** ppxEventGroupBuffer ); + * @endcode + * + * Retrieve a pointer to a statically created event groups's data structure + * buffer. It is the same buffer that is supplied at the time of creation. + * + * @param xEventGroup The event group for which to retrieve the buffer. + * + * @param ppxEventGroupBuffer Used to return a pointer to the event groups's + * data structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void * pvEventGroup, + const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback( void * pvEventGroup, + const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION; + void vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* EVENT_GROUPS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/list.h b/Middlewares/Third_Party/FreeRTOS/Source/include/list.h new file mode 100644 index 0000000..62c6238 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/list.h @@ -0,0 +1,503 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * ascending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + + +#ifndef LIST_H +#define LIST_H + +#ifndef INC_FREERTOS_H + #error "FreeRTOS.h must be included before list.h" +#endif + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/* Macros that can be used to place known values within the list structures, + * then check that the known values do not get corrupted during the execution of + * the application. These may catch the list data structures being overwritten in + * memory. They will not catch data errors caused by incorrect configuration or + * use of FreeRTOS.*/ +#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) + /* Define the macros to do nothing. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) + #define listTEST_LIST_INTEGRITY( pxList ) +#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */ + /* Define macros that add new members into the list structures. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + +/* Define macros that set the new structure members to known values. */ + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + +/* Define macros that will assert if one of the structure members does not + * contain its expected value. */ + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) + #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST; +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /**< The value being listed. In most cases this is used to sort the list in ascending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /**< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /**< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /**< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST * configLIST_VOLATILE pxContainer; /**< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +#if ( configUSE_MINI_LIST_ITEM == 1 ) + struct xMINI_LIST_ITEM + { + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; + }; + typedef struct xMINI_LIST_ITEM MiniListItem_t; +#else + typedef struct xLIST_ITEM MiniListItem_t; +#endif + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + volatile UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /**< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /**< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in ascending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the next list item. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ + do { \ + List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ + } while( 0 ) + +/* + * Version of uxListRemove() that does not return a value. Provided as a slight + * optimisation for xTaskIncrementTick() by being inline. + * + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page listREMOVE_ITEM listREMOVE_ITEM + * \ingroup LinkedList + */ +#define listREMOVE_ITEM( pxItemToRemove ) \ + do { \ + /* The list item knows which list it is in. Obtain the list from the list \ + * item. */ \ + List_t * const pxList = ( pxItemToRemove )->pxContainer; \ + \ + ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \ + ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext; \ + /* Make sure the index is left pointing to a valid item. */ \ + if( pxList->pxIndex == ( pxItemToRemove ) ) \ + { \ + pxList->pxIndex = ( pxItemToRemove )->pxPrevious; \ + } \ + \ + ( pxItemToRemove )->pxContainer = NULL; \ + ( pxList->uxNumberOfItems )--; \ + } while( 0 ) + +/* + * Inline version of vListInsertEnd() to provide slight optimisation for + * xTaskIncrementTick(). + * + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page listINSERT_END listINSERT_END + * \ingroup LinkedList + */ +#define listINSERT_END( pxList, pxNewListItem ) \ + do { \ + ListItem_t * const pxIndex = ( pxList )->pxIndex; \ + \ + /* Only effective when configASSERT() is also defined, these tests may catch \ + * the list data structures being overwritten in memory. They will not catch \ + * data errors caused by incorrect configuration or use of FreeRTOS. */ \ + listTEST_LIST_INTEGRITY( ( pxList ) ); \ + listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) ); \ + \ + /* Insert a new list item into ( pxList ), but rather than sort the list, \ + * makes the new list item the last item to be removed by a call to \ + * listGET_OWNER_OF_NEXT_ENTRY(). */ \ + ( pxNewListItem )->pxNext = pxIndex; \ + ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \ + \ + pxIndex->pxPrevious->pxNext = ( pxNewListItem ); \ + pxIndex->pxPrevious = ( pxNewListItem ); \ + \ + /* Remember which list the item is in. */ \ + ( pxNewListItem )->pxContainer = ( pxList ); \ + \ + ( ( pxList )->uxNumberOfItems )++; \ + } while( 0 ) + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (ascending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, + ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, + ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* ifndef LIST_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h b/Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h new file mode 100644 index 0000000..136445d --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/message_buffer.h @@ -0,0 +1,887 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +/* + * Message buffers build functionality on top of FreeRTOS stream buffers. + * Whereas stream buffers are used to send a continuous stream of data from one + * task or interrupt to another, message buffers are used to send variable + * length discrete messages from one task or interrupt to another. Their + * implementation is light weight, making them particularly suited for interrupt + * to task and core to core communication scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * timeout to 0. + * + * Message buffers hold variable length messages. To enable that, when a + * message is written to the message buffer an additional sizeof( size_t ) bytes + * are also written to store the message's length (that happens internally, with + * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so writing a 10 byte message to a message buffer on a 32-bit + * architecture will actually reduce the available space in the message buffer + * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length + * of the message). + */ + +#ifndef FREERTOS_MESSAGE_BUFFER_H +#define FREERTOS_MESSAGE_BUFFER_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include message_buffer.h" +#endif + +/* Message buffers are built onto of stream buffers. */ +#include "stream_buffer.h" + +/* *INDENT-OFF* */ +#if defined( __cplusplus ) + extern "C" { +#endif +/* *INDENT-ON* */ + +/** + * Type by which message buffers are referenced. For example, a call to + * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can + * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), + * etc. Message buffer is essentially built as a stream buffer hence its handle + * is also set to same type as a stream buffer handle. + */ +typedef StreamBufferHandle_t MessageBufferHandle_t; + +/*-----------------------------------------------------------*/ + +/** + * message_buffer.h + * + * @code{c} + * MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes ); + * @endcode + * + * Creates a new message buffer using dynamically allocated memory. See + * xMessageBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes (not messages) the message + * buffer will be able to hold at any one time. When a message is written to + * the message buffer an additional sizeof( size_t ) bytes are also written to + * store the message's length. sizeof( size_t ) is typically 4 bytes on a + * 32-bit architecture, so on most 32-bit architectures a 10 byte message will + * take up 14 bytes of message buffer space. + * + * @param pxSendCompletedCallback Callback invoked when a send operation to the + * message buffer is complete. If the parameter is NULL or xMessageBufferCreate() + * is called without the parameter, then it will use the default implementation + * provided by sbSEND_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when a receive operation from + * the message buffer is complete. If the parameter is NULL or xMessageBufferCreate() + * is called without the parameter, it will use the default implementation provided + * by sbRECEIVE_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @return If NULL is returned, then the message buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the message buffer data structures and storage area. A non-NULL value being + * returned indicates that the message buffer has been created successfully - + * the returned value should be stored as the handle to the created message + * buffer. + * + * Example use: + * @code{c} + * + * void vAFunction( void ) + * { + * MessageBufferHandle_t xMessageBuffer; + * const size_t xMessageBufferSizeBytes = 100; + * + * // Create a message buffer that can hold 100 bytes. The memory used to hold + * // both the message buffer structure and the messages themselves is allocated + * // dynamically. Each message added to the buffer consumes an additional 4 + * // bytes which are used to hold the length of the message. + * xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes ); + * + * if( xMessageBuffer == NULL ) + * { + * // There was not enough heap memory space available to create the + * // message buffer. + * } + * else + * { + * // The message buffer was created successfully and can now be used. + * } + * + * @endcode + * \defgroup xMessageBufferCreate xMessageBufferCreate + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreate( xBufferSizeBytes ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, pdTRUE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * message_buffer.h + * + * @code{c} + * MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, + * uint8_t *pucMessageBufferStorageArea, + * StaticMessageBuffer_t *pxStaticMessageBuffer ); + * @endcode + * Creates a new message buffer using statically allocated memory. See + * xMessageBufferCreate() for a version that uses dynamically allocated memory. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucMessageBufferStorageArea parameter. When a message is written to the + * message buffer an additional sizeof( size_t ) bytes are also written to store + * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so on most 32-bit architecture a 10 byte message will take up + * 14 bytes of message buffer space. The maximum number of bytes that can be + * stored in the message buffer is actually (xBufferSizeBytes - 1). + * + * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes big. This is the array to which messages are + * copied when they are written to the message buffer. + * + * @param pxStaticMessageBuffer Must point to a variable of type + * StaticMessageBuffer_t, which will be used to hold the message buffer's data + * structure. + * + * @param pxSendCompletedCallback Callback invoked when a new message is sent to the message buffer. + * If the parameter is NULL or xMessageBufferCreate() is called without the parameter, then it will use the default + * implementation provided by sbSEND_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when a message is read from a + * message buffer. If the parameter is NULL or xMessageBufferCreate() is called without the parameter, it will + * use the default implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @return If the message buffer is created successfully then a handle to the + * created message buffer is returned. If either pucMessageBufferStorageArea or + * pxStaticmessageBuffer are NULL then NULL is returned. + * + * Example use: + * @code{c} + * + * // Used to dimension the array used to hold the messages. The available space + * // will actually be one less than this, so 999. + #define STORAGE_SIZE_BYTES 1000 + * + * // Defines the memory that will actually hold the messages within the message + * // buffer. + * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; + * + * // The variable used to hold the message buffer structure. + * StaticMessageBuffer_t xMessageBufferStruct; + * + * void MyFunction( void ) + * { + * MessageBufferHandle_t xMessageBuffer; + * + * xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStorageBuffer ), + * ucStorageBuffer, + * &xMessageBufferStruct ); + * + * // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer + * // parameters were NULL, xMessageBuffer will not be NULL, and can be used to + * // reference the created message buffer in other message buffer API calls. + * + * // Other code that uses the message buffer can go here. + * } + * + * @endcode + * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, pdTRUE, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * message_buffer.h + * + * @code{c} + * BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer, + * uint8_t ** ppucMessageBufferStorageArea, + * StaticMessageBuffer_t ** ppxStaticMessageBuffer ); + * @endcode + * + * Retrieve pointers to a statically created message buffer's data structure + * buffer and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xMessageBuffer The message buffer for which to retrieve the buffers. + * + * @param ppucMessageBufferStorageArea Used to return a pointer to the + * message buffer's storage area buffer. + * + * @param ppxStaticMessageBuffer Used to return a pointer to the message + * buffer's data structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.. + * + * \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers + * \ingroup MessageBufferManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \ + xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * message_buffer.h + * + * @code{c} + * size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer, + * const void *pvTxData, + * size_t xDataLengthBytes, + * TickType_t xTicksToWait ); + * @endcode + * + * Sends a discrete message to the message buffer. The message can be any + * length that fits within the buffer's free space, and is copied into the + * buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferSend() to write to a message buffer from a task. Use + * xMessageBufferSendFromISR() to write to a message buffer from an interrupt + * service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer to which a message is + * being sent. + * + * @param pvTxData A pointer to the message that is to be copied into the + * message buffer. + * + * @param xDataLengthBytes The length of the message. That is, the number of + * bytes to copy from pvTxData into the message buffer. When a message is + * written to the message buffer an additional sizeof( size_t ) bytes are also + * written to store the message's length. sizeof( size_t ) is typically 4 bytes + * on a 32-bit architecture, so on most 32-bit architecture setting + * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24 + * bytes (20 bytes of message data and 4 bytes to hold the message length). + * + * @param xTicksToWait The maximum amount of time the calling task should remain + * in the Blocked state to wait for enough space to become available in the + * message buffer, should the message buffer have insufficient space when + * xMessageBufferSend() is called. The calling task will never block if + * xTicksToWait is zero. The block time is specified in tick periods, so the + * absolute time it represents is dependent on the tick frequency. The macro + * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into + * a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will cause + * the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The number of bytes written to the message buffer. If the call to + * xMessageBufferSend() times out before there was enough space to write the + * message into the message buffer then zero is returned. If the call did not + * time out then xDataLengthBytes is returned. + * + * Example use: + * @code{c} + * void vAFunction( MessageBufferHandle_t xMessageBuffer ) + * { + * size_t xBytesSent; + * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; + * char *pcStringToSend = "String to send"; + * const TickType_t x100ms = pdMS_TO_TICKS( 100 ); + * + * // Send an array to the message buffer, blocking for a maximum of 100ms to + * // wait for enough space to be available in the message buffer. + * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); + * + * if( xBytesSent != sizeof( ucArrayToSend ) ) + * { + * // The call to xMessageBufferSend() times out before there was enough + * // space in the buffer for the data to be written. + * } + * + * // Send the string to the message buffer. Return immediately if there is + * // not enough space in the buffer. + * xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); + * + * if( xBytesSent != strlen( pcStringToSend ) ) + * { + * // The string could not be added to the message buffer because there was + * // not enough free space in the buffer. + * } + * } + * @endcode + * \defgroup xMessageBufferSend xMessageBufferSend + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) \ + xStreamBufferSend( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( xTicksToWait ) ) + +/** + * message_buffer.h + * + * @code{c} + * size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer, + * const void *pvTxData, + * size_t xDataLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * Interrupt safe version of the API function that sends a discrete message to + * the message buffer. The message can be any length that fits within the + * buffer's free space, and is copied into the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferSend() to write to a message buffer from a task. Use + * xMessageBufferSendFromISR() to write to a message buffer from an interrupt + * service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer to which a message is + * being sent. + * + * @param pvTxData A pointer to the message that is to be copied into the + * message buffer. + * + * @param xDataLengthBytes The length of the message. That is, the number of + * bytes to copy from pvTxData into the message buffer. When a message is + * written to the message buffer an additional sizeof( size_t ) bytes are also + * written to store the message's length. sizeof( size_t ) is typically 4 bytes + * on a 32-bit architecture, so on most 32-bit architecture setting + * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24 + * bytes (20 bytes of message data and 4 bytes to hold the message length). + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for data. Calling + * xMessageBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xMessageBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the code example below for an example. + * + * @return The number of bytes actually written to the message buffer. If the + * message buffer didn't have enough free space for the message to be stored + * then 0 is returned, otherwise xDataLengthBytes is returned. + * + * Example use: + * @code{c} + * // A message buffer that has already been created. + * MessageBufferHandle_t xMessageBuffer; + * + * void vAnInterruptServiceRoutine( void ) + * { + * size_t xBytesSent; + * char *pcStringToSend = "String to send"; + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. + * + * // Attempt to send the string to the message buffer. + * xBytesSent = xMessageBufferSendFromISR( xMessageBuffer, + * ( void * ) pcStringToSend, + * strlen( pcStringToSend ), + * &xHigherPriorityTaskWoken ); + * + * if( xBytesSent != strlen( pcStringToSend ) ) + * { + * // The string could not be added to the message buffer because there was + * // not enough free space in the buffer. + * } + * + * // If xHigherPriorityTaskWoken was set to pdTRUE inside + * // xMessageBufferSendFromISR() then a task that has a priority above the + * // priority of the currently executing task was unblocked and a context + * // switch should be performed to ensure the ISR returns to the unblocked + * // task. In most FreeRTOS ports this is done by simply passing + * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the + * // variables value, and perform the context switch if necessary. Check the + * // documentation for the port in use for port specific instructions. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * @endcode + * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) \ + xStreamBufferSendFromISR( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( pxHigherPriorityTaskWoken ) ) + +/** + * message_buffer.h + * + * @code{c} + * size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, + * void *pvRxData, + * size_t xBufferLengthBytes, + * TickType_t xTicksToWait ); + * @endcode + * + * Receives a discrete message from a message buffer. Messages can be of + * variable length and are copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for a message, should the message buffer be empty. + * xMessageBufferReceive() will return immediately if xTicksToWait is zero and + * the message buffer is empty. The block time is specified in tick periods, so + * the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. If xMessageBufferReceive() times out before a message became available + * then zero is returned. If the length of the message is greater than + * xBufferLengthBytes then the message will be left in the message buffer and + * zero is returned. + * + * Example use: + * @code{c} + * void vAFunction( MessageBuffer_t xMessageBuffer ) + * { + * uint8_t ucRxData[ 20 ]; + * size_t xReceivedBytes; + * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); + * + * // Receive the next message from the message buffer. Wait in the Blocked + * // state (so not using any CPU processing time) for a maximum of 100ms for + * // a message to become available. + * xReceivedBytes = xMessageBufferReceive( xMessageBuffer, + * ( void * ) ucRxData, + * sizeof( ucRxData ), + * xBlockTime ); + * + * if( xReceivedBytes > 0 ) + * { + * // A ucRxData contains a message that is xReceivedBytes long. Process + * // the message here.... + * } + * } + * @endcode + * \defgroup xMessageBufferReceive xMessageBufferReceive + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) \ + xStreamBufferReceive( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( xTicksToWait ) ) + + +/** + * message_buffer.h + * + * @code{c} + * size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer, + * void *pvRxData, + * size_t xBufferLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * An interrupt safe version of the API function that receives a discrete + * message from a message buffer. Messages can be of variable length and are + * copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for space to become available. Calling + * xMessageBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. + * + * Example use: + * @code{c} + * // A message buffer that has already been created. + * MessageBuffer_t xMessageBuffer; + * + * void vAnInterruptServiceRoutine( void ) + * { + * uint8_t ucRxData[ 20 ]; + * size_t xReceivedBytes; + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. + * + * // Receive the next message from the message buffer. + * xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer, + * ( void * ) ucRxData, + * sizeof( ucRxData ), + * &xHigherPriorityTaskWoken ); + * + * if( xReceivedBytes > 0 ) + * { + * // A ucRxData contains a message that is xReceivedBytes long. Process + * // the message here.... + * } + * + * // If xHigherPriorityTaskWoken was set to pdTRUE inside + * // xMessageBufferReceiveFromISR() then a task that has a priority above the + * // priority of the currently executing task was unblocked and a context + * // switch should be performed to ensure the ISR returns to the unblocked + * // task. In most FreeRTOS ports this is done by simply passing + * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the + * // variables value, and perform the context switch if necessary. Check the + * // documentation for the port in use for port specific instructions. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * @endcode + * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) \ + xStreamBufferReceiveFromISR( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( pxHigherPriorityTaskWoken ) ) + +/** + * message_buffer.h + * + * @code{c} + * void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * + * Deletes a message buffer that was previously created using a call to + * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message + * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), + * then the allocated memory is freed. + * + * A message buffer handle must not be used after the message buffer has been + * deleted. + * + * @param xMessageBuffer The handle of the message buffer to be deleted. + * + */ +#define vMessageBufferDelete( xMessageBuffer ) \ + vStreamBufferDelete( xMessageBuffer ) + +/** + * message_buffer.h + * @code{c} + * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * + * Tests to see if a message buffer is full. A message buffer is full if it + * cannot accept any more messages, of any size, until space is made available + * by a message being removed from the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is full then + * pdTRUE is returned. Otherwise pdFALSE is returned. + */ +#define xMessageBufferIsFull( xMessageBuffer ) \ + xStreamBufferIsFull( xMessageBuffer ) + +/** + * message_buffer.h + * @code{c} + * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * + * Tests to see if a message buffer is empty (does not contain any messages). + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is empty then + * pdTRUE is returned. Otherwise pdFALSE is returned. + * + */ +#define xMessageBufferIsEmpty( xMessageBuffer ) \ + xStreamBufferIsEmpty( xMessageBuffer ) + +/** + * message_buffer.h + * @code{c} + * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferReset xMessageBufferReset + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReset( xMessageBuffer ) \ + xStreamBufferReset( xMessageBuffer ) + + +/** + * message_buffer.h + * @code{c} + * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * Returns the number of bytes of free space in the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The number of bytes that can be written to the message buffer before + * the message buffer would be full. When a message is written to the message + * buffer an additional sizeof( size_t ) bytes are also written to store the + * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size + * of the largest message that can be written to the message buffer is 6 bytes. + * + * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSpaceAvailable( xMessageBuffer ) \ + xStreamBufferSpacesAvailable( xMessageBuffer ) +#define xMessageBufferSpacesAvailable( xMessageBuffer ) \ + xStreamBufferSpacesAvailable( xMessageBuffer ) /* Corrects typo in original macro name. */ + +/** + * message_buffer.h + * @code{c} + * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ); + * @endcode + * Returns the length (in bytes) of the next message in a message buffer. + * Useful if xMessageBufferReceive() returned 0 because the size of the buffer + * passed into xMessageBufferReceive() was too small to hold the next message. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The length (in bytes) of the next message in the message buffer, or 0 + * if the message buffer is empty. + * + * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes + * \ingroup MessageBufferManagement + */ +#define xMessageBufferNextLengthBytes( xMessageBuffer ) \ + xStreamBufferNextMessageLengthBytes( xMessageBuffer ) PRIVILEGED_FUNCTION; + +/** + * message_buffer.h + * + * @code{c} + * BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xMessageBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferSendCompletedFromISR(). If calling + * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \ + xStreamBufferSendCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) ) + +/** + * message_buffer.h + * + * @code{c} + * BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xMessageBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferReceiveCompletedFromISR(). If calling + * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \ + xStreamBufferReceiveCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) ) + +/* *INDENT-OFF* */ +#if defined( __cplusplus ) + } /* extern "C" */ +#endif +/* *INDENT-ON* */ + +#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h b/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h new file mode 100644 index 0000000..574f1da --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h @@ -0,0 +1,476 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +typedef struct xTaskGenericNotifyParams +{ + TaskHandle_t xTaskToNotify; + UBaseType_t uxIndexToNotify; + uint32_t ulValue; + eNotifyAction eAction; + uint32_t * pulPreviousNotificationValue; +} xTaskGenericNotifyParams_t; + +typedef struct xTaskGenericNotifyWaitParams +{ + UBaseType_t uxIndexToWaitOn; + uint32_t ulBitsToClearOnEntry; + uint32_t ulBitsToClearOnExit; + uint32_t * pulNotificationValue; + TickType_t xTicksToWait; +} xTaskGenericNotifyWaitParams_t; + +typedef struct xTimerGenericCommandParams +{ + TimerHandle_t xTimer; + BaseType_t xCommandID; + TickType_t xOptionalValue; + BaseType_t * pxHigherPriorityTaskWoken; + TickType_t xTicksToWait; +} xTimerGenericCommandParams_t; + +typedef struct xEventGroupWaitBitsParams +{ + EventGroupHandle_t xEventGroup; + EventBits_t uxBitsToWaitFor; + BaseType_t xClearOnExit; + BaseType_t xWaitForAllBits; + TickType_t xTicksToWait; +} xEventGroupWaitBitsParams_t; + +/* MPU versions of task.h API functions. */ +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Task APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; + void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; + void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + void MPU_vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; +void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION; +UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* MPU versions of queue.h API functions. */ +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, + UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Queue APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; + QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + +BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue, + const void * const pvItemToQueue, + BaseType_t * const pxHigherPriorityTaskWoken, + const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue, + void * const pvBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue, + void * const pvBuffer, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* MPU versions of timers.h API functions. */ +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Timer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION; + +/* MPU versions of event_group.h API functions. */ +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL; + void MPU_vEventGroupSetNumber( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL; +#endif /* #if ( configUSE_TRACE_FACILITY == 1 ) */ + +/* Privileged only wrappers for Event Group APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION; + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION; + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + +BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/* MPU versions of message/stream_buffer.h API functions. */ +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +/* Privileged only wrappers for Stream Buffer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +#if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) FREERTOS_SYSTEM_CALL; + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; + +#else /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xStreamBufferType, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + +BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers, + uint8_t * ppucStreamBufferStorageArea, + StaticStreamBuffer_t * ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION; +size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +#endif /* MPU_PROTOTYPES_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_syscall_numbers.h b/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_syscall_numbers.h new file mode 100644 index 0000000..03c3ebd --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_syscall_numbers.h @@ -0,0 +1,106 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef MPU_SYSCALL_NUMBERS_H +#define MPU_SYSCALL_NUMBERS_H + +/* Numbers assigned to various system calls. */ +#define SYSTEM_CALL_xTaskGenericNotify 0 +#define SYSTEM_CALL_xTaskGenericNotifyWait 1 +#define SYSTEM_CALL_xTimerGenericCommand 2 +#define SYSTEM_CALL_xEventGroupWaitBits 3 +#define SYSTEM_CALL_xTaskDelayUntil 4 +#define SYSTEM_CALL_xTaskAbortDelay 5 +#define SYSTEM_CALL_vTaskDelay 6 +#define SYSTEM_CALL_uxTaskPriorityGet 7 +#define SYSTEM_CALL_eTaskGetState 8 +#define SYSTEM_CALL_vTaskGetInfo 9 +#define SYSTEM_CALL_xTaskGetIdleTaskHandle 10 +#define SYSTEM_CALL_vTaskSuspend 11 +#define SYSTEM_CALL_vTaskResume 12 +#define SYSTEM_CALL_xTaskGetTickCount 13 +#define SYSTEM_CALL_uxTaskGetNumberOfTasks 14 +#define SYSTEM_CALL_pcTaskGetName 15 +#define SYSTEM_CALL_ulTaskGetRunTimeCounter 16 +#define SYSTEM_CALL_ulTaskGetRunTimePercent 17 +#define SYSTEM_CALL_ulTaskGetIdleRunTimePercent 18 +#define SYSTEM_CALL_ulTaskGetIdleRunTimeCounter 19 +#define SYSTEM_CALL_vTaskSetApplicationTaskTag 20 +#define SYSTEM_CALL_xTaskGetApplicationTaskTag 21 +#define SYSTEM_CALL_vTaskSetThreadLocalStoragePointer 22 +#define SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer 23 +#define SYSTEM_CALL_uxTaskGetSystemState 24 +#define SYSTEM_CALL_uxTaskGetStackHighWaterMark 25 +#define SYSTEM_CALL_uxTaskGetStackHighWaterMark2 26 +#define SYSTEM_CALL_xTaskGetCurrentTaskHandle 27 +#define SYSTEM_CALL_xTaskGetSchedulerState 28 +#define SYSTEM_CALL_vTaskSetTimeOutState 29 +#define SYSTEM_CALL_xTaskCheckForTimeOut 30 +#define SYSTEM_CALL_ulTaskGenericNotifyTake 31 +#define SYSTEM_CALL_xTaskGenericNotifyStateClear 32 +#define SYSTEM_CALL_ulTaskGenericNotifyValueClear 33 +#define SYSTEM_CALL_xQueueGenericSend 34 +#define SYSTEM_CALL_uxQueueMessagesWaiting 35 +#define SYSTEM_CALL_uxQueueSpacesAvailable 36 +#define SYSTEM_CALL_xQueueReceive 37 +#define SYSTEM_CALL_xQueuePeek 38 +#define SYSTEM_CALL_xQueueSemaphoreTake 39 +#define SYSTEM_CALL_xQueueGetMutexHolder 40 +#define SYSTEM_CALL_xQueueTakeMutexRecursive 41 +#define SYSTEM_CALL_xQueueGiveMutexRecursive 42 +#define SYSTEM_CALL_xQueueSelectFromSet 43 +#define SYSTEM_CALL_xQueueAddToSet 44 +#define SYSTEM_CALL_vQueueAddToRegistry 45 +#define SYSTEM_CALL_vQueueUnregisterQueue 46 +#define SYSTEM_CALL_pcQueueGetName 47 +#define SYSTEM_CALL_pvTimerGetTimerID 48 +#define SYSTEM_CALL_vTimerSetTimerID 49 +#define SYSTEM_CALL_xTimerIsTimerActive 50 +#define SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle 51 +#define SYSTEM_CALL_pcTimerGetName 52 +#define SYSTEM_CALL_vTimerSetReloadMode 53 +#define SYSTEM_CALL_xTimerGetReloadMode 54 +#define SYSTEM_CALL_uxTimerGetReloadMode 55 +#define SYSTEM_CALL_xTimerGetPeriod 56 +#define SYSTEM_CALL_xTimerGetExpiryTime 57 +#define SYSTEM_CALL_xEventGroupClearBits 58 +#define SYSTEM_CALL_xEventGroupSetBits 59 +#define SYSTEM_CALL_xEventGroupSync 60 +#define SYSTEM_CALL_uxEventGroupGetNumber 61 +#define SYSTEM_CALL_vEventGroupSetNumber 62 +#define SYSTEM_CALL_xStreamBufferSend 63 +#define SYSTEM_CALL_xStreamBufferReceive 64 +#define SYSTEM_CALL_xStreamBufferIsFull 65 +#define SYSTEM_CALL_xStreamBufferIsEmpty 66 +#define SYSTEM_CALL_xStreamBufferSpacesAvailable 67 +#define SYSTEM_CALL_xStreamBufferBytesAvailable 68 +#define SYSTEM_CALL_xStreamBufferSetTriggerLevel 69 +#define SYSTEM_CALL_xStreamBufferNextMessageLengthBytes 70 +#define NUM_SYSTEM_CALLS 71 /* Total number of system calls. */ + +#endif /* MPU_SYSCALL_NUMBERS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h b/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h new file mode 100644 index 0000000..e61514f --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h @@ -0,0 +1,297 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but + * only for ports that are using the MPU. */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + +/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + * included from queue.c or task.c to prevent it from having an effect within + * those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + +/* Map standard task.h API functions to the MPU equivalents. */ + #define vTaskDelay MPU_vTaskDelay + #define xTaskDelayUntil MPU_xTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define ulTaskGetIdleRunTimeCounter MPU_ulTaskGetIdleRunTimeCounter + #define ulTaskGetIdleRunTimePercent MPU_ulTaskGetIdleRunTimePercent + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskGenericNotifyWait MPU_xTaskGenericNotifyWait + #define ulTaskGenericNotifyTake MPU_ulTaskGenericNotifyTake + #define xTaskGenericNotifyStateClear MPU_xTaskGenericNotifyStateClear + #define ulTaskGenericNotifyValueClear MPU_ulTaskGenericNotifyValueClear + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define ulTaskGetRunTimeCounter MPU_ulTaskGetRunTimeCounter + #define ulTaskGetRunTimePercent MPU_ulTaskGetRunTimePercent + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Privileged only wrappers for Task APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) + /* These are not needed in v2 because they do not take a task + * handle and therefore, no lookup is needed. Needed in v1 because + * these are available as system calls in v1. */ + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define vTaskList MPU_vTaskList + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskCatchUpTicks MPU_xTaskCatchUpTicks + #define xTaskResumeAll MPU_xTaskResumeAll + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define vTaskDelete MPU_vTaskDelete + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define xTaskGetHandle MPU_xTaskGetHandle + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define xTaskCreateRestrictedStatic MPU_xTaskCreateRestrictedStatic + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define xTaskGetStaticBuffers MPU_xTaskGetStaticBuffers + #define uxTaskPriorityGetFromISR MPU_uxTaskPriorityGetFromISR + #define xTaskResumeFromISR MPU_xTaskResumeFromISR + #define xTaskGetApplicationTaskTagFromISR MPU_xTaskGetApplicationTaskTagFromISR + #define xTaskGenericNotifyFromISR MPU_xTaskGenericNotifyFromISR + #define vTaskGenericNotifyGiveFromISR MPU_vTaskGenericNotifyGiveFromISR + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Map standard queue.h API functions to the MPU equivalents. */ + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueReceive MPU_xQueueReceive + #define xQueuePeek MPU_xQueuePeek + #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif /* #if ( configQUEUE_REGISTRY_SIZE > 0 ) */ + +/* Privileged only wrappers for Queue APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #define vQueueDelete MPU_vQueueDelete + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueGenericReset MPU_xQueueGenericReset + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xQueueGenericGetStaticBuffers MPU_xQueueGenericGetStaticBuffers + #define xQueueGenericSendFromISR MPU_xQueueGenericSendFromISR + #define xQueueGiveFromISR MPU_xQueueGiveFromISR + #define xQueuePeekFromISR MPU_xQueuePeekFromISR + #define xQueueReceiveFromISR MPU_xQueueReceiveFromISR + #define xQueueIsQueueEmptyFromISR MPU_xQueueIsQueueEmptyFromISR + #define xQueueIsQueueFullFromISR MPU_xQueueIsQueueFullFromISR + #define uxQueueMessagesWaitingFromISR MPU_uxQueueMessagesWaitingFromISR + #define xQueueGetMutexHolderFromISR MPU_xQueueGetMutexHolderFromISR + #define xQueueSelectFromSetFromISR MPU_xQueueSelectFromSetFromISR + #endif /* if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Map standard timer.h API functions to the MPU equivalents. */ + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerGenericCommand MPU_xTimerGenericCommand + #define pcTimerGetName MPU_pcTimerGetName + #define vTimerSetReloadMode MPU_vTimerSetReloadMode + #define uxTimerGetReloadMode MPU_uxTimerGetReloadMode + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xTimerGetReloadMode MPU_xTimerGetReloadMode + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Privileged only wrappers for Timer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define xTimerGetStaticBuffer MPU_xTimerGetStaticBuffer + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Map standard event_group.h API functions to the MPU equivalents. */ + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + #define uxEventGroupGetNumber MPU_uxEventGroupGetNumber + #define vEventGroupSetNumber MPU_vEventGroupSetNumber + #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ + +/* Privileged only wrappers for Event Group APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define vEventGroupDelete MPU_vEventGroupDelete + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xEventGroupGetStaticBuffer MPU_xEventGroupGetStaticBuffer + #define xEventGroupClearBitsFromISR MPU_xEventGroupClearBitsFromISR + #define xEventGroupSetBitsFromISR MPU_xEventGroupSetBitsFromISR + #define xEventGroupGetBitsFromISR MPU_xEventGroupGetBitsFromISR + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Map standard message/stream_buffer.h API functions to the MPU + * equivalents. */ + #define xStreamBufferSend MPU_xStreamBufferSend + #define xStreamBufferReceive MPU_xStreamBufferReceive + #define xStreamBufferIsFull MPU_xStreamBufferIsFull + #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty + #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable + #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable + #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel + #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes + +/* Privileged only wrappers for Stream Buffer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ + + #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate + #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + #define vStreamBufferDelete MPU_vStreamBufferDelete + #define xStreamBufferReset MPU_xStreamBufferReset + + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + #define xStreamBufferGetStaticBuffers MPU_xStreamBufferGetStaticBuffers + #define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR + #define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR + #define xStreamBufferSendCompletedFromISR MPU_xStreamBufferSendCompletedFromISR + #define xStreamBufferReceiveCompletedFromISR MPU_xStreamBufferReceiveCompletedFromISR + #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + +/* Remove the privileged function macro, but keep the PRIVILEGED_DATA + * macro so applications can place data in privileged access sections + * (useful when using statically allocated objects). */ + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) + #define FREERTOS_SYSTEM_CALL + + + #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + #define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) ) + #define vRevokeAccessToTask( xTask, xTaskToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) ) + + #define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) ) + #define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) ) + + #define vGrantAccessToQueue( xTask, xQueueToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToGrantAccess ) ) + #define vRevokeAccessToQueue( xTask, xQueueToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToRevokeAccess ) ) + + #define vGrantAccessToQueueSet( xTask, xQueueSetToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToGrantAccess ) ) + #define vRevokeAccessToQueueSet( xTask, xQueueSetToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToRevokeAccess ) ) + + #define vGrantAccessToEventGroup( xTask, xEventGroupToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToGrantAccess ) ) + #define vRevokeAccessToEventGroup( xTask, xEventGroupToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToRevokeAccess ) ) + + #define vGrantAccessToStreamBuffer( xTask, xStreamBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToGrantAccess ) ) + #define vRevokeAccessToStreamBuffer( xTask, xStreamBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToRevokeAccess ) ) + + #define vGrantAccessToMessageBuffer( xTask, xMessageBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToGrantAccess ) ) + #define vRevokeAccessToMessageBuffer( xTask, xMessageBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToRevokeAccess ) ) + + #define vGrantAccessToTimer( xTask, xTimerToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToGrantAccess ) ) + #define vRevokeAccessToTimer( xTask, xTimerToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToRevokeAccess ) ) + + #endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +/* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__( ( section( "privileged_functions" ) ) ) + #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) + #define FREERTOS_SYSTEM_CALL __attribute__( ( section( "freertos_system_calls" ) ) ) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define FREERTOS_SYSTEM_CALL + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/newlib-freertos.h b/Middlewares/Third_Party/FreeRTOS/Source/include/newlib-freertos.h new file mode 100644 index 0000000..b6911c9 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/newlib-freertos.h @@ -0,0 +1,62 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef INC_NEWLIB_FREERTOS_H +#define INC_NEWLIB_FREERTOS_H + +/* Note Newlib support has been included by popular demand, but is not + * used by the FreeRTOS maintainers themselves. FreeRTOS is not + * responsible for resulting newlib operation. User must be familiar with + * newlib and must provide system-wide implementations of the necessary + * stubs. Be warned that (at the time of writing) the current newlib design + * implements a system-wide malloc() that must be provided with locks. + * + * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html + * for additional information. */ + +#include + +#define configUSE_C_RUNTIME_TLS_SUPPORT 1 + +#ifndef configTLS_BLOCK_TYPE + #define configTLS_BLOCK_TYPE struct _reent +#endif + +#ifndef configINIT_TLS_BLOCK + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) ) +#endif + +#ifndef configSET_TLS_BLOCK + #define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) ) +#endif + +#ifndef configDEINIT_TLS_BLOCK + #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) +#endif + +#endif /* INC_NEWLIB_FREERTOS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/picolibc-freertos.h b/Middlewares/Third_Party/FreeRTOS/Source/include/picolibc-freertos.h new file mode 100644 index 0000000..63f6927 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/picolibc-freertos.h @@ -0,0 +1,90 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef INC_PICOLIBC_FREERTOS_H +#define INC_PICOLIBC_FREERTOS_H + +/* Use picolibc TLS support to allocate space for __thread variables, + * initialize them at thread creation and set the TLS context at + * thread switch time. + * + * See the picolibc TLS docs: + * https://github.com/picolibc/picolibc/blob/main/doc/tls.md + * for additional information. */ + +#include + +#define configUSE_C_RUNTIME_TLS_SUPPORT 1 + +#define configTLS_BLOCK_TYPE void * + +#define picolibcTLS_SIZE ( ( portPOINTER_SIZE_TYPE ) _tls_size() ) +#define picolibcSTACK_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) + +#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8 + +/* Picolibc 1.8 and newer have explicit alignment values provided + * by the _tls_align() inline */ + #define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) ( _tls_align() - 1 ) ) +#else + +/* For older Picolibc versions, use the general port alignment value */ + #define picolibcTLS_ALIGNMENT_MASK ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) +#endif + +/* Allocate thread local storage block off the end of the +* stack. The _tls_size() function returns the size (in +* bytes) of the total TLS area used by the application */ +#if ( portSTACK_GROWTH < 0 ) + + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ + do { \ + pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) \ + - picolibcTLS_SIZE ) & ~ \ + configMAX( picolibcSTACK_ALIGNMENT_MASK, \ + picolibcTLS_ALIGNMENT_MASK ) ); \ + xTLSBlock = pxTopOfStack; \ + _init_tls( xTLSBlock ); \ + } while( 0 ) +#else /* portSTACK_GROWTH */ + #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) \ + do { \ + xTLSBlock = ( void * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack + \ + picolibcTLS_ALIGNMENT_MASK ) & ~picolibcTLS_ALIGNMENT_MASK ); \ + pxTopOfStack = ( StackType_t * ) ( ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) + \ + picolibcTLS_SIZE ) + picolibcSTACK_ALIGNMENT_MASK ) & \ + ~picolibcSTACK_ALIGNMENT_MASK ); \ + _init_tls( xTLSBlock ); \ + } while( 0 ) +#endif /* portSTACK_GROWTH */ + +#define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock ) + +#define configDEINIT_TLS_BLOCK( xTLSBlock ) + +#endif /* INC_PICOLIBC_FREERTOS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h b/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h new file mode 100644 index 0000000..ec11f0f --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h @@ -0,0 +1,271 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/*----------------------------------------------------------- +* Portable layer API. Each function must be defined for each port. +*----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a + * pre-processor definition was used to ensure the pre-processor found the correct + * portmacro.h file for the port being used. That scheme was deprecated in favour + * of setting the compiler's include path such that it found the correct + * portmacro.h file - removing the need for the constant and allowing the + * portmacro.h file to be located anywhere in relation to the port being used. + * Purely for reasons of backward compatibility the old method is still valid, but + * to make it clear that new projects should not use it, support for the port + * specific constants has been moved into the deprecated_definitions.h header + * file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h + * did not result in a portmacro.h header file being included - and it should be + * included here. In this case the path to the correct portmacro.h header file + * must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#elif portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#elif portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#elif portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#elif portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#elif portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#else /* if portBYTE_ALIGNMENT == 32 */ + #error "Invalid portBYTE_ALIGNMENT definition" +#endif /* if portBYTE_ALIGNMENT == 32 */ + +#ifndef portUSING_MPU_WRAPPERS + #define portUSING_MPU_WRAPPERS 0 +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifndef portHAS_STACK_OVERFLOW_CHECKING + #define portHAS_STACK_OVERFLOW_CHECKING 0 +#endif + +#ifndef portARCH_NAME + #define portARCH_NAME NULL +#endif + +#ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP + /* Defaults to 0 for backward compatibility. */ + #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION; + #else + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION; + #endif /* if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) */ +#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */ + #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + StackType_t * pxEndOfStack, + TaskFunction_t pxCode, + void * pvParameters ) PRIVILEGED_FUNCTION; + #else + StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) PRIVILEGED_FUNCTION; + #endif +#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */ + +/* Used by heap_5.c to define the start address and size of each memory region + * that together comprise the total FreeRTOS heap space. */ +typedef struct HeapRegion +{ + uint8_t * pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* Used to pass information about the heap out of vPortGetHeapStats(). */ +typedef struct xHeapStats +{ + size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */ + size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ + size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ + size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */ + size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */ + size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */ + size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */ +} HeapStats_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; + +/* + * Returns a HeapStats_t structure filled with information about the current + * heap state. + */ +void vPortGetHeapStats( HeapStats_t * pxHeapStats ); + +/* + * Map to the memory management routines required for the port. + */ +void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void * pvPortCalloc( size_t xNum, + size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void * pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +#if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 ) + void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION; + void vPortFreeStack( void * pv ) PRIVILEGED_FUNCTION; +#else + #define pvPortMallocStack pvPortMalloc + #define vPortFreeStack vPortFree +#endif + +#if ( configUSE_MALLOC_FAILED_HOOK == 1 ) + +/** + * task.h + * @code{c} + * void vApplicationMallocFailedHook( void ) + * @endcode + * + * This hook function is called when allocation failed. + */ + void vApplicationMallocFailedHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ +#endif + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + +/** + * @brief Checks if the calling task is authorized to access the given buffer. + * + * @param pvBuffer The buffer which the calling task wants to access. + * @param ulBufferLength The length of the pvBuffer. + * @param ulAccessRequested The permissions that the calling task wants. + * + * @return pdTRUE if the calling task is authorized to access the buffer, + * pdFALSE otherwise. + */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION; +#endif + +/** + * @brief Checks if the calling task is authorized to access the given kernel object. + * + * @param lInternalIndexOfKernelObject The index of the kernel object in the kernel + * object handle pool. + * + * @return pdTRUE if the calling task is authorized to access the kernel object, + * pdFALSE otherwise. + */ +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION; + +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* PORTABLE_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h b/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h new file mode 100644 index 0000000..4c46333 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h @@ -0,0 +1,131 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (* TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. This macro can be + * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the + * definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS + #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000U ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) +#define pdFALSE_SIGNED ( ( BaseType_t ) 0 ) +#define pdTRUE_SIGNED ( ( BaseType_t ) 1 ) +#define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0 ) +#define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES + #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5a5a5a5a5aULL +#else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS + * itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS + * itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +/* Re-defining endian values for generic naming. */ +#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN +#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN + + +#endif /* PROJDEFS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h b/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h new file mode 100644 index 0000000..836adf5 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h @@ -0,0 +1,1764 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +#include "task.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef struct QueueDefinition * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef struct QueueDefinition * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + * @code{c} + * QueueHandle_t xQueueCreate( + * UBaseType_t uxQueueLength, + * UBaseType_t uxItemSize + * ); + * @endcode + * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * }; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1, xQueue2; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); + * if( xQueue1 == 0 ) + * { + * // Queue was not created and must not be used. + * } + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * if( xQueue2 == 0 ) + * { + * // Queue was not created and must not be used. + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + * @code{c} + * QueueHandle_t xQueueCreateStatic( + * UBaseType_t uxQueueLength, + * UBaseType_t uxItemSize, + * uint8_t *pucQueueStorage, + * StaticQueue_t *pxQueueBuffer + * ); + * @endcode + * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * https://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorage If uxItemSize is not zero then + * pucQueueStorage must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorage can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * }; + * + #define QUEUE_LENGTH 10 + #define ITEM_SIZE sizeof( uint32_t ) + * + * // xQueueBuffer will hold the queue structure. + * StaticQueue_t xQueueBuffer; + * + * // ucQueueStorage will hold the items posted to the queue. Must be at least + * // [(queue length) * ( queue item size)] bytes long. + * uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ]; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold. + * ITEM_SIZE // The size of each item in the queue + * &( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue. + * &xQueueBuffer ); // The buffer that will hold the queue structure. + * + * // The queue is guaranteed to be created successfully as no dynamic memory + * // allocation is used. Therefore xQueue1 is now a handle to a valid queue. + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + * @code{c} + * BaseType_t xQueueGetStaticBuffers( QueueHandle_t xQueue, + * uint8_t ** ppucQueueStorage, + * StaticQueue_t ** ppxStaticQueue ); + * @endcode + * + * Retrieve pointers to a statically created queue's data structure buffer + * and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xQueue The queue for which to retrieve the buffers. + * + * @param ppucQueueStorage Used to return a pointer to the queue's storage + * area buffer. + * + * @param ppxStaticQueue Used to return a pointer to the queue's data + * structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xQueueGetStaticBuffers xQueueGetStaticBuffers + * \ingroup QueueManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueGetStaticBuffers( xQueue, ppucQueueStorage, ppxStaticQueue ) xQueueGenericGetStaticBuffers( ( xQueue ), ( ppucQueueStorage ), ( ppxStaticQueue ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + * @code{c} + * BaseType_t xQueueSendToToFront( + * QueueHandle_t xQueue, + * const void *pvItemToQueue, + * TickType_t xTicksToWait + * ); + * @endcode + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * uint32_t ulVar = 10UL; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1, xQueue2; + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * + * // ... + * + * if( xQueue1 != 0 ) + * { + * // Send an uint32_t. Wait for 10 ticks for space to become + * // available if necessary. + * if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS ) + * { + * // Failed to post the message, even after 10 ticks. + * } + * } + * + * if( xQueue2 != 0 ) + * { + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) \ + xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + * @code{c} + * BaseType_t xQueueSendToBack( + * QueueHandle_t xQueue, + * const void *pvItemToQueue, + * TickType_t xTicksToWait + * ); + * @endcode + * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * uint32_t ulVar = 10UL; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1, xQueue2; + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * + * // ... + * + * if( xQueue1 != 0 ) + * { + * // Send an uint32_t. Wait for 10 ticks for space to become + * // available if necessary. + * if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS ) + * { + * // Failed to post the message, even after 10 ticks. + * } + * } + * + * if( xQueue2 != 0 ) + * { + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) \ + xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + * @code{c} + * BaseType_t xQueueSend( + * QueueHandle_t xQueue, + * const void * pvItemToQueue, + * TickType_t xTicksToWait + * ); + * @endcode + * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * uint32_t ulVar = 10UL; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1, xQueue2; + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * + * // ... + * + * if( xQueue1 != 0 ) + * { + * // Send an uint32_t. Wait for 10 ticks for space to become + * // available if necessary. + * if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS ) + * { + * // Failed to post the message, even after 10 ticks. + * } + * } + * + * if( xQueue2 != 0 ) + * { + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) \ + xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + * @code{c} + * BaseType_t xQueueOverwrite( + * QueueHandle_t xQueue, + * const void * pvItemToQueue + * ); + * @endcode + * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: + * @code{c} + * + * void vFunction( void *pvParameters ) + * { + * QueueHandle_t xQueue; + * uint32_t ulVarToSend, ulValReceived; + * + * // Create a queue to hold one uint32_t value. It is strongly + * // recommended *not* to use xQueueOverwrite() on queues that can + * // contain more than one value, and doing so will trigger an assertion + * // if configASSERT() is defined. + * xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); + * + * // Write the value 10 to the queue using xQueueOverwrite(). + * ulVarToSend = 10; + * xQueueOverwrite( xQueue, &ulVarToSend ); + * + * // Peeking the queue should now return 10, but leave the value 10 in + * // the queue. A block time of zero is used as it is known that the + * // queue holds a value. + * ulValReceived = 0; + * xQueuePeek( xQueue, &ulValReceived, 0 ); + * + * if( ulValReceived != 10 ) + * { + * // Error unless the item was removed by a different task. + * } + * + * // The queue is still full. Use xQueueOverwrite() to overwrite the + * // value held in the queue with 100. + * ulVarToSend = 100; + * xQueueOverwrite( xQueue, &ulVarToSend ); + * + * // This time read from the queue, leaving the queue empty once more. + * // A block time of 0 is used again. + * xQueueReceive( xQueue, &ulValReceived, 0 ); + * + * // The value read should be the last value written, even though the + * // queue was already full when the value was written. + * if( ulValReceived != 100 ) + * { + * // Error! + * } + * + * // ... + * } + * @endcode + * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) \ + xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + * @code{c} + * BaseType_t xQueueGenericSend( + * QueueHandle_t xQueue, + * const void * pvItemToQueue, + * TickType_t xTicksToWait + * BaseType_t xCopyPosition + * ); + * @endcode + * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * uint32_t ulVar = 10UL; + * + * void vATask( void *pvParameters ) + * { + * QueueHandle_t xQueue1, xQueue2; + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 uint32_t values. + * xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) ); + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * + * // ... + * + * if( xQueue1 != 0 ) + * { + * // Send an uint32_t. Wait for 10 ticks for space to become + * // available if necessary. + * if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS ) + * { + * // Failed to post the message, even after 10 ticks. + * } + * } + * + * if( xQueue2 != 0 ) + * { + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK ); + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * BaseType_t xQueuePeek( + * QueueHandle_t xQueue, + * void * const pvBuffer, + * TickType_t xTicksToWait + * ); + * @endcode + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * QueueHandle_t xQueue; + * + * // Task to create a queue and post a value. + * void vATask( void *pvParameters ) + * { + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * if( xQueue == 0 ) + * { + * // Failed to create the queue. + * } + * + * // ... + * + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * + * // ... Rest of task code. + * } + * + * // Task to peek the data from the queue. + * void vADifferentTask( void *pvParameters ) + * { + * struct AMessage *pxRxedMessage; + * + * if( xQueue != 0 ) + * { + * // Peek a message on the created queue. Block for 10 ticks if a + * // message is not immediately available. + * if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) ) + * { + * // pcRxedMessage now points to the struct AMessage variable posted + * // by vATask, but the item still remains on the queue. + * } + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueuePeek xQueuePeek + * \ingroup QueueManagement + */ +BaseType_t xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * BaseType_t xQueuePeekFromISR( + * QueueHandle_t xQueue, + * void *pvBuffer, + * ); + * @endcode + * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, + void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * BaseType_t xQueueReceive( + * QueueHandle_t xQueue, + * void *pvBuffer, + * TickType_t xTicksToWait + * ); + * @endcode + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: + * @code{c} + * struct AMessage + * { + * char ucMessageID; + * char ucData[ 20 ]; + * } xMessage; + * + * QueueHandle_t xQueue; + * + * // Task to create a queue and post a value. + * void vATask( void *pvParameters ) + * { + * struct AMessage *pxMessage; + * + * // Create a queue capable of containing 10 pointers to AMessage structures. + * // These should be passed by pointer as they contain a lot of data. + * xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) ); + * if( xQueue == 0 ) + * { + * // Failed to create the queue. + * } + * + * // ... + * + * // Send a pointer to a struct AMessage object. Don't block if the + * // queue is already full. + * pxMessage = & xMessage; + * xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 ); + * + * // ... Rest of task code. + * } + * + * // Task to receive from the queue. + * void vADifferentTask( void *pvParameters ) + * { + * struct AMessage *pxRxedMessage; + * + * if( xQueue != 0 ) + * { + * // Receive a message on the created queue. Block for 10 ticks if a + * // message is not immediately available. + * if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) ) + * { + * // pcRxedMessage now points to the struct AMessage variable posted + * // by vATask. + * } + * } + * + * // ... Rest of task code. + * } + * @endcode + * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ); + * @endcode + * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ); + * @endcode + * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * void vQueueDelete( QueueHandle_t xQueue ); + * @endcode + * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * BaseType_t xQueueSendToFrontFromISR( + * QueueHandle_t xQueue, + * const void *pvItemToQueue, + * BaseType_t *pxHigherPriorityTaskWoken + * ); + * @endcode + * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): + * @code{c} + * void vBufferISR( void ) + * { + * char cIn; + * BaseType_t xHigherPriorityTaskWoken; + * + * // We have not woken a task at the start of the ISR. + * xHigherPriorityTaskWoken = pdFALSE; + * + * // Loop until the buffer is empty. + * do + * { + * // Obtain a byte from the buffer. + * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); + * + * // Post the byte. + * xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); + * + * } while( portINPUT_BYTE( BUFFER_COUNT ) ); + * + * // Now the buffer is empty we can switch context if necessary. + * if( xHigherPriorityTaskWoken ) + * { + * taskYIELD (); + * } + * } + * @endcode + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ + xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + * @code{c} + * BaseType_t xQueueSendToBackFromISR( + * QueueHandle_t xQueue, + * const void *pvItemToQueue, + * BaseType_t *pxHigherPriorityTaskWoken + * ); + * @endcode + * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): + * @code{c} + * void vBufferISR( void ) + * { + * char cIn; + * BaseType_t xHigherPriorityTaskWoken; + * + * // We have not woken a task at the start of the ISR. + * xHigherPriorityTaskWoken = pdFALSE; + * + * // Loop until the buffer is empty. + * do + * { + * // Obtain a byte from the buffer. + * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); + * + * // Post the byte. + * xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); + * + * } while( portINPUT_BYTE( BUFFER_COUNT ) ); + * + * // Now the buffer is empty we can switch context if necessary. + * if( xHigherPriorityTaskWoken ) + * { + * taskYIELD (); + * } + * } + * @endcode + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ + xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + * @code{c} + * BaseType_t xQueueOverwriteFromISR( + * QueueHandle_t xQueue, + * const void * pvItemToQueue, + * BaseType_t *pxHigherPriorityTaskWoken + * ); + * @endcode + * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: + * @code{c} + * + * QueueHandle_t xQueue; + * + * void vFunction( void *pvParameters ) + * { + * // Create a queue to hold one uint32_t value. It is strongly + * // recommended *not* to use xQueueOverwriteFromISR() on queues that can + * // contain more than one value, and doing so will trigger an assertion + * // if configASSERT() is defined. + * xQueue = xQueueCreate( 1, sizeof( uint32_t ) ); + * } + * + * void vAnInterruptHandler( void ) + * { + * // xHigherPriorityTaskWoken must be set to pdFALSE before it is used. + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * uint32_t ulVarToSend, ulValReceived; + * + * // Write the value 10 to the queue using xQueueOverwriteFromISR(). + * ulVarToSend = 10; + * xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken ); + * + * // The queue is full, but calling xQueueOverwriteFromISR() again will still + * // pass because the value held in the queue will be overwritten with the + * // new value. + * ulVarToSend = 100; + * xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken ); + * + * // Reading from the queue will now return 100. + * + * // ... + * + * if( xHigherPrioritytaskWoken == pdTRUE ) + * { + * // Writing to the queue caused a task to unblock and the unblocked task + * // has a priority higher than or equal to the priority of the currently + * // executing task (the task this interrupt interrupted). Perform a context + * // switch so this interrupt returns directly to the unblocked task. + * portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port. + * } + * } + * @endcode + * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ + xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + * @code{c} + * BaseType_t xQueueSendFromISR( + * QueueHandle_t xQueue, + * const void *pvItemToQueue, + * BaseType_t *pxHigherPriorityTaskWoken + * ); + * @endcode + * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): + * @code{c} + * void vBufferISR( void ) + * { + * char cIn; + * BaseType_t xHigherPriorityTaskWoken; + * + * // We have not woken a task at the start of the ISR. + * xHigherPriorityTaskWoken = pdFALSE; + * + * // Loop until the buffer is empty. + * do + * { + * // Obtain a byte from the buffer. + * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); + * + * // Post the byte. + * xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); + * + * } while( portINPUT_BYTE( BUFFER_COUNT ) ); + * + * // Now the buffer is empty we can switch context if necessary. + * if( xHigherPriorityTaskWoken ) + * { + * // Actual macro used here is port specific. + * portYIELD_FROM_ISR (); + * } + * } + * @endcode + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \ + xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + * @code{c} + * BaseType_t xQueueGenericSendFromISR( + * QueueHandle_t xQueue, + * const void *pvItemToQueue, + * BaseType_t *pxHigherPriorityTaskWoken, + * BaseType_t xCopyPosition + * ); + * @endcode + * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): + * @code{c} + * void vBufferISR( void ) + * { + * char cIn; + * BaseType_t xHigherPriorityTaskWokenByPost; + * + * // We have not woken a task at the start of the ISR. + * xHigherPriorityTaskWokenByPost = pdFALSE; + * + * // Loop until the buffer is empty. + * do + * { + * // Obtain a byte from the buffer. + * cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); + * + * // Post each byte. + * xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK ); + * + * } while( portINPUT_BYTE( BUFFER_COUNT ) ); + * + * // Now the buffer is empty we can switch context if necessary. Note that the + * // name of the yield function required is port specific. + * if( xHigherPriorityTaskWokenByPost ) + * { + * portYIELD_FROM_ISR(); + * } + * } + * @endcode + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, + const void * const pvItemToQueue, + BaseType_t * const pxHigherPriorityTaskWoken, + const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * queue. h + * @code{c} + * BaseType_t xQueueReceiveFromISR( + * QueueHandle_t xQueue, + * void *pvBuffer, + * BaseType_t *pxTaskWoken + * ); + * @endcode + * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxHigherPriorityTaskWoken A task may be blocked waiting for space to + * become available on the queue. If xQueueReceiveFromISR causes such a task + * to unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: + * @code{c} + * + * QueueHandle_t xQueue; + * + * // Function to create a queue and post some values. + * void vAFunction( void *pvParameters ) + * { + * char cValueToPost; + * const TickType_t xTicksToWait = ( TickType_t )0xff; + * + * // Create a queue capable of containing 10 characters. + * xQueue = xQueueCreate( 10, sizeof( char ) ); + * if( xQueue == 0 ) + * { + * // Failed to create the queue. + * } + * + * // ... + * + * // Post some characters that will be used within an ISR. If the queue + * // is full then this task will block for xTicksToWait ticks. + * cValueToPost = 'a'; + * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); + * cValueToPost = 'b'; + * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); + * + * // ... keep posting characters ... this task may block when the queue + * // becomes full. + * + * cValueToPost = 'c'; + * xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait ); + * } + * + * // ISR that outputs all the characters received on the queue. + * void vISR_Routine( void ) + * { + * BaseType_t xTaskWokenByReceive = pdFALSE; + * char cRxedChar; + * + * while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) ) + * { + * // A character was received. Output the character now. + * vOutputCharacter( cRxedChar ); + * + * // If removing the character from the queue woke the task that was + * // posting onto the queue xTaskWokenByReceive will have been set to + * // pdTRUE. No matter how many times this loop iterates only one + * // task will be woken. + * } + * + * if( xTaskWokenByReceive != ( char ) pdFALSE; + * { + * taskYIELD (); + * } + * } + * @endcode + * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, + void * const pvBuffer, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from within an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, + const void * pvItemToQueue, + BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, + void * pvBuffer, + BaseType_t * pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, + const void * pvItemToQueue, + TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, + void * pvBuffer, + TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( ( xQueue ), pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not affect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * If vQueueAddToRegistry is called more than once with the same xQueue + * parameter, the registry will store the pcQueueName parameter from the + * most recent call to vQueueAddToRegistry. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcQueueName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + const char * pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to create a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to create a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to retrieve the buffers of statically + * created queues. This is called by other functions and macros that retrieve + * the buffers of other statically created RTOS objects that use the queue + * structure as their base. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on https://www.FreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, + TickType_t xTicksToWait, + const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, + UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueItemSize( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueLength( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* QUEUE_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h b/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h new file mode 100644 index 0000000..46ac85a --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h @@ -0,0 +1,1214 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + * @code{c} + * vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * https://www.FreeRTOS.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore = NULL; + * + * void vATask( void * pvParameters ) + * { + * // Semaphore cannot be used before a call to vSemaphoreCreateBinary (). + * // This is a macro so pass the variable in directly. + * vSemaphoreCreateBinary( xSemaphore ); + * + * if( xSemaphore != NULL ) + * { + * // The semaphore was created successfully. + * // The semaphore can now be used. + * } + * } + * @endcode + * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + do { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } while( 0 ) +#endif + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateBinary( void ); + * @endcode + * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * https://www.FreeRTOS.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore = NULL; + * + * void vATask( void * pvParameters ) + * { + * // Semaphore cannot be used before a call to xSemaphoreCreateBinary(). + * // This is a macro so pass the variable in directly. + * xSemaphore = xSemaphoreCreateBinary(); + * + * if( xSemaphore != NULL ) + * { + * // The semaphore was created successfully. + * // The semaphore can now be used. + * } + * } + * @endcode + * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer ); + * @endcode + * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * https://www.FreeRTOS.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore = NULL; + * StaticSemaphore_t xSemaphoreBuffer; + * + * void vATask( void * pvParameters ) + * { + * // Semaphore cannot be used before a call to xSemaphoreCreateBinary(). + * // The semaphore's data structures will be placed in the xSemaphoreBuffer + * // variable, the address of which is passed into the function. The + * // function's parameter is not NULL, so the function will not attempt any + * // dynamic memory allocation, and therefore the function will not return + * // return NULL. + * xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer ); + * + * // Rest of task code goes here. + * } + * @endcode + * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, ( pxStaticSemaphore ), queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + * @code{c} + * xSemaphoreTake( + * SemaphoreHandle_t xSemaphore, + * TickType_t xBlockTime + * ); + * @endcode + * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore = NULL; + * + * // A task that creates a semaphore. + * void vATask( void * pvParameters ) + * { + * // Create the semaphore to guard a shared resource. + * xSemaphore = xSemaphoreCreateBinary(); + * } + * + * // A task that uses the semaphore. + * void vAnotherTask( void * pvParameters ) + * { + * // ... Do other things. + * + * if( xSemaphore != NULL ) + * { + * // See if we can obtain the semaphore. If the semaphore is not available + * // wait 10 ticks to see if it becomes free. + * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) + * { + * // We were able to obtain the semaphore and can now access the + * // shared resource. + * + * // ... + * + * // We have finished accessing the shared resource. Release the + * // semaphore. + * xSemaphoreGive( xSemaphore ); + * } + * else + * { + * // We could not obtain the semaphore and can therefore not access + * // the shared resource safely. + * } + * } + * } + * @endcode + * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) + +/** + * semphr. h + * @code{c} + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ); + * @endcode + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xMutex = NULL; + * + * // A task that creates a mutex. + * void vATask( void * pvParameters ) + * { + * // Create the mutex to guard a shared resource. + * xMutex = xSemaphoreCreateRecursiveMutex(); + * } + * + * // A task that uses the mutex. + * void vAnotherTask( void * pvParameters ) + * { + * // ... Do other things. + * + * if( xMutex != NULL ) + * { + * // See if we can obtain the mutex. If the mutex is not available + * // wait 10 ticks to see if it becomes free. + * if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) + * { + * // We were able to obtain the mutex and can now access the + * // shared resource. + * + * // ... + * // For some reason due to the nature of the code further calls to + * // xSemaphoreTakeRecursive() are made on the same mutex. In real + * // code these would not be just sequential calls as this would make + * // no sense. Instead the calls are likely to be buried inside + * // a more complex call structure. + * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); + * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); + * + * // The mutex has now been 'taken' three times, so will not be + * // available to another task until it has also been given back + * // three times. Again it is unlikely that real code would have + * // these calls sequentially, but instead buried in a more complex + * // call structure. This is just for illustrative purposes. + * xSemaphoreGiveRecursive( xMutex ); + * xSemaphoreGiveRecursive( xMutex ); + * xSemaphoreGiveRecursive( xMutex ); + * + * // Now the mutex can be taken by other tasks. + * } + * else + * { + * // We could not obtain the mutex and can therefore not access + * // the shared resource safely. + * } + * } + * } + * @endcode + * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + * @code{c} + * xSemaphoreGive( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore = NULL; + * + * void vATask( void * pvParameters ) + * { + * // Create the semaphore to guard a shared resource. + * xSemaphore = vSemaphoreCreateBinary(); + * + * if( xSemaphore != NULL ) + * { + * if( xSemaphoreGive( xSemaphore ) != pdTRUE ) + * { + * // We would expect this call to fail because we cannot give + * // a semaphore without first "taking" it! + * } + * + * // Obtain the semaphore - don't block if the semaphore is not + * // immediately available. + * if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) ) + * { + * // We now have the semaphore and can access the shared resource. + * + * // ... + * + * // We have finished accessing the shared resource so can free the + * // semaphore. + * if( xSemaphoreGive( xSemaphore ) != pdTRUE ) + * { + * // We would not expect this call to fail because we must have + * // obtained the semaphore to get here. + * } + * } + * } + * } + * @endcode + * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + * @code{c} + * xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex ); + * @endcode + * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xMutex = NULL; + * + * // A task that creates a mutex. + * void vATask( void * pvParameters ) + * { + * // Create the mutex to guard a shared resource. + * xMutex = xSemaphoreCreateRecursiveMutex(); + * } + * + * // A task that uses the mutex. + * void vAnotherTask( void * pvParameters ) + * { + * // ... Do other things. + * + * if( xMutex != NULL ) + * { + * // See if we can obtain the mutex. If the mutex is not available + * // wait 10 ticks to see if it becomes free. + * if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE ) + * { + * // We were able to obtain the mutex and can now access the + * // shared resource. + * + * // ... + * // For some reason due to the nature of the code further calls to + * // xSemaphoreTakeRecursive() are made on the same mutex. In real + * // code these would not be just sequential calls as this would make + * // no sense. Instead the calls are likely to be buried inside + * // a more complex call structure. + * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); + * xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); + * + * // The mutex has now been 'taken' three times, so will not be + * // available to another task until it has also been given back + * // three times. Again it is unlikely that real code would have + * // these calls sequentially, it would be more likely that the calls + * // to xSemaphoreGiveRecursive() would be called as a call stack + * // unwound. This is just for demonstrative purposes. + * xSemaphoreGiveRecursive( xMutex ); + * xSemaphoreGiveRecursive( xMutex ); + * xSemaphoreGiveRecursive( xMutex ); + * + * // Now the mutex can be taken by other tasks. + * } + * else + * { + * // We could not obtain the mutex and can therefore not access + * // the shared resource safely. + * } + * } + * } + * @endcode + * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + * @code{c} + * xSemaphoreGiveFromISR( + * SemaphoreHandle_t xSemaphore, + * BaseType_t *pxHigherPriorityTaskWoken + * ); + * @endcode + * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: + * @code{c} + \#define LONG_TIME 0xffff + \#define TICKS_TO_WAIT 10 + * SemaphoreHandle_t xSemaphore = NULL; + * + * // Repetitive task. + * void vATask( void * pvParameters ) + * { + * for( ;; ) + * { + * // We want this task to run every 10 ticks of a timer. The semaphore + * // was created before this task was started. + * + * // Block waiting for the semaphore to become available. + * if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) + * { + * // It is time to execute. + * + * // ... + * + * // We have finished our task. Return to the top of the loop where + * // we will block on the semaphore until it is time to execute + * // again. Note when using the semaphore for synchronisation with an + * // ISR in this manner there is no need to 'give' the semaphore back. + * } + * } + * } + * + * // Timer ISR + * void vTimerISR( void * pvParameters ) + * { + * static uint8_t ucLocalTickCount = 0; + * static BaseType_t xHigherPriorityTaskWoken; + * + * // A timer tick has occurred. + * + * // ... Do other time functions. + * + * // Is it time for vATask () to run? + * xHigherPriorityTaskWoken = pdFALSE; + * ucLocalTickCount++; + * if( ucLocalTickCount >= TICKS_TO_WAIT ) + * { + * // Unblock the task by releasing the semaphore. + * xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); + * + * // Reset the count so we release the semaphore again in 10 ticks time. + * ucLocalTickCount = 0; + * } + * + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // We can force a context switch here. Context switching from an + * // ISR uses port specific syntax. Check the demo task for your port + * // to find the syntax required. + * } + * } + * @endcode + * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + * @code{c} + * xSemaphoreTakeFromISR( + * SemaphoreHandle_t xSemaphore, + * BaseType_t *pxHigherPriorityTaskWoken + * ); + * @endcode + * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateMutex( void ); + * @endcode + * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * https://www.FreeRTOS.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore; + * + * void vATask( void * pvParameters ) + * { + * // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). + * // This is a macro so pass the variable in directly. + * xSemaphore = xSemaphoreCreateMutex(); + * + * if( xSemaphore != NULL ) + * { + * // The semaphore was created successfully. + * // The semaphore can now be used. + * } + * } + * @endcode + * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_MUTEXES == 1 ) ) + #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer ); + * @endcode + * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * https://www.FreeRTOS.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore; + * StaticSemaphore_t xMutexBuffer; + * + * void vATask( void * pvParameters ) + * { + * // A mutex cannot be used before it has been created. xMutexBuffer is + * // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is + * // attempted. + * xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer ); + * + * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL, + * // so there is no need to check it. + * } + * @endcode + * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ +#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_MUTEXES == 1 ) ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif + + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void ); + * @endcode + * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexes use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore; + * + * void vATask( void * pvParameters ) + * { + * // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). + * // This is a macro so pass the variable in directly. + * xSemaphore = xSemaphoreCreateRecursiveMutex(); + * + * if( xSemaphore != NULL ) + * { + * // The semaphore was created successfully. + * // The semaphore can now be used. + * } + * } + * @endcode + * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer ); + * @endcode + * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexes use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore; + * StaticSemaphore_t xMutexBuffer; + * + * void vATask( void * pvParameters ) + * { + * // A recursive semaphore cannot be used before it is created. Here a + * // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic(). + * // The address of xMutexBuffer is passed into the function, and will hold + * // the mutexes data structures - so no dynamic memory allocation will be + * // attempted. + * xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer ); + * + * // As no dynamic memory allocation was performed, xSemaphore cannot be NULL, + * // so there is no need to check it. + * } + * @endcode + * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, ( pxStaticSemaphore ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount ); + * @endcode + * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * https://www.FreeRTOS.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore; + * + * void vATask( void * pvParameters ) + * { + * SemaphoreHandle_t xSemaphore = NULL; + * + * // Semaphore cannot be used before a call to xSemaphoreCreateCounting(). + * // The max value to which the semaphore can count should be 10, and the + * // initial value assigned to the count should be 0. + * xSemaphore = xSemaphoreCreateCounting( 10, 0 ); + * + * if( xSemaphore != NULL ) + * { + * // The semaphore was created successfully. + * // The semaphore can now be used. + * } + * } + * @endcode + * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + * @code{c} + * SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer ); + * @endcode + * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * https://www.FreeRTOS.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: + * @code{c} + * SemaphoreHandle_t xSemaphore; + * StaticSemaphore_t xSemaphoreBuffer; + * + * void vATask( void * pvParameters ) + * { + * SemaphoreHandle_t xSemaphore = NULL; + * + * // Counting semaphore cannot be used before they have been created. Create + * // a counting semaphore using xSemaphoreCreateCountingStatic(). The max + * // value to which the semaphore can count is 10, and the initial value + * // assigned to the count will be 0. The address of xSemaphoreBuffer is + * // passed in and will be used to hold the semaphore structure, so no dynamic + * // memory allocation will be used. + * xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer ); + * + * // No memory allocation was attempted so xSemaphore cannot be NULL, so there + * // is no need to check its value. + * } + * @endcode + * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + * @code{c} + * void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + * @code{c} + * TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex ); + * @endcode + * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) +#endif + +/** + * semphr.h + * @code{c} + * TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex ); + * @endcode + * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + #define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) +#endif + +/** + * semphr.h + * @code{c} + * UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + * @code{c} + * UBaseType_t uxSemaphoreGetCountFromISR( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * If the semaphore is a counting semaphore then uxSemaphoreGetCountFromISR() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCountFromISR() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + * @code{c} + * BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore ); + * @endcode + * + * Retrieve pointer to a statically created binary semaphore, counting semaphore, + * or mutex semaphore's data structure buffer. This is the same buffer that is + * supplied at the time of creation. + * + * @param xSemaphore The semaphore for which to retrieve the buffer. + * + * @param ppxSemaphoreBuffer Used to return a pointer to the semaphore's + * data structure buffer. + * + * @return pdTRUE if buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreGetStaticBuffer( xSemaphore, ppxSemaphoreBuffer ) xQueueGenericGetStaticBuffers( ( QueueHandle_t ) ( xSemaphore ), NULL, ( ppxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +#endif /* SEMAPHORE_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h b/Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h new file mode 100644 index 0000000..354400d --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/stack_macros.h @@ -0,0 +1,137 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +/* + * portSTACK_LIMIT_PADDING is a number of extra words to consider to be in + * use on the stack. + */ +#ifndef portSTACK_LIMIT_PADDING + #define portSTACK_LIMIT_PADDING 0 +#endif + +#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + +/* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } while( 0 ) + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + +/* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } while( 0 ) + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } while( 0 ) + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do { \ + int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } while( 0 ) + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h b/Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h new file mode 100644 index 0000000..48ca266 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h @@ -0,0 +1,945 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section section and set the + * receive block time to 0. + * + */ + +#ifndef STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include stream_buffer.h" +#endif + +/* *INDENT-OFF* */ +#if defined( __cplusplus ) + extern "C" { +#endif +/* *INDENT-ON* */ + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ +struct StreamBufferDef_t; +typedef struct StreamBufferDef_t * StreamBufferHandle_t; + +/** + * Type used as a stream buffer's optional callback. + */ +typedef void (* StreamBufferCallbackFunction_t)( StreamBufferHandle_t xStreamBuffer, + BaseType_t xIsInsideISR, + BaseType_t * const pxHigherPriorityTaskWoken ); + +/** + * stream_buffer.h + * + * @code{c} + * StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes ); + * @endcode + * + * Creates a new stream buffer using dynamically allocated memory. See + * xStreamBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream buffer will be + * able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to + * trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default + * implementation provided by sbSEND_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a + * stream buffer. If the parameter is NULL, it will use the default + * implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @return If NULL is returned, then the stream buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream buffer data structures and storage area. A non-NULL value being + * returned indicates that the stream buffer has been created successfully - + * the returned value should be stored as the handle to the created stream + * buffer. + * + * Example use: + * @code{c} + * + * void vAFunction( void ) + * { + * StreamBufferHandle_t xStreamBuffer; + * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10; + * + * // Create a stream buffer that can hold 100 bytes. The memory used to hold + * // both the stream buffer structure and the data in the stream buffer is + * // allocated dynamically. + * xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel ); + * + * if( xStreamBuffer == NULL ) + * { + * // There was not enough heap memory space available to create the + * // stream buffer. + * } + * else + * { + * // The stream buffer was created successfully and can now be used. + * } + * } + * @endcode + * \defgroup xStreamBufferCreate xStreamBufferCreate + * \ingroup StreamBufferManagement + */ + +#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xStreamBufferCreateWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * stream_buffer.h + * + * @code{c} + * StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes, + * size_t xTriggerLevelBytes, + * uint8_t *pucStreamBufferStorageArea, + * StaticStreamBuffer_t *pxStaticStreamBuffer ); + * @endcode + * Creates a new stream buffer using statically allocated memory. See + * xStreamBufferCreate() for a version that uses dynamically allocated memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBufferCreateStatic() to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes big. This is the array to which streams are + * copied when they are written to the stream buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream buffer's data + * structure. + * + * @param pxSendCompletedCallback Callback invoked when number of bytes at least equal to + * trigger level is sent to the stream buffer. If the parameter is NULL, it will use the default + * implementation provided by sbSEND_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @param pxReceiveCompletedCallback Callback invoked when more than zero bytes are read from a + * stream buffer. If the parameter is NULL, it will use the default + * implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback, + * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h. + * + * @return If the stream buffer is created successfully then a handle to the + * created stream buffer is returned. If either pucStreamBufferStorageArea or + * pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: + * @code{c} + * + * // Used to dimension the array used to hold the streams. The available space + * // will actually be one less than this, so 999. + #define STORAGE_SIZE_BYTES 1000 + * + * // Defines the memory that will actually hold the streams within the stream + * // buffer. + * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; + * + * // The variable used to hold the stream buffer structure. + * StaticStreamBuffer_t xStreamBufferStruct; + * + * void MyFunction( void ) + * { + * StreamBufferHandle_t xStreamBuffer; + * const size_t xTriggerLevel = 1; + * + * xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucStorageBuffer ), + * xTriggerLevel, + * ucStorageBuffer, + * &xStreamBufferStruct ); + * + * // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer + * // parameters were NULL, xStreamBuffer will not be NULL, and can be used to + * // reference the created stream buffer in other stream buffer API calls. + * + * // Other code that uses the stream buffer can go here. + * } + * + * @endcode + * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic + * \ingroup StreamBufferManagement + */ + +#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), NULL, NULL ) + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define xStreamBufferCreateStaticWithCallback( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \ + xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), ( xTriggerLevelBytes ), pdFALSE, ( pucStreamBufferStorageArea ), ( pxStaticStreamBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) ) +#endif + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, + * uint8_t ** ppucStreamBufferStorageArea, + * StaticStreamBuffer_t ** ppxStaticStreamBuffer ); + * @endcode + * + * Retrieve pointers to a statically created stream buffer's data structure + * buffer and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xStreamBuffer The stream buffer for which to retrieve the buffers. + * + * @param ppucStreamBufferStorageArea Used to return a pointer to the stream + * buffer's storage area buffer. + * + * @param ppxStaticStreamBuffer Used to return a pointer to the stream + * buffer's data structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xStreamBufferGetStaticBuffers xStreamBufferGetStaticBuffers + * \ingroup StreamBufferManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, + uint8_t ** ppucStreamBufferStorageArea, + StaticStreamBuffer_t ** ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * stream_buffer.h + * + * @code{c} + * size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + * const void *pvTxData, + * size_t xDataLengthBytes, + * TickType_t xTicksToWait ); + * @endcode + * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: + * @code{c} + * void vAFunction( StreamBufferHandle_t xStreamBuffer ) + * { + * size_t xBytesSent; + * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 }; + * char *pcStringToSend = "String to send"; + * const TickType_t x100ms = pdMS_TO_TICKS( 100 ); + * + * // Send an array to the stream buffer, blocking for a maximum of 100ms to + * // wait for enough space to be available in the stream buffer. + * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms ); + * + * if( xBytesSent != sizeof( ucArrayToSend ) ) + * { + * // The call to xStreamBufferSend() times out before there was enough + * // space in the buffer for the data to be written, but it did + * // successfully write xBytesSent bytes. + * } + * + * // Send the string to the stream buffer. Return immediately if there is not + * // enough space in the buffer. + * xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 ); + * + * if( xBytesSent != strlen( pcStringToSend ) ) + * { + * // The entire string could not be added to the stream buffer because + * // there was not enough free space in the buffer, but xBytesSent bytes + * // were sent. Could try again to send the remaining bytes. + * } + * } + * @endcode + * \defgroup xStreamBufferSend xStreamBufferSend + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + * const void *pvTxData, + * size_t xDataLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: + * @code{c} + * // A stream buffer that has already been created. + * StreamBufferHandle_t xStreamBuffer; + * + * void vAnInterruptServiceRoutine( void ) + * { + * size_t xBytesSent; + * char *pcStringToSend = "String to send"; + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. + * + * // Attempt to send the string to the stream buffer. + * xBytesSent = xStreamBufferSendFromISR( xStreamBuffer, + * ( void * ) pcStringToSend, + * strlen( pcStringToSend ), + * &xHigherPriorityTaskWoken ); + * + * if( xBytesSent != strlen( pcStringToSend ) ) + * { + * // There was not enough free space in the stream buffer for the entire + * // string to be written, ut xBytesSent bytes were written. + * } + * + * // If xHigherPriorityTaskWoken was set to pdTRUE inside + * // xStreamBufferSendFromISR() then a task that has a priority above the + * // priority of the currently executing task was unblocked and a context + * // switch should be performed to ensure the ISR returns to the unblocked + * // task. In most FreeRTOS ports this is done by simply passing + * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the + * // variables value, and perform the context switch if necessary. Check the + * // documentation for the port in use for port specific instructions. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * @endcode + * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + * void *pvRxData, + * size_t xBufferLengthBytes, + * TickType_t xTicksToWait ); + * @endcode + * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferReceive()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: + * @code{c} + * void vAFunction( StreamBuffer_t xStreamBuffer ) + * { + * uint8_t ucRxData[ 20 ]; + * size_t xReceivedBytes; + * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); + * + * // Receive up to another sizeof( ucRxData ) bytes from the stream buffer. + * // Wait in the Blocked state (so not using any CPU processing time) for a + * // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be + * // available. + * xReceivedBytes = xStreamBufferReceive( xStreamBuffer, + * ( void * ) ucRxData, + * sizeof( ucRxData ), + * xBlockTime ); + * + * if( xReceivedBytes > 0 ) + * { + * // A ucRxData contains another xReceivedBytes bytes of data, which can + * // be processed here.... + * } + * } + * @endcode + * \defgroup xStreamBufferReceive xStreamBufferReceive + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + * void *pvRxData, + * size_t xBufferLengthBytes, + * BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: + * @code{c} + * // A stream buffer that has already been created. + * StreamBuffer_t xStreamBuffer; + * + * void vAnInterruptServiceRoutine( void ) + * { + * uint8_t ucRxData[ 20 ]; + * size_t xReceivedBytes; + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE. + * + * // Receive the next stream from the stream buffer. + * xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer, + * ( void * ) ucRxData, + * sizeof( ucRxData ), + * &xHigherPriorityTaskWoken ); + * + * if( xReceivedBytes > 0 ) + * { + * // ucRxData contains xReceivedBytes read from the stream buffer. + * // Process the stream here.... + * } + * + * // If xHigherPriorityTaskWoken was set to pdTRUE inside + * // xStreamBufferReceiveFromISR() then a task that has a priority above the + * // priority of the currently executing task was unblocked and a context + * // switch should be performed to ensure the ISR returns to the unblocked + * // task. In most FreeRTOS ports this is done by simply passing + * // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the + * // variables value, and perform the context switch if necessary. Check the + * // documentation for the port in use for port specific instructions. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * } + * @endcode + * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \defgroup vStreamBufferDelete vStreamBufferDelete + * \ingroup StreamBufferManagement + */ +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsFull xStreamBufferIsFull + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferReset xStreamBufferReset + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ); + * @endcode + * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ); + * @endcode + * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * + * @code{c} + * BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* Functions below here are not part of the public API. */ +StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + + +StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_TRACE_FACILITY == 1 ) + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, + UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +#endif + +/* *INDENT-OFF* */ +#if defined( __cplusplus ) + } +#endif +/* *INDENT-ON* */ + +#endif /* !defined( STREAM_BUFFER_H ) */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/task.h b/Middlewares/Third_Party/FreeRTOS/Source/include/task.h new file mode 100644 index 0000000..1207e18 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/task.h @@ -0,0 +1,3235 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/*----------------------------------------------------------- +* MACROS AND DEFINITIONS +*----------------------------------------------------------*/ + +/* + * If tskKERNEL_VERSION_NUMBER ends with + it represents the version in development + * after the numbered release. + * + * The tskKERNEL_VERSION_MAJOR, tskKERNEL_VERSION_MINOR, tskKERNEL_VERSION_BUILD + * values will reflect the last released version number. + */ +#define tskKERNEL_VERSION_NUMBER "V10.6.2" +#define tskKERNEL_VERSION_MAJOR 10 +#define tskKERNEL_VERSION_MINOR 6 +#define tskKERNEL_VERSION_BUILD 2 + +/* MPU region parameters passed in ulParameters + * of MemoryRegion_t struct. */ +#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) +#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) +#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) +#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) + +/* MPU region permissions stored in MPU settings to + * authorize access requests. */ +#define tskMPU_READ_PERMISSION ( 1UL << 0UL ) +#define tskMPU_WRITE_PERMISSION ( 1UL << 1UL ) + +/* The direct to task notification feature used to have only a single notification + * per task. Now there is an array of notifications per task that is dimensioned by + * configTASK_NOTIFICATION_ARRAY_ENTRIES. For backward compatibility, any use of the + * original direct to task notification defaults to using the first index in the + * array. */ +#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 ) + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tskTaskControlBlock * TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (* TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a ready or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void * pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + configSTACK_DEPTH_TYPE usStackDepth; + void * pvParameters; + UBaseType_t uxPriority; + StackType_t * puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; + #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + StaticTask_t * const pxTaskBuffer; + #endif +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task + * in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char * pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See https://www.FreeRTOS.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t * pxStackBase; /* Points to the lowest address of the task's stack area. */ + #if ( ( portSTACK_GROWTH > 0 ) && ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t * pxTopOfStack; /* Points to the top address of the task's stack area. */ + StackType_t * pxEndOfStack; /* Points to the end address of the task's stack area. */ + #endif + configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPRESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + #if ( INCLUDE_vTaskSuspend == 1 ) + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ + #endif /* INCLUDE_vTaskSuspend */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) + +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is + * 0 to generate more optimal code when configASSERT() is defined as the constant + * is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- +* TASK CREATION API +*----------------------------------------------------------*/ + +/** + * task. h + * @code{c} + * BaseType_t xTaskCreate( + * TaskFunction_t pxTaskCode, + * const char *pcName, + * configSTACK_DEPTH_TYPE usStackDepth, + * void *pvParameters, + * UBaseType_t uxPriority, + * TaskHandle_t *pxCreatedTask + * ); + * @endcode + * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pxTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: + * @code{c} + * // Task to be created. + * void vTaskCode( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * } + * } + * + * // Function that creates a task. + * void vOtherFunction( void ) + * { + * static uint8_t ucParameterToPass; + * TaskHandle_t xHandle = NULL; + * + * // Create the task, storing the handle. Note that the passed parameter ucParameterToPass + * // must exist for the lifetime of the task, so in this case is declared static. If it was just an + * // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time + * // the new task attempts to access it. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle ); + * configASSERT( xHandle ); + * + * // Use the handle to delete the task. + * if( xHandle != NULL ) + * { + * vTaskDelete( xHandle ); + * } + * } + * @endcode + * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + * @code{c} + * TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + * const char *pcName, + * uint32_t ulStackDepth, + * void *pvParameters, + * UBaseType_t uxPriority, + * StackType_t *puxStackBuffer, + * StaticTask_t *pxTaskBuffer ); + * @endcode + * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pxTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param puxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither puxStackBuffer nor pxTaskBuffer are NULL, then the task + * will be created and a handle to the created task is returned. If either + * puxStackBuffer or pxTaskBuffer are NULL then the task will not be created and + * NULL is returned. + * + * Example usage: + * @code{c} + * + * // Dimensions of the buffer that the task being created will use as its stack. + * // NOTE: This is the number of words the stack will hold, not the number of + * // bytes. For example, if each stack item is 32-bits, and this is set to 100, + * // then 400 bytes (100 * 32-bits) will be allocated. + #define STACK_SIZE 200 + * + * // Structure that will hold the TCB of the task being created. + * StaticTask_t xTaskBuffer; + * + * // Buffer that the task being created will use as its stack. Note this is + * // an array of StackType_t variables. The size of StackType_t is dependent on + * // the RTOS port. + * StackType_t xStack[ STACK_SIZE ]; + * + * // Function that implements the task being created. + * void vTaskCode( void * pvParameters ) + * { + * // The parameter value is expected to be 1 as 1 is passed in the + * // pvParameters value in the call to xTaskCreateStatic(). + * configASSERT( ( uint32_t ) pvParameters == 1UL ); + * + * for( ;; ) + * { + * // Task code goes here. + * } + * } + * + * // Function that creates a task. + * void vOtherFunction( void ) + * { + * TaskHandle_t xHandle = NULL; + * + * // Create the task without using any dynamic memory allocation. + * xHandle = xTaskCreateStatic( + * vTaskCode, // Function that implements the task. + * "NAME", // Text name for the task. + * STACK_SIZE, // Stack size in words, not bytes. + * ( void * ) 1, // Parameter passed into the task. + * tskIDLE_PRIORITY,// Priority at which the task is created. + * xStack, // Array to use as the task's stack. + * &xTaskBuffer ); // Variable to hold the task's data structure. + * + * // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have + * // been created, and xHandle will be the task's handle. Use the handle + * // to suspend the task. + * vTaskSuspend( xHandle ); + * } + * @endcode + * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + * @code{c} + * BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); + * @endcode + * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * See xTaskCreateRestrictedStatic() for a version that does not use any + * dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: + * @code{c} + * // Create an TaskParameters_t structure that defines the task to be created. + * static const TaskParameters_t xCheckTaskParameters = + * { + * vATask, // pvTaskCode - the function that implements the task. + * "ATask", // pcName - just a text name for the task to assist debugging. + * 100, // usStackDepth - the stack size DEFINED IN WORDS. + * NULL, // pvParameters - passed into the task function as the function parameters. + * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. + * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. + * + * // xRegions - Allocate up to three separate memory regions for access by + * // the task, with appropriate access permissions. Different processors have + * // different memory alignment requirements - refer to the FreeRTOS documentation + * // for full information. + * { + * // Base address Length Parameters + * { cReadWriteArray, 32, portMPU_REGION_READ_WRITE }, + * { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY }, + * { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE } + * } + * }; + * + * int main( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task from the const structure defined above. The task handle + * // is requested (the second parameter is not NULL) but in this case just for + * // demonstration purposes as its not actually used. + * xTaskCreateRestricted( &xRegTest1Parameters, &xHandle ); + * + * // Start the scheduler. + * vTaskStartScheduler(); + * + * // Will only get here if there was insufficient memory to create the idle + * // and/or timer task. + * for( ;; ); + * } + * @endcode + * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + * @code{c} + * BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); + * @endcode + * + * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. + * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreateRestricted() then the stack is provided by the application writer, + * and the memory used to hold the task's data structure is automatically + * dynamically allocated inside the xTaskCreateRestricted() function. If a task + * is created using xTaskCreateRestrictedStatic() then the application writer + * must provide the memory used to hold the task's data structures too. + * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be + * created without using any dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure + * contains an additional member, which is used to point to a variable of type + * StaticTask_t - which is then used to hold the task's data structure. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: + * @code{c} + * // Create an TaskParameters_t structure that defines the task to be created. + * // The StaticTask_t variable is only included in the structure when + * // configSUPPORT_STATIC_ALLOCATION is set to 1. The PRIVILEGED_DATA macro can + * // be used to force the variable into the RTOS kernel's privileged data area. + * static PRIVILEGED_DATA StaticTask_t xTaskBuffer; + * static const TaskParameters_t xCheckTaskParameters = + * { + * vATask, // pvTaskCode - the function that implements the task. + * "ATask", // pcName - just a text name for the task to assist debugging. + * 100, // usStackDepth - the stack size DEFINED IN WORDS. + * NULL, // pvParameters - passed into the task function as the function parameters. + * ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state. + * cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack. + * + * // xRegions - Allocate up to three separate memory regions for access by + * // the task, with appropriate access permissions. Different processors have + * // different memory alignment requirements - refer to the FreeRTOS documentation + * // for full information. + * { + * // Base address Length Parameters + * { cReadWriteArray, 32, portMPU_REGION_READ_WRITE }, + * { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY }, + * { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE } + * } + * + * &xTaskBuffer; // Holds the task's data structure. + * }; + * + * int main( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task from the const structure defined above. The task handle + * // is requested (the second parameter is not NULL) but in this case just for + * // demonstration purposes as its not actually used. + * xTaskCreateRestrictedStatic( &xRegTest1Parameters, &xHandle ); + * + * // Start the scheduler. + * vTaskStartScheduler(); + * + * // Will only get here if there was insufficient memory to create the idle + * // and/or timer task. + * for( ;; ); + * } + * @endcode + * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic + * \ingroup Tasks + */ +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + * @code{c} + * void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); + * @endcode + * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param[in] pxRegions A pointer to a MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: + * @code{c} + * // Define an array of MemoryRegion_t structures that configures an MPU region + * // allowing read/write access for 1024 bytes starting at the beginning of the + * // ucOneKByte array. The other two of the maximum 3 definable regions are + * // unused so set to zero. + * static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] = + * { + * // Base address Length Parameters + * { ucOneKByte, 1024, portMPU_REGION_READ_WRITE }, + * { 0, 0, 0 }, + * { 0, 0, 0 } + * }; + * + * void vATask( void *pvParameters ) + * { + * // This task was created such that it has access to certain regions of + * // memory as defined by the MPU configuration. At some point it is + * // desired that these MPU regions are replaced with that defined in the + * // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions() + * // for this purpose. NULL is used as the task handle to indicate that this + * // function should modify the MPU regions of the calling task. + * vTaskAllocateMPURegions( NULL, xAltRegions ); + * + * // Now the task can continue its function, but from this point on can only + * // access its stack and the ucOneKByte array (unless any other statically + * // defined or shared regions have been declared elsewhere). + * } + * @endcode + * \defgroup vTaskAllocateMPURegions vTaskAllocateMPURegions + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, + const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskDelete( TaskHandle_t xTaskToDelete ); + * @endcode + * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTaskToDelete The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: + * @code{c} + * void vOtherFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create the task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // Use the handle to delete the task. + * vTaskDelete( xHandle ); + * } + * @endcode + * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- +* TASK CONTROL API +*----------------------------------------------------------*/ + +/** + * task. h + * @code{c} + * void vTaskDelay( const TickType_t xTicksToDelay ); + * @endcode + * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will affect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See xTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + * + * void vTaskFunction( void * pvParameters ) + * { + * // Block for 500ms. + * const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + * + * for( ;; ) + * { + * // Simply toggle the LED every 500ms, blocking between each toggle. + * vToggleLED(); + * vTaskDelay( xDelay ); + * } + * } + * + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * BaseType_t xTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement ); + * @endcode + * + * INCLUDE_xTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, xTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The macro pdMS_TO_TICKS() can be used to calculate the number of ticks from a + * time specified in milliseconds with a resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within xTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling xTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * @return Value which can be used to check whether the task was actually delayed. + * Will be pdTRUE if the task way delayed and pdFALSE otherwise. A task will not + * be delayed if the next expected wake time is in the past. + * + * Example usage: + * @code{c} + * // Perform an action every 10 ticks. + * void vTaskFunction( void * pvParameters ) + * { + * TickType_t xLastWakeTime; + * const TickType_t xFrequency = 10; + * BaseType_t xWasDelayed; + * + * // Initialise the xLastWakeTime variable with the current time. + * xLastWakeTime = xTaskGetTickCount (); + * for( ;; ) + * { + * // Wait for the next cycle. + * xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency ); + * + * // Perform action here. xWasDelayed value can be used to determine + * // whether a deadline was missed if the code here took too long. + * } + * } + * @endcode + * \defgroup xTaskDelayUntil xTaskDelayUntil + * \ingroup TaskCtrl + */ +BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/* + * vTaskDelayUntil() is the older version of xTaskDelayUntil() and does not + * return a value. + */ +#define vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ) \ + do { \ + ( void ) xTaskDelayUntil( ( pxPreviousWakeTime ), ( xTimeIncrement ) ); \ + } while( 0 ) + + +/** + * task. h + * @code{c} + * BaseType_t xTaskAbortDelay( TaskHandle_t xTask ); + * @endcode + * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * There is no 'FromISR' version of this function as an interrupt would need to + * know which object a task was blocked on in order to know which actions to + * take. For example, if the task was blocked on a queue the interrupt handler + * would then need to know if the queue was locked. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ); + * @endcode + * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to obtain the priority of the created task. + * // It was created with tskIDLE_PRIORITY, but may have changed + * // it itself. + * if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY ) + * { + * // The task has changed it's priority. + * } + * + * // ... + * + * // Is our priority higher than the created task? + * if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) ) + * { + * // Our priority (obtained using NULL handle) is higher. + * } + * } + * @endcode + * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ); + * @endcode + * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * eTaskState eTaskGetState( TaskHandle_t xTask ); + * @endcode + * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); + * @endcode + * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @param xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * TaskStatus_t xTaskDetails; + * + * // Obtain the handle of a task from its name. + * xHandle = xTaskGetHandle( "Task_Name" ); + * + * // Check the handle is not NULL. + * configASSERT( xHandle ); + * + * // Use the handle to obtain further information about the task. + * vTaskGetInfo( xHandle, + * &xTaskDetails, + * pdTRUE, // Include the high water mark in xTaskDetails. + * eInvalid ); // Include the task state in xTaskDetails. + * } + * @endcode + * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); + * @endcode + * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to raise the priority of the created task. + * vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 ); + * + * // ... + * + * // Use a NULL handle to raise our priority to the same value. + * vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 ); + * } + * @endcode + * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskSuspend( TaskHandle_t xTaskToSuspend ); + * @endcode + * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to suspend the created task. + * vTaskSuspend( xHandle ); + * + * // ... + * + * // The created task will not run during this period, unless + * // another task calls vTaskResume( xHandle ). + * + * //... + * + * + * // Suspend ourselves. + * vTaskSuspend( NULL ); + * + * // We cannot get here unless another task calls vTaskResume + * // with our handle as the parameter. + * } + * @endcode + * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskResume( TaskHandle_t xTaskToResume ); + * @endcode + * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * TaskHandle_t xHandle; + * + * // Create a task, storing the handle. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle ); + * + * // ... + * + * // Use the handle to suspend the created task. + * vTaskSuspend( xHandle ); + * + * // ... + * + * // The created task will not run during this period, unless + * // another task calls vTaskResume( xHandle ). + * + * //... + * + * + * // Resume the suspended task ourselves. + * vTaskResume( xHandle ); + * + * // The created task will once again get microcontroller processing + * // time in accordance with its priority within the system. + * } + * @endcode + * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void xTaskResumeFromISR( TaskHandle_t xTaskToResume ); + * @endcode + * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- +* SCHEDULER CONTROL +*----------------------------------------------------------*/ + +/** + * task. h + * @code{c} + * void vTaskStartScheduler( void ); + * @endcode + * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: + * @code{c} + * void vAFunction( void ) + * { + * // Create at least one task before starting the kernel. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + * + * // Start the real time kernel with preemption. + * vTaskStartScheduler (); + * + * // Will not get here unless a task calls vTaskEndScheduler () + * } + * @endcode + * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskEndScheduler( void ); + * @endcode + * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: + * @code{c} + * void vTaskCode( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * + * // At some point we want to end the real time kernel processing + * // so call ... + * vTaskEndScheduler (); + * } + * } + * + * void vAFunction( void ) + * { + * // Create at least one task before starting the kernel. + * xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + * + * // Start the real time kernel with preemption. + * vTaskStartScheduler (); + * + * // Will only get here when the vTaskCode () task has called + * // vTaskEndScheduler (). When we get here we are back to single task + * // execution. + * } + * @endcode + * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskSuspendAll( void ); + * @endcode + * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * xTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: + * @code{c} + * void vTask1( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * + * // ... + * + * // At some point the task wants to perform a long operation during + * // which it does not want to get swapped out. It cannot use + * // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the + * // operation may cause interrupts to be missed - including the + * // ticks. + * + * // Prevent the real time kernel swapping out the task. + * vTaskSuspendAll (); + * + * // Perform the operation here. There is no need to use critical + * // sections as we have all the microcontroller processing time. + * // During this time interrupts will still operate and the kernel + * // tick count will be maintained. + * + * // ... + * + * // The operation is complete. Restart the kernel. + * xTaskResumeAll (); + * } + * } + * @endcode + * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * BaseType_t xTaskResumeAll( void ); + * @endcode + * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: + * @code{c} + * void vTask1( void * pvParameters ) + * { + * for( ;; ) + * { + * // Task code goes here. + * + * // ... + * + * // At some point the task wants to perform a long operation during + * // which it does not want to get swapped out. It cannot use + * // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the + * // operation may cause interrupts to be missed - including the + * // ticks. + * + * // Prevent the real time kernel swapping out the task. + * vTaskSuspendAll (); + * + * // Perform the operation here. There is no need to use critical + * // sections as we have all the microcontroller processing time. + * // During this time interrupts will still operate and the real + * // time kernel tick count will be maintained. + * + * // ... + * + * // The operation is complete. Restart the kernel. We want to force + * // a context switch - but there is no point if resuming the scheduler + * // caused a context switch already. + * if( !xTaskResumeAll () ) + * { + * taskYIELD (); + * } + * } + * } + * @endcode + * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- +* TASK UTILITIES +*----------------------------------------------------------*/ + +/** + * task. h + * @code{c} + * TickType_t xTaskGetTickCount( void ); + * @endcode + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * TickType_t xTaskGetTickCountFromISR( void ); + * @endcode + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * uint16_t uxTaskGetNumberOfTasks( void ); + * @endcode + * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * char *pcTaskGetName( TaskHandle_t xTaskToQuery ); + * @endcode + * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + * @code{c} + * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ); + * @endcode + * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + * @code{c} + * BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask, + * StackType_t ** ppuxStackBuffer, + * StaticTask_t ** ppxTaskBuffer ); + * @endcode + * + * Retrieve pointers to a statically created task's data structure + * buffer and stack buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xTask The task for which to retrieve the buffers. + * + * @param ppuxStackBuffer Used to return a pointer to the task's stack buffer. + * + * @param ppxTaskBuffer Used to return a pointer to the task's data structure + * buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xTaskGetStaticBuffers xTaskGetStaticBuffers + * \ingroup TaskUtils + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task.h + * @code{c} + * UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); + * @endcode + * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + * @code{c} + * configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ); + * @endcode + * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before + * FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, + * so the following two prototypes will cause a compilation error. This can be + * fixed by simply guarding against the inclusion of these two prototypes unless + * they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration + * constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + +/** + * task.h + * @code{c} + * void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); + * @endcode + * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + +/** + * task.h + * @code{c} + * void xTaskGetApplicationTaskTag( TaskHandle_t xTask ); + * @endcode + * + * Returns the pxHookFunction value assigned to the task xTask. Do not + * call from an interrupt service routine - call + * xTaskGetApplicationTaskTagFromISR() instead. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + * @code{c} + * void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ); + * @endcode + * + * Returns the pxHookFunction value assigned to the task xTask. Can + * be called from an interrupt service routine. + */ + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + +/* Each task contains an array of pointers that is dimensioned by the + * configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + * kernel does not use the pointers itself, so the application writer can use + * the pointers for any purpose they wish. The following two functions are + * used to set and query a pointer respectively. */ + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) PRIVILEGED_FUNCTION; + void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) PRIVILEGED_FUNCTION; + +#endif + +#if ( configCHECK_FOR_STACK_OVERFLOW > 0 ) + +/** + * task.h + * @code{c} + * void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName); + * @endcode + * + * The application stack overflow hook is called when a stack overflow is detected for a task. + * + * Details on stack overflow detection can be found here: https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html + * + * @param xTask the task that just exceeded its stack boundaries. + * @param pcTaskName A character string containing the name of the offending task. + */ + void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * pcTaskName ); + +#endif + +#if ( configUSE_IDLE_HOOK == 1 ) + +/** + * task.h + * @code{c} + * void vApplicationIdleHook( void ); + * @endcode + * + * The application idle hook is called by the idle task. + * This allows the application designer to add background functionality without + * the overhead of a separate task. + * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + */ + void vApplicationIdleHook( void ); + +#endif + + +#if ( configUSE_TICK_HOOK != 0 ) + +/** + * task.h + * @code{c} + * void vApplicationTickHook( void ); + * @endcode + * + * This hook function is called in the system tick handler after any OS work is completed. + */ + void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/** + * task.h + * @code{c} + * void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) + * @endcode + * + * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Idle Task TCB. This function is required when + * configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION + * + * @param ppxIdleTaskTCBBuffer A handle to a statically allocated TCB buffer + * @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task + * @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + */ + void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */ +#endif + +/** + * task.h + * @code{c} + * BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); + * @endcode + * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * https://www.FreeRTOS.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: + * @code{c} + * // This example demonstrates how a human readable table of run time stats + * // information is generated from raw data provided by uxTaskGetSystemState(). + * // The human readable table is written to pcWriteBuffer + * void vTaskGetRunTimeStats( char *pcWriteBuffer ) + * { + * TaskStatus_t *pxTaskStatusArray; + * volatile UBaseType_t uxArraySize, x; + * configRUN_TIME_COUNTER_TYPE ulTotalRunTime, ulStatsAsPercentage; + * + * // Make sure the write buffer does not contain a string. + * pcWriteBuffer = 0x00; + * + * // Take a snapshot of the number of tasks in case it changes while this + * // function is executing. + * uxArraySize = uxTaskGetNumberOfTasks(); + * + * // Allocate a TaskStatus_t structure for each task. An array could be + * // allocated statically at compile time. + * pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) ); + * + * if( pxTaskStatusArray != NULL ) + * { + * // Generate raw status information about each task. + * uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime ); + * + * // For percentage calculations. + * ulTotalRunTime /= 100UL; + * + * // Avoid divide by zero errors. + * if( ulTotalRunTime > 0 ) + * { + * // For each populated position in the pxTaskStatusArray array, + * // format the raw data as human readable ASCII data + * for( x = 0; x < uxArraySize; x++ ) + * { + * // What percentage of the total run time has the task used? + * // This will always be rounded down to the nearest integer. + * // ulTotalRunTimeDiv100 has already been divided by 100. + * ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime; + * + * if( ulStatsAsPercentage > 0UL ) + * { + * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + * } + * else + * { + * // If the percentage is zero here then the task has + * // consumed less than 1% of the total run time. + * sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter ); + * } + * + * pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); + * } + * } + * + * // The array is no longer needed, free the memory it consumes. + * vPortFree( pxTaskStatusArray ); + * } + * } + * @endcode + */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * void vTaskList( char *pcWriteBuffer ); + * @endcode + * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task: + * names, states, priority, stack usage and task number. + * Stack usage specified as the number of unused StackType_t words stack can hold + * on top of stack - not the number of bytes. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + * @code{c} + * void vTaskGetRunTimeStats( char *pcWriteBuffer ); + * @endcode + * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + * @code{c} + * configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ); + * configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ); + * @endcode + * + * configGENERATE_RUN_TIME_STATS must be defined as 1 for these functions to be + * available. The application must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() to configure a peripheral timer/counter and + * return the timers current count value respectively. The counter should be + * at least 10 times the frequency of the tick count. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total + * execution time of each task into a buffer, ulTaskGetRunTimeCounter() + * returns the total execution time of just one task and + * ulTaskGetRunTimePercent() returns the percentage of the CPU time used by + * just one task. + * + * @return The total run time of the given task or the percentage of the total + * run time consumed by the given task. This is the amount of time the task + * has actually been executing. The unit of time is dependent on the frequency + * configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() macros. + * + * \defgroup ulTaskGetRunTimeCounter ulTaskGetRunTimeCounter + * \ingroup TaskUtils + */ +configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ); + * configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ); + * @endcode + * + * configGENERATE_RUN_TIME_STATS must be defined as 1 for these functions to be + * available. The application must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() to configure a peripheral timer/counter and + * return the timers current count value respectively. The counter should be + * at least 10 times the frequency of the tick count. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total + * execution time of each task into a buffer, ulTaskGetIdleRunTimeCounter() + * returns the total execution time of just the idle task and + * ulTaskGetIdleRunTimePercent() returns the percentage of the CPU time used by + * just the idle task. + * + * Note the amount of idle time is only a good measure of the slack time in a + * system if there are no other tasks executing at the idle priority, tickless + * idle is not used, and configIDLE_SHOULD_YIELD is set to 0. + * + * @return The total run time of the idle task or the percentage of the total + * run time consumed by the idle task. This is the amount of time the + * idle task has actually been executing. The unit of time is dependent on the + * frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and + * portGET_RUN_TIME_COUNTER_VALUE() macros. + * + * \defgroup ulTaskGetIdleRunTimeCounter ulTaskGetIdleRunTimeCounter + * \ingroup TaskUtils + */ +configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; +configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction ); + * BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); + * @endcode + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * Sends a direct to task notification to a task, with an optional value and + * action. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * A task can use xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() to + * [optionally] block to wait for a notification to be pending. The task does + * not consume any CPU time while it is in the Blocked state. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their + * un-indexed equivalents). If the task was already in the Blocked state to + * wait for a notification when the notification arrives then the task will + * automatically be removed from the Blocked state (unblocked) and the + * notification cleared. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotify() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling xTaskNotify() is equivalent to calling xTaskNotifyIndexed() + * with the uxIndexToNotify parameter set to 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotify() does + * not have this parameter and always sends notifications to index 0. + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The target notification value is bitwise ORed with ulValue. + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * eIncrement - + * The target notification value is incremented. ulValue is not used and + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The target notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification at the + * same array index (the task already had a notification pending at that index). + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending at the + * same array index then the target notification value is set to ulValue and + * xTaskNotifyIndexed() will return pdPASS. If the task being notified already + * had a notification pending at the same array index then no action is + * performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification at the specified array index without the + * notification value at that index being updated. ulValue is not used and + * xTaskNotifyIndexed() always returns pdPASS in this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotifyIndexed xTaskNotifyIndexed + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) \ + xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction ) \ + xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL ) + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyAndQueryIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); + * BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue ); + * @endcode + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * xTaskNotifyAndQueryIndexed() performs the same operation as + * xTaskNotifyIndexed() with the addition that it also returns the subject + * task's prior notification value (the notification value at the time the + * function is called rather than when the function returns) in the additional + * pulPreviousNotifyValue parameter. + * + * xTaskNotifyAndQuery() performs the same operation as xTaskNotify() with the + * addition that it also returns the subject task's prior notification value + * (the notification value as it was at the time the function is called, rather + * than when the function returns) in the additional pulPreviousNotifyValue + * parameter. + * + * \defgroup xTaskNotifyAndQueryIndexed xTaskNotifyAndQueryIndexed + * \ingroup TaskNotifications + */ +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ + xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) +#define xTaskNotifyAndQueryIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotifyValue ) \ + xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); + * BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * A version of xTaskNotifyIndexed() that can be used from an interrupt service + * routine (ISR). + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block + * to wait for a notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their + * un-indexed equivalents). If the task was already in the Blocked state to + * wait for a notification when the notification arrives then the task will + * automatically be removed from the Blocked state (unblocked) and the + * notification cleared. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyFromISR() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling xTaskNotifyFromISR() is equivalent to calling + * xTaskNotifyIndexedFromISR() with the uxIndexToNotify parameter set to 0. + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyFromISR() + * does not have this parameter and always sends notifications to index 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNotify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotifyIndexedFromISR xTaskNotifyIndexedFromISR + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) \ + xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) \ + xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyAndQueryIndexedFromISR( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); + * BaseType_t xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * xTaskNotifyAndQueryIndexedFromISR() performs the same operation as + * xTaskNotifyIndexedFromISR() with the addition that it also returns the + * subject task's prior notification value (the notification value at the time + * the function is called rather than at the time the function returns) in the + * additional pulPreviousNotifyValue parameter. + * + * xTaskNotifyAndQueryFromISR() performs the same operation as + * xTaskNotifyFromISR() with the addition that it also returns the subject + * task's prior notification value (the notification value at the time the + * function is called rather than at the time the function returns) in the + * additional pulPreviousNotifyValue parameter. + * + * \defgroup xTaskNotifyAndQueryIndexedFromISR xTaskNotifyAndQueryIndexedFromISR + * \ingroup TaskNotifications + */ +#define xTaskNotifyAndQueryIndexedFromISR( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ + xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) \ + xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyWaitIndexed( UBaseType_t uxIndexToWaitOn, uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); + * + * BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); + * @endcode + * + * Waits for a direct to task notification to be pending at a given index within + * an array of direct to task notifications. + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWaitIndexed() or ulTaskNotifyTakeIndexed() (or their + * un-indexed equivalents). If the task was already in the Blocked state to + * wait for a notification when the notification arrives then the task will + * automatically be removed from the Blocked state (unblocked) and the + * notification cleared. + * + * A task can use xTaskNotifyWaitIndexed() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTakeIndexed() to [optionally] block + * to wait for a notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyWait() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling xTaskNotifyWait() is equivalent to calling + * xTaskNotifyWaitIndexed() with the uxIndexToWaitOn parameter set to 0. + * + * @param uxIndexToWaitOn The index within the calling task's array of + * notification values on which the calling task will wait for a notification to + * be received. uxIndexToWaitOn must be less than + * configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyWait() does + * not have this parameter and always waits for notifications on index 0. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICKS( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWaitIndexed xTaskNotifyWaitIndexed + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +#define xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) \ + xTaskGenericNotifyWait( tskDEFAULT_INDEX_TO_NOTIFY, ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) +#define xTaskNotifyWaitIndexed( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) \ + xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) ) + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify ); + * BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); + * @endcode + * + * Sends a direct to task notification to a particular index in the target + * task's notification array in a manner similar to giving a counting semaphore. + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * macros to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * xTaskNotifyGiveIndexed() is a helper macro intended for use when task + * notifications are used as light weight and faster binary or counting + * semaphore equivalents. Actual FreeRTOS semaphores are given using the + * xSemaphoreGive() API function, the equivalent action that instead uses a task + * notification is xTaskNotifyGiveIndexed(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotifyTakeIndexed() API function rather than the + * xTaskNotifyWaitIndexed() API function. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyGive() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling xTaskNotifyGive() is equivalent to calling + * xTaskNotifyGiveIndexed() with the uxIndexToNotify parameter set to 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyGive() + * does not have this parameter and always sends notifications to index 0. + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGiveIndexed xTaskNotifyGiveIndexed + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) \ + xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( 0 ), eIncrement, NULL ) +#define xTaskNotifyGiveIndexed( xTaskToNotify, uxIndexToNotify ) \ + xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + * @code{c} + * void vTaskNotifyGiveIndexedFromISR( TaskHandle_t xTaskHandle, UBaseType_t uxIndexToNotify, BaseType_t *pxHigherPriorityTaskWoken ); + * void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken ); + * @endcode + * + * A version of xTaskNotifyGiveIndexed() that can be called from an interrupt + * service routine (ISR). + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * vTaskNotifyGiveIndexedFromISR() is intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given from an ISR using the + * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses + * a task notification is vTaskNotifyGiveIndexedFromISR(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotifyTakeIndexed() API function rather than the + * xTaskNotifyWaitIndexed() API function. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyFromISR() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling xTaskNotifyGiveFromISR() is equivalent to calling + * xTaskNotifyGiveIndexedFromISR() with the uxIndexToNotify parameter set to 0. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param uxIndexToNotify The index within the target task's array of + * notification values to which the notification is to be sent. uxIndexToNotify + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. + * xTaskNotifyGiveFromISR() does not have this parameter and always sends + * notifications to index 0. + * + * @param pxHigherPriorityTaskWoken vTaskNotifyGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch + * should be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * \defgroup vTaskNotifyGiveIndexedFromISR vTaskNotifyGiveIndexedFromISR + * \ingroup TaskNotifications + */ +void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define vTaskNotifyGiveFromISR( xTaskToNotify, pxHigherPriorityTaskWoken ) \ + vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( pxHigherPriorityTaskWoken ) ) +#define vTaskNotifyGiveIndexedFromISR( xTaskToNotify, uxIndexToNotify, pxHigherPriorityTaskWoken ) \ + vTaskGenericNotifyGiveFromISR( ( xTaskToNotify ), ( uxIndexToNotify ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + * @code{c} + * uint32_t ulTaskNotifyTakeIndexed( UBaseType_t uxIndexToWaitOn, BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); + * + * uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); + * @endcode + * + * Waits for a direct to task notification on a particular index in the calling + * task's notification array in a manner similar to taking a counting semaphore. + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment one of the task's notification values. In + * that way task notifications can be used to send data to a task, or be used as + * light weight and fast binary or counting semaphores. + * + * ulTaskNotifyTakeIndexed() is intended for use when a task notification is + * used as a faster and lighter weight binary or counting semaphore alternative. + * Actual FreeRTOS semaphores are taken using the xSemaphoreTake() API function, + * the equivalent action that instead uses a task notification is + * ulTaskNotifyTakeIndexed(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGiveIndexed() + * macro, or xTaskNotifyIndex() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTakeIndexed() can either clear the task's notification value at + * the array index specified by the uxIndexToWaitOn parameter to zero on exit, + * in which case the notification value acts like a binary semaphore, or + * decrement the notification value on exit, in which case the notification + * value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTakeIndexed() to [optionally] block to wait for + * a notification. The task does not consume any CPU time while it is in the + * Blocked state. + * + * Where as xTaskNotifyWaitIndexed() will return when a notification is pending, + * ulTaskNotifyTakeIndexed() will return when the task's notification value is + * not zero. + * + * **NOTE** Each notification within the array operates independently - a task + * can only block on one notification within the array at a time and will not be + * unblocked by a notification sent to any other array index. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. ulTaskNotifyTake() is the original API function, and remains backward + * compatible by always operating on the notification value at index 0 in the + * array. Calling ulTaskNotifyTake() is equivalent to calling + * ulTaskNotifyTakeIndexed() with the uxIndexToWaitOn parameter set to 0. + * + * @param uxIndexToWaitOn The index within the calling task's array of + * notification values on which the calling task will wait for a notification to + * be non-zero. uxIndexToWaitOn must be less than + * configTASK_NOTIFICATION_ARRAY_ENTRIES. xTaskNotifyTake() does + * not have this parameter and always waits for notifications on index 0. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICKS( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTakeIndexed ulTaskNotifyTakeIndexed + * \ingroup TaskNotifications + */ +uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +#define ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ) \ + ulTaskGenericNotifyTake( ( tskDEFAULT_INDEX_TO_NOTIFY ), ( xClearCountOnExit ), ( xTicksToWait ) ) +#define ulTaskNotifyTakeIndexed( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ) \ + ulTaskGenericNotifyTake( ( uxIndexToWaitOn ), ( xClearCountOnExit ), ( xTicksToWait ) ) + +/** + * task. h + * @code{c} + * BaseType_t xTaskNotifyStateClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToCLear ); + * + * BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); + * @endcode + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * If a notification is sent to an index within the array of notifications then + * the notification at that index is said to be 'pending' until it is read or + * explicitly cleared by the receiving task. xTaskNotifyStateClearIndexed() + * is the function that clears a pending notification without reading the + * notification value. The notification value at the same array index is not + * altered. Set xTask to NULL to clear the notification state of the calling + * task. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. xTaskNotifyStateClear() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling xTaskNotifyStateClear() is equivalent to calling + * xTaskNotifyStateClearIndexed() with the uxIndexToNotify parameter set to 0. + * + * @param xTask The handle of the RTOS task that will have a notification state + * cleared. Set xTask to NULL to clear a notification state in the calling + * task. To obtain a task's handle create the task using xTaskCreate() and + * make use of the pxCreatedTask parameter, or create the task using + * xTaskCreateStatic() and store the returned value, or use the task's name in + * a call to xTaskGetHandle(). + * + * @param uxIndexToClear The index within the target task's array of + * notification values to act upon. For example, setting uxIndexToClear to 1 + * will clear the state of the notification at index 1 within the array. + * uxIndexToClear must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. + * ulTaskNotifyStateClear() does not have this parameter and always acts on the + * notification at index 0. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * + * \defgroup xTaskNotifyStateClearIndexed xTaskNotifyStateClearIndexed + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) PRIVILEGED_FUNCTION; +#define xTaskNotifyStateClear( xTask ) \ + xTaskGenericNotifyStateClear( ( xTask ), ( tskDEFAULT_INDEX_TO_NOTIFY ) ) +#define xTaskNotifyStateClearIndexed( xTask, uxIndexToClear ) \ + xTaskGenericNotifyStateClear( ( xTask ), ( uxIndexToClear ) ) + +/** + * task. h + * @code{c} + * uint32_t ulTaskNotifyValueClearIndexed( TaskHandle_t xTask, UBaseType_t uxIndexToClear, uint32_t ulBitsToClear ); + * + * uint32_t ulTaskNotifyValueClear( TaskHandle_t xTask, uint32_t ulBitsToClear ); + * @endcode + * + * See https://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for these + * functions to be available. + * + * Each task has a private array of "notification values" (or 'notifications'), + * each of which is a 32-bit unsigned integer (uint32_t). The constant + * configTASK_NOTIFICATION_ARRAY_ENTRIES sets the number of indexes in the + * array, and (for backward compatibility) defaults to 1 if left undefined. + * Prior to FreeRTOS V10.4.0 there was only one notification value per task. + * + * ulTaskNotifyValueClearIndexed() clears the bits specified by the + * ulBitsToClear bit mask in the notification value at array index uxIndexToClear + * of the task referenced by xTask. + * + * Backward compatibility information: + * Prior to FreeRTOS V10.4.0 each task had a single "notification value", and + * all task notification API functions operated on that value. Replacing the + * single notification value with an array of notification values necessitated a + * new set of API functions that could address specific notifications within the + * array. ulTaskNotifyValueClear() is the original API function, and remains + * backward compatible by always operating on the notification value at index 0 + * within the array. Calling ulTaskNotifyValueClear() is equivalent to calling + * ulTaskNotifyValueClearIndexed() with the uxIndexToClear parameter set to 0. + * + * @param xTask The handle of the RTOS task that will have bits in one of its + * notification values cleared. Set xTask to NULL to clear bits in a + * notification value of the calling task. To obtain a task's handle create the + * task using xTaskCreate() and make use of the pxCreatedTask parameter, or + * create the task using xTaskCreateStatic() and store the returned value, or + * use the task's name in a call to xTaskGetHandle(). + * + * @param uxIndexToClear The index within the target task's array of + * notification values in which to clear the bits. uxIndexToClear + * must be less than configTASK_NOTIFICATION_ARRAY_ENTRIES. + * ulTaskNotifyValueClear() does not have this parameter and always clears bits + * in the notification value at index 0. + * + * @param ulBitsToClear Bit mask of the bits to clear in the notification value of + * xTask. Set a bit to 1 to clear the corresponding bits in the task's notification + * value. Set ulBitsToClear to 0xffffffff (UINT_MAX on 32-bit architectures) to clear + * the notification value to 0. Set ulBitsToClear to 0 to query the task's + * notification value without clearing any bits. + * + * + * @return The value of the target task's notification value before the bits + * specified by ulBitsToClear were cleared. + * \defgroup ulTaskNotifyValueClear ulTaskNotifyValueClear + * \ingroup TaskNotifications + */ +uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; +#define ulTaskNotifyValueClear( xTask, ulBitsToClear ) \ + ulTaskGenericNotifyValueClear( ( xTask ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulBitsToClear ) ) +#define ulTaskNotifyValueClearIndexed( xTask, uxIndexToClear, ulBitsToClear ) \ + ulTaskGenericNotifyValueClear( ( xTask ), ( uxIndexToClear ), ( ulBitsToClear ) ) + +/** + * task.h + * @code{c} + * void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); + * @endcode + * + * Capture the current time for future use with xTaskCheckForTimeOut(). + * + * @param pxTimeOut Pointer to a timeout object into which the current time + * is to be captured. The captured time includes the tick count and the number + * of times the tick count has overflowed since the system first booted. + * \defgroup vTaskSetTimeOutState vTaskSetTimeOutState + * \ingroup TaskCtrl + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/** + * task.h + * @code{c} + * BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); + * @endcode + * + * Determines if pxTicksToWait ticks has passed since a time was captured + * using a call to vTaskSetTimeOutState(). The captured time includes the tick + * count and the number of times the tick count has overflowed. + * + * @param pxTimeOut The time status as captured previously using + * vTaskSetTimeOutState. If the timeout has not yet occurred, it is updated + * to reflect the current time status. + * @param pxTicksToWait The number of ticks to check for timeout i.e. if + * pxTicksToWait ticks have passed since pxTimeOut was last updated (either by + * vTaskSetTimeOutState() or xTaskCheckForTimeOut()), the timeout has occurred. + * If the timeout has not occurred, pxTicksToWait is updated to reflect the + * number of remaining ticks. + * + * @return If timeout has occurred, pdTRUE is returned. Otherwise pdFALSE is + * returned and pxTicksToWait is updated to reflect the number of remaining + * ticks. + * + * @see https://www.FreeRTOS.org/xTaskCheckForTimeOut.html + * + * Example Usage: + * @code{c} + * // Driver library function used to receive uxWantedBytes from an Rx buffer + * // that is filled by a UART interrupt. If there are not enough bytes in the + * // Rx buffer then the task enters the Blocked state until it is notified that + * // more data has been placed into the buffer. If there is still not enough + * // data then the task re-enters the Blocked state, and xTaskCheckForTimeOut() + * // is used to re-calculate the Block time to ensure the total amount of time + * // spent in the Blocked state does not exceed MAX_TIME_TO_WAIT. This + * // continues until either the buffer contains at least uxWantedBytes bytes, + * // or the total amount of time spent in the Blocked state reaches + * // MAX_TIME_TO_WAIT - at which point the task reads however many bytes are + * // available up to a maximum of uxWantedBytes. + * + * size_t xUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes ) + * { + * size_t uxReceived = 0; + * TickType_t xTicksToWait = MAX_TIME_TO_WAIT; + * TimeOut_t xTimeOut; + * + * // Initialize xTimeOut. This records the time at which this function + * // was entered. + * vTaskSetTimeOutState( &xTimeOut ); + * + * // Loop until the buffer contains the wanted number of bytes, or a + * // timeout occurs. + * while( UART_bytes_in_rx_buffer( pxUARTInstance ) < uxWantedBytes ) + * { + * // The buffer didn't contain enough data so this task is going to + * // enter the Blocked state. Adjusting xTicksToWait to account for + * // any time that has been spent in the Blocked state within this + * // function so far to ensure the total amount of time spent in the + * // Blocked state does not exceed MAX_TIME_TO_WAIT. + * if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE ) + * { + * //Timed out before the wanted number of bytes were available, + * // exit the loop. + * break; + * } + * + * // Wait for a maximum of xTicksToWait ticks to be notified that the + * // receive interrupt has placed more data into the buffer. + * ulTaskNotifyTake( pdTRUE, xTicksToWait ); + * } + * + * // Attempt to read uxWantedBytes from the receive buffer into pucBuffer. + * // The actual number of bytes read (which might be less than + * // uxWantedBytes) is returned. + * uxReceived = UART_read_from_receive_buffer( pxUARTInstance, + * pucBuffer, + * uxWantedBytes ); + * + * return uxReceived; + * } + * @endcode + * \defgroup xTaskCheckForTimeOut xTaskCheckForTimeOut + * \ingroup TaskCtrl + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task.h + * @code{c} + * BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ); + * @endcode + * + * This function corrects the tick count value after the application code has held + * interrupts disabled for an extended period resulting in tick interrupts having + * been missed. + * + * This function is similar to vTaskStepTick(), however, unlike + * vTaskStepTick(), xTaskCatchUpTicks() may move the tick count forward past a + * time at which a task should be removed from the blocked state. That means + * tasks may have to be removed from the blocked state as the tick count is + * moved. + * + * @param xTicksToCatchUp The number of tick interrupts that have been missed due to + * interrupts being disabled. Its value is not computed automatically, so must be + * computed by the application writer. + * + * @return pdTRUE if moving the tick count forward resulted in a task leaving the + * blocked state and a context switch being performed. Otherwise pdFALSE. + * + * \defgroup xTaskCatchUpTicks xTaskCatchUpTicks + * \ingroup TaskCtrl + */ +BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; + + +/*----------------------------------------------------------- +* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES +*----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning task's priority) to insert the list item into the event list in task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks, the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, + const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, + const TickType_t xItemValue, + const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, + TickType_t xTicksToWait, + const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, + const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +portDONT_DISCARD void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, + UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTaskNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, + const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critical + * section. + */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +#if ( portUSING_MPU_WRAPPERS == 1 ) + +/* + * For internal use only. Get MPU settings associated with a task. + */ + xMPU_SETTINGS * xTaskGetMPUSettings( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +#endif /* portUSING_MPU_WRAPPERS */ + + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/* + * For internal use only. Grant/Revoke a task's access to a kernel object. + */ + void vGrantAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) PRIVILEGED_FUNCTION; + void vRevokeAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Grant/Revoke a task's access to a kernel object. + */ + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION; + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION; + +#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ +#endif /* INC_TASK_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h b/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h new file mode 100644 index 0000000..0900edb --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h @@ -0,0 +1,1403 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -save -e537 This headers are only multiply included if the application code + * happens to also be including task.h. */ +#include "task.h" +/*lint -restore */ + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/*----------------------------------------------------------- +* MACROS AND DEFINITIONS +*----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to + * be used solely through the macros that make up the public software timer API, + * as defined below. The commands that are sent from interrupts must use the + * highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task + * or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tmrTimerControl * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (* PendedFunction_t)( void *, + uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * BaseType_t xAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. Time timer period must be greater than 0. + * + * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created because there is + * insufficient FreeRTOS heap remaining to allocate the timer + * structures then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * ( x + 1 ) ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const BaseType_t xAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * BaseType_t xAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * https://www.FreeRTOS.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. The timer period must be greater than 0. + * + * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If xAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const BaseType_t xAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void * pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ +#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) \ + xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + void * pvParameter1, + uint32_t ulParameter2, + BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + void * pvParameter1, + uint32_t ulParameter2, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * void vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t xAutoReload ); + * + * Updates a timer to be either an auto-reload timer, in which case the timer + * automatically resets itself each time it expires, or a one-shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being updated. + * + * @param xAutoReload If xAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the timer's period (see the + * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If + * xAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + */ +void vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t xAutoReload ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ); + * + * Queries a timer to determine if it is an auto-reload timer, in which case the timer + * automatically resets itself each time it expires, or a one-shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being queried. + * + * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise + * pdFALSE is returned. + */ +BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ); + * + * Queries a timer to determine if it is an auto-reload timer, in which case the timer + * automatically resets itself each time it expires, or a one-shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being queried. + * + * @return If the timer is an auto-reload timer then pdTRUE is returned, otherwise + * pdFALSE is returned. + */ +UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); + * + * Returns the time in ticks at which the timer will expire. If this is less + * than the current tick count then the expiry time has overflowed from the + * current time. + * + * @param xTimer The handle of the timer being queried. + * + * @return If the timer is running then the time in ticks at which the timer + * will next expire is returned. If the timer is not running then the return + * value is undefined. + */ +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer, + * StaticTimer_t ** ppxTimerBuffer ); + * + * Retrieve pointer to a statically created timer's data structure + * buffer. This is the same buffer that is supplied at the time of + * creation. + * + * @param xTimer The timer for which to retrieve the buffer. + * + * @param ppxTaskBuffer Used to return a pointer to the timers's data + * structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#if ( configUSE_TRACE_FACILITY == 1 ) + void vTimerSetTimerNumber( TimerHandle_t xTimer, + UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; +#endif + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/** + * task.h + * @code{c} + * void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, StackType_t ** ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) + * @endcode + * + * This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Timer Task TCB. This function is required when + * configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION + * + * @param ppxTimerTaskTCBBuffer A handle to a statically allocated TCB buffer + * @param ppxTimerTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task + * @param pulTimerTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer + */ + void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ); + +#endif + +#if ( configUSE_DAEMON_TASK_STARTUP_HOOK != 0 ) + +/** + * timers.h + * @code{c} + * void vApplicationDaemonTaskStartupHook( void ); + * @endcode + * + * This hook function is called form the timer task once when the task starts running. + */ + void vApplicationDaemonTaskStartupHook( void ); + +#endif + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ +#endif /* TIMERS_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/list.c b/Middlewares/Third_Party/FreeRTOS/Source/list.c new file mode 100644 index 0000000..6129aff --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/list.c @@ -0,0 +1,226 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "list.h" + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified + * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be + * defined for the header files above, but not in this file, in order to + * generate the correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/*----------------------------------------------------------- +* PUBLIC LIST API documented in list.h +*----------------------------------------------------------*/ + +void vListInitialise( List_t * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + * end of the list. To initialise the list the list end is inserted + * as the only list entry. */ + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) ); + + /* The list end value is the highest possible value in the list to + * ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + * when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */ + #if ( configUSE_MINI_LIST_ITEM == 0 ) + { + pxList->xListEnd.pvOwner = NULL; + pxList->xListEnd.pxContainer = NULL; + listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) ); + } + #endif + + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; + + /* Write known values into the list if + * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); + listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( ListItem_t * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pxContainer = NULL; + + /* Write known values into the list item if + * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); + listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( List_t * const pxList, + ListItem_t * const pxNewListItem ) +{ + ListItem_t * const pxIndex = pxList->pxIndex; + + /* Only effective when configASSERT() is also defined, these tests may catch + * the list data structures being overwritten in memory. They will not catch + * data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert a new list item into pxList, but rather than sort the list, + * makes the new list item the last item to be removed by a call to + * listGET_OWNER_OF_NEXT_ENTRY(). */ + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( List_t * const pxList, + ListItem_t * const pxNewListItem ) +{ + ListItem_t * pxIterator; + const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; + + /* Only effective when configASSERT() is also defined, these tests may catch + * the list data structures being overwritten in memory. They will not catch + * data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert the new list item into the list, sorted in xItemValue order. + * + * If the list already contains a list item with the same item value then the + * new list item should be placed after it. This ensures that TCBs which are + * stored in ready lists (all of which have the same xItemValue value) get a + * share of the CPU. However, if the xItemValue is the same as the back marker + * the iteration loop below will not end. Therefore the value is checked + * first, and the algorithm slightly modified if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + * If you find your application is crashing here then likely causes are + * listed below. In addition see https://www.FreeRTOS.org/FAQHelp.html for + * more tips, and ensure configASSERT() is defined! + * https://www.FreeRTOS.org/a00110.html#configASSERT + * + * 1) Stack overflow - + * see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html + * 2) Incorrect interrupt priority assignment, especially on Cortex-M + * parts where numerically high priority values denote low actual + * interrupt priorities, which can seem counter intuitive. See + * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition + * of configMAX_SYSCALL_INTERRUPT_PRIORITY on + * https://www.FreeRTOS.org/a00110.html + * 3) Calling an API function from within a critical section or when + * the scheduler is suspended, or calling an API function that does + * not end in "FromISR" from an interrupt. + * 4) Using a queue or semaphore before it has been initialised or + * before the scheduler has been started (are interrupts firing + * before vTaskStartScheduler() has been called?). + * 5) If the FreeRTOS port supports interrupt nesting then ensure that + * the priority of the tick interrupt is at or below + * configMAX_SYSCALL_INTERRUPT_PRIORITY. + **********************************************************************/ + + for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ + { + /* There is nothing to do here, just iterating to the wanted + * insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + * item later. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) +{ +/* The list item knows which list it is in. Obtain the list from the list + * item. */ + List_t * const pxList = pxItemToRemove->pxContainer; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxItemToRemove->pxContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c b/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c new file mode 100644 index 0000000..17efcdb --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c @@ -0,0 +1,2545 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + #error Access control list is not available with this MPU wrapper. Please set configENABLE_ACCESS_CONTROL_LIST to 0. + #endif + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, + const char * const pcName, + uint16_t usStackDepth, + void * pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxPriority = uxPriority & ~( portPRIVILEGE_BIT ); + portMEMORY_BARRIER(); + + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + } + + return xReturn; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxPriority = uxPriority & ~( portPRIVILEGE_BIT ); + portMEMORY_BARRIER(); + + xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + } + + return xReturn; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskDelete( pxTaskToDelete ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskDelete( pxTaskToDelete ); + } + } + #endif /* if ( INCLUDE_vTaskDelete == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskDelayUntil == 1 ) + BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + } + + return xReturn; + } + #endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskAbortDelay( xTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskAbortDelay( xTask ); + } + + return xReturn; + } + #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskDelay( xTicksToDelay ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskDelay( xTicksToDelay ); + } + } + #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxTaskPriorityGet( pxTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxTaskPriorityGet( pxTask ); + } + + return uxReturn; + } + #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, + UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskPrioritySet( pxTask, uxNewPriority ); + } + } + #endif /* if ( INCLUDE_vTaskPrioritySet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_eTaskGetState == 1 ) + eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + eTaskState eReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + eReturn = eTaskGetState( pxTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + eReturn = eTaskGetState( pxTask ); + } + + return eReturn; + } + #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + } + } + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + xReturn = xTaskGetIdleTaskHandle(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGetIdleTaskHandle(); + } + + return xReturn; + } + #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskSuspend( pxTaskToSuspend ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskSuspend( pxTaskToSuspend ); + } + } + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskResume( pxTaskToResume ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskResume( pxTaskToResume ); + } + } + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskSuspendAll( void ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskSuspendAll(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskSuspendAll(); + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xTaskResumeAll( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskResumeAll(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskResumeAll(); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGetTickCount(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGetTickCount(); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxTaskGetNumberOfTasks(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxTaskGetNumberOfTasks(); + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */ + { + char * pcReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + pcReturn = pcTaskGetName( xTaskToQuery ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + pcReturn = pcTaskGetName( xTaskToQuery ); + } + + return pcReturn; + } +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetHandle == 1 ) + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGetHandle( pcNameToQuery ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGetHandle( pcNameToQuery ); + } + + return xReturn; + } + #endif /* if ( INCLUDE_xTaskGetHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskList( char * pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskList( pcWriteBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskList( pcWriteBuffer ); + } + } + #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskGetRunTimeStats( char * pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskGetRunTimeStats( pcWriteBuffer ); + } + } + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) /* FREERTOS_SYSTEM_CALL */ + { + configRUN_TIME_COUNTER_TYPE xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = ulTaskGetIdleRunTimePercent(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = ulTaskGetIdleRunTimePercent(); + } + + return xReturn; + } + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */ + { + configRUN_TIME_COUNTER_TYPE xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = ulTaskGetIdleRunTimeCounter(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = ulTaskGetIdleRunTimeCounter(); + } + + return xReturn; + } + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + } + } + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHookFunction_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGetApplicationTaskTag( xTask ); + } + + return xReturn; + } + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + } + } + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */ + { + void * pvReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + } + + return pvReturn; + } + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + } + + return xReturn; + } + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * pxTaskStatusArray, + UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + } + + return uxReturn; + } + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskCatchUpTicks( xTicksToCatchUp ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskCatchUpTicks( xTicksToCatchUp ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + } + + return uxReturn; + } + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + configSTACK_DEPTH_TYPE uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + } + + return uxReturn; + } + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + xReturn = xTaskGetCurrentTaskHandle(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGetCurrentTaskHandle(); + } + + return xReturn; + } + #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetSchedulerState == 1 ) + BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGetSchedulerState(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGetSchedulerState(); + } + + return xReturn; + } + #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTaskSetTimeOutState( pxTimeOut ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTaskSetTimeOutState( pxTimeOut ); + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGenericNotify( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGenericNotify( xTaskToNotify, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue ); + } + + return xReturn; + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGenericNotifyWait( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + } + + return xReturn; + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + uint32_t ulReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + ulReturn = ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + ulReturn = ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); + } + + return ulReturn; + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTaskGenericNotifyStateClear( xTask, uxIndexToClear ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTaskGenericNotifyStateClear( xTask, uxIndexToClear ); + } + + return xReturn; + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* FREERTOS_SYSTEM_CALL */ + { + uint32_t ulReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + ulReturn = ulTaskGenericNotifyValueClear( xTask, uxIndexToClear, ulBitsToClear ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + ulReturn = ulTaskGenericNotifyValueClear( xTask, uxIndexToClear, ulBitsToClear ); + } + + return ulReturn; + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, + UBaseType_t uxItemSize, + uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + } + + return xReturn; + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + } + + return xReturn; + } + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, + BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxQueueMessagesWaiting( pxQueue ); + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxQueueSpacesAvailable( xQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxQueueSpacesAvailable( xQueue ); + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREERTOS_SYSTEM_CALL */ + { + void * xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueGetMutexHolder( xSemaphore ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueGetMutexHolder( xSemaphore ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueCreateMutex( ucQueueType ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueCreateMutex( ucQueueType ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, + UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + } + + return xReturn; + } + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueGiveMutexRecursive( xMutex ); + } + + return xReturn; + } + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueCreateSet( uxEventQueueLength ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueCreateSet( uxEventQueueLength ); + } + + return xReturn; + } + #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetMemberHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + } + + return xReturn; + } + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + } + + return xReturn; + } + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + } + + return xReturn; + } + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcName ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vQueueAddToRegistry( xQueue, pcName ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vQueueAddToRegistry( xQueue, pcName ); + } + } + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vQueueUnregisterQueue( xQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vQueueUnregisterQueue( xQueue ); + } + } + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + const char * pcReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + pcReturn = pcQueueGetName( xQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + pcReturn = pcQueueGetName( xQueue ); + } + + return pcReturn; + } + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vQueueDelete( xQueue ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vQueueDelete( xQueue ); + } + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + void * pvReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + pvReturn = pvTimerGetTimerID( xTimer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + pvReturn = pvTimerGetTimerID( xTimer ); + } + + return pvReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTimerSetTimerID( xTimer, pvNewID ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTimerSetTimerID( xTimer, pvNewID ); + } + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTimerIsTimerActive( xTimer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTimerIsTimerActive( xTimer ); + } + + return xReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTimerGetTimerDaemonTaskHandle(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTimerGetTimerDaemonTaskHandle(); + } + + return xReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vTimerSetReloadMode( xTimer, uxAutoReload ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vTimerSetReloadMode( xTimer, uxAutoReload ); + } + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) + { + UBaseType_t uxReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + uxReturn = uxTimerGetReloadMode( xTimer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + uxReturn = uxTimerGetReloadMode( xTimer ); + } + + return uxReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + const char * pcReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + pcReturn = pcTimerGetName( xTimer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + pcReturn = pcTimerGetName( xTimer ); + } + + return pcReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTimerGetPeriod( xTimer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTimerGetPeriod( xTimer ); + } + + return xReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTimerGetExpiryTime( xTimer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTimerGetExpiryTime( xTimer ); + } + + return xReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + } + + return xReturn; + } + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreate( void ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupCreate(); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupCreate(); + } + + return xReturn; + } + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); + } + + return xReturn; + } + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vEventGroupDelete( xEventGroup ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vEventGroupDelete( xEventGroup ); + } + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + vStreamBufferDelete( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + vStreamBufferDelete( xStreamBuffer ); + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferIsFull( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferIsFull( xStreamBuffer ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferReset( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferReset( xStreamBuffer ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + + /** + * Streambuffer application level callback functionality is disabled for MPU + * enabled ports. + */ + configASSERT( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ); + + if( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ) + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + NULL, + NULL ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + NULL, + NULL ); + } + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + xReturn = NULL; + } + + return xReturn; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + + /** + * Streambuffer application level callback functionality is disabled for MPU + * enabled ports. + */ + configASSERT( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ); + + if( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ) + { + if( portIS_PRIVILEGED() == pdFALSE ) + { + portRAISE_PRIVILEGE(); + portMEMORY_BARRIER(); + + xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + pucStreamBufferStorageArea, + pxStaticStreamBuffer, + NULL, + NULL ); + portMEMORY_BARRIER(); + + portRESET_PRIVILEGE(); + portMEMORY_BARRIER(); + } + else + { + xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + pucStreamBufferStorageArea, + pxStaticStreamBuffer, + NULL, + NULL ); + } + } + else + { + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + xReturn = NULL; + } + + return xReturn; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + +/* Functions that the application writer wants to execute in privileged mode + * can be defined in application_defined_privileged_functions.h. The functions + * must take the same format as those above whereby the privilege state on exit + * equals the privilege state on entry. For example: + * + * void MPU_FunctionName( [parameters ] ) FREERTOS_SYSTEM_CALL; + * void MPU_FunctionName( [parameters ] ) + * { + * if( portIS_PRIVILEGED() == pdFALSE ) + * { + * portRAISE_PRIVILEGE(); + * portMEMORY_BARRIER(); + * + * FunctionName( [parameters ] ); + * portMEMORY_BARRIER(); + * + * portRESET_PRIVILEGE(); + * portMEMORY_BARRIER(); + * } + * else + * { + * FunctionName( [parameters ] ); + * } + * } + */ + + #if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" + #endif +/*-----------------------------------------------------------*/ + +#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers_v2.c b/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers_v2.c new file mode 100644 index 0000000..f82762d --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers_v2.c @@ -0,0 +1,5054 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" +#include "mpu_syscall_numbers.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/*-----------------------------------------------------------*/ + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE + #error configPROTECTED_KERNEL_OBJECT_POOL_SIZE must be defined to maximum number of kernel objects in the application. + #endif + +/** + * @brief Offset added to the index before returning to the user. + * + * If the actual handle is stored at index i, ( i + INDEX_OFFSET ) + * is returned to the user. + */ + #define INDEX_OFFSET 1 + +/** + * @brief Opaque type for a kernel object. + */ + struct OpaqueObject; + typedef struct OpaqueObject * OpaqueObjectHandle_t; + +/** + * @brief Defines kernel object in the kernel object pool. + */ + typedef struct KernelObject + { + OpaqueObjectHandle_t xInternalObjectHandle; + uint32_t ulKernelObjectType; + void * pvKernelObjectData; + } KernelObject_t; + +/** + * @brief Kernel object types. + */ + #define KERNEL_OBJECT_TYPE_INVALID ( 0UL ) + #define KERNEL_OBJECT_TYPE_QUEUE ( 1UL ) + #define KERNEL_OBJECT_TYPE_TASK ( 2UL ) + #define KERNEL_OBJECT_TYPE_STREAM_BUFFER ( 3UL ) + #define KERNEL_OBJECT_TYPE_EVENT_GROUP ( 4UL ) + #define KERNEL_OBJECT_TYPE_TIMER ( 5UL ) + +/** + * @brief Checks whether an external index is valid or not. + */ + #define IS_EXTERNAL_INDEX_VALID( lIndex ) \ + ( ( ( lIndex ) >= INDEX_OFFSET ) && \ + ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + INDEX_OFFSET ) ) ) + +/** + * @brief Checks whether an internal index is valid or not. + */ + #define IS_INTERNAL_INDEX_VALID( lIndex ) \ + ( ( ( lIndex ) >= 0 ) && \ + ( ( lIndex ) < ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE ) ) ) + +/** + * @brief Converts an internal index into external. + */ + #define CONVERT_TO_EXTERNAL_INDEX( lIndex ) ( ( lIndex ) + INDEX_OFFSET ) + +/** + * @brief Converts an external index into internal. + */ + #define CONVERT_TO_INTERNAL_INDEX( lIndex ) ( ( lIndex ) - INDEX_OFFSET ) + +/** + * @brief Max value that fits in a uint32_t type. + */ + #define mpuUINT32_MAX ( ~( ( uint32_t ) 0 ) ) + +/** + * @brief Check if multiplying a and b will result in overflow. + */ + #define mpuMULTIPLY_UINT32_WILL_OVERFLOW( a, b ) ( ( ( a ) > 0 ) && ( ( b ) > ( mpuUINT32_MAX / ( a ) ) ) ) + +/** + * @brief Get the index of a free slot in the kernel object pool. + * + * If a free slot is found, this function marks the slot as + * "not free". + * + * @return Index of a free slot is returned, if a free slot is + * found. Otherwise -1 is returned. + */ + static int32_t MPU_GetFreeIndexInKernelObjectPool( void ) PRIVILEGED_FUNCTION; + +/** + * @brief Set the given index as free in the kernel object pool. + * + * @param lIndex The index to set as free. + */ + static void MPU_SetIndexFreeInKernelObjectPool( int32_t lIndex ) PRIVILEGED_FUNCTION; + +/** + * @brief Get the index at which a given kernel object is stored. + * + * @param xHandle The given kernel object handle. + * @param ulKernelObjectType The kernel object type. + * + * @return Index at which the kernel object is stored if it is a valid + * handle, -1 otherwise. + */ + static int32_t MPU_GetIndexForHandle( OpaqueObjectHandle_t xHandle, + uint32_t ulKernelObjectType ) PRIVILEGED_FUNCTION; + +/** + * @brief Store the given kernel object handle at the given index in + * the kernel object pool. + * + * @param lIndex Index to store the given handle at. + * @param xHandle Kernel object handle to store. + * @param pvKernelObjectData The data associated with the kernel object. + * Currently, only used for timer objects to store timer callback. + * @param ulKernelObjectType The kernel object type. + */ + static void MPU_StoreHandleAndDataAtIndex( int32_t lIndex, + OpaqueObjectHandle_t xHandle, + void * pvKernelObjectData, + uint32_t ulKernelObjectType ) PRIVILEGED_FUNCTION; + +/** + * @brief Get the kernel object handle at the given index from + * the kernel object pool. + * + * @param lIndex Index at which to get the kernel object handle. + * @param ulKernelObjectType The kernel object type. + * + * @return The kernel object handle at the index. + */ + static OpaqueObjectHandle_t MPU_GetHandleAtIndex( int32_t lIndex, + uint32_t ulKernelObjectType ) PRIVILEGED_FUNCTION; + + #if ( configUSE_TIMERS == 1 ) + +/** + * @brief The function registered as callback for all the timers. + * + * We intercept all the timer callbacks so that we can call application + * callbacks with opaque handle. + * + * @param xInternalHandle The internal timer handle. + */ + static void MPU_TimerCallback( TimerHandle_t xInternalHandle ) PRIVILEGED_FUNCTION; + + #endif /* #if ( configUSE_TIMERS == 1 ) */ + +/* + * Wrappers to keep all the casting in one place. + */ + #define MPU_StoreQueueHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueHandleAtIndex( lIndex ) ( QueueHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + + #if ( configUSE_QUEUE_SETS == 1 ) + #define MPU_StoreQueueSetHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueSetHandleAtIndex( lIndex ) ( QueueSetHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_StoreQueueSetMemberHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetQueueSetMemberHandleAtIndex( lIndex ) ( QueueSetMemberHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_QUEUE ) + #define MPU_GetIndexForQueueSetMemberHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_QUEUE ) + #endif + +/* + * Wrappers to keep all the casting in one place for Task APIs. + */ + #define MPU_StoreTaskHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_TASK ) + #define MPU_GetTaskHandleAtIndex( lIndex ) ( TaskHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_TASK ) + #define MPU_GetIndexForTaskHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_TASK ) + +/* + * Wrappers to keep all the casting in one place for Event Group APIs. + */ + #define MPU_StoreEventGroupHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_GetEventGroupHandleAtIndex( lIndex ) ( EventGroupHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + #define MPU_GetIndexForEventGroupHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_EVENT_GROUP ) + +/* + * Wrappers to keep all the casting in one place for Stream Buffer APIs. + */ + #define MPU_StoreStreamBufferHandleAtIndex( lIndex, xHandle ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, NULL, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_GetStreamBufferHandleAtIndex( lIndex ) ( StreamBufferHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + #define MPU_GetIndexForStreamBufferHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_STREAM_BUFFER ) + + #if ( configUSE_TIMERS == 1 ) + +/* + * Wrappers to keep all the casting in one place for Timer APIs. + */ + #define MPU_StoreTimerHandleAtIndex( lIndex, xHandle, pxApplicationCallback ) MPU_StoreHandleAndDataAtIndex( lIndex, ( OpaqueObjectHandle_t ) xHandle, ( void * ) pxApplicationCallback, KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_GetTimerHandleAtIndex( lIndex ) ( TimerHandle_t ) MPU_GetHandleAtIndex( lIndex, KERNEL_OBJECT_TYPE_TIMER ) + #define MPU_GetIndexForTimerHandle( xHandle ) MPU_GetIndexForHandle( ( OpaqueObjectHandle_t ) xHandle, KERNEL_OBJECT_TYPE_TIMER ) + + #endif /* #if ( configUSE_TIMERS == 1 ) */ + +/*-----------------------------------------------------------*/ + +/** + * @brief Kernel object pool. + */ + PRIVILEGED_DATA static KernelObject_t xKernelObjectPool[ configPROTECTED_KERNEL_OBJECT_POOL_SIZE ] = { NULL }; +/*-----------------------------------------------------------*/ + + static int32_t MPU_GetFreeIndexInKernelObjectPool( void ) /* PRIVILEGED_FUNCTION */ + { + int32_t i, lFreeIndex = -1; + + /* This function is called only from resource create APIs + * which are not supposed to be called from ISRs. Therefore, + * we only need to suspend the scheduler and do not require + * critical section. */ + vTaskSuspendAll(); + { + for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ ) + { + if( xKernelObjectPool[ i ].xInternalObjectHandle == NULL ) + { + /* Mark this index as not free. */ + xKernelObjectPool[ i ].xInternalObjectHandle = ( OpaqueObjectHandle_t ) ( ~0 ); + lFreeIndex = i; + break; + } + } + } + xTaskResumeAll(); + + return lFreeIndex; + } +/*-----------------------------------------------------------*/ + + static void MPU_SetIndexFreeInKernelObjectPool( int32_t lIndex ) /* PRIVILEGED_FUNCTION */ + { + configASSERT( IS_INTERNAL_INDEX_VALID( lIndex ) != pdFALSE ); + + taskENTER_CRITICAL(); + { + xKernelObjectPool[ lIndex ].xInternalObjectHandle = NULL; + xKernelObjectPool[ lIndex ].ulKernelObjectType = KERNEL_OBJECT_TYPE_INVALID; + xKernelObjectPool[ lIndex ].pvKernelObjectData = NULL; + } + taskEXIT_CRITICAL(); + } +/*-----------------------------------------------------------*/ + + static int32_t MPU_GetIndexForHandle( OpaqueObjectHandle_t xHandle, + uint32_t ulKernelObjectType ) /* PRIVILEGED_FUNCTION */ + { + int32_t i, lIndex = -1; + + configASSERT( xHandle != NULL ); + + for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ ) + { + if( ( xKernelObjectPool[ i ].xInternalObjectHandle == xHandle ) && + ( xKernelObjectPool[ i ].ulKernelObjectType == ulKernelObjectType ) ) + { + lIndex = i; + break; + } + } + + return lIndex; + } +/*-----------------------------------------------------------*/ + + static void MPU_StoreHandleAndDataAtIndex( int32_t lIndex, + OpaqueObjectHandle_t xHandle, + void * pvKernelObjectData, + uint32_t ulKernelObjectType ) /* PRIVILEGED_FUNCTION */ + { + configASSERT( IS_INTERNAL_INDEX_VALID( lIndex ) != pdFALSE ); + xKernelObjectPool[ lIndex ].xInternalObjectHandle = xHandle; + xKernelObjectPool[ lIndex ].ulKernelObjectType = ulKernelObjectType; + xKernelObjectPool[ lIndex ].pvKernelObjectData = pvKernelObjectData; + } +/*-----------------------------------------------------------*/ + + static OpaqueObjectHandle_t MPU_GetHandleAtIndex( int32_t lIndex, + uint32_t ulKernelObjectType ) /* PRIVILEGED_FUNCTION */ + { + OpaqueObjectHandle_t xObjectHandle = NULL; + + configASSERT( IS_INTERNAL_INDEX_VALID( lIndex ) != pdFALSE ); + + if( xKernelObjectPool[ lIndex ].ulKernelObjectType == ulKernelObjectType ) + { + xObjectHandle = xKernelObjectPool[ lIndex ].xInternalObjectHandle; + } + + return xObjectHandle; + } +/*-----------------------------------------------------------*/ + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + void vGrantAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) /* PRIVILEGED_FUNCTION */ + { + int32_t lExternalTaskIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( IS_EXTERNAL_INDEX_VALID( lExternalKernelObjectHandle ) != pdFALSE ) + { + if( xExternalTaskHandle == NULL ) + { + vPortGrantAccessToKernelObject( xExternalTaskHandle, CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + else + { + lExternalTaskIndex = ( int32_t ) xExternalTaskHandle; + + if( IS_EXTERNAL_INDEX_VALID( lExternalTaskIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lExternalTaskIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, + CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + } + } + } + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + void vRevokeAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) /* PRIVILEGED_FUNCTION */ + { + int32_t lExternalTaskIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( IS_EXTERNAL_INDEX_VALID( lExternalKernelObjectHandle ) != pdFALSE ) + { + if( xExternalTaskHandle == NULL ) + { + vPortRevokeAccessToKernelObject( xExternalTaskHandle, CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + else + { + lExternalTaskIndex = ( int32_t ) xExternalTaskHandle; + + if( IS_EXTERNAL_INDEX_VALID( lExternalTaskIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lExternalTaskIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vPortRevokeAccessToKernelObject( xInternalTaskHandle, + CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + } + } + } + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + static void MPU_TimerCallback( TimerHandle_t xInternalHandle ) /* PRIVILEGED_FUNCTION */ + { + int32_t i, lIndex = -1; + TimerHandle_t xExternalHandle = NULL; + TimerCallbackFunction_t pxApplicationCallBack = NULL; + + /* Coming from the timer task and therefore, should be valid. */ + configASSERT( xInternalHandle != NULL ); + + for( i = 0; i < configPROTECTED_KERNEL_OBJECT_POOL_SIZE; i++ ) + { + if( ( ( TimerHandle_t ) xKernelObjectPool[ i ].xInternalObjectHandle == xInternalHandle ) && + ( xKernelObjectPool[ i ].ulKernelObjectType == KERNEL_OBJECT_TYPE_TIMER ) ) + { + lIndex = i; + break; + } + } + + configASSERT( lIndex != -1 ); + xExternalHandle = ( TimerHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + + pxApplicationCallBack = ( TimerCallbackFunction_t ) xKernelObjectPool[ lIndex ].pvKernelObjectData; + pxApplicationCallBack( xExternalHandle ); + } + + #endif /* #if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for tasks APIs. */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskDelayUntil == 1 ) + + BaseType_t MPU_xTaskDelayUntilImpl( TickType_t * const pxPreviousWakeTime, + TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskDelayUntilImpl( TickType_t * const pxPreviousWakeTime, + TickType_t xTimeIncrement ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xIsPreviousWakeTimeAccessible = pdFALSE; + + if( ( pxPreviousWakeTime != NULL ) && ( xTimeIncrement > 0U ) ) + { + xIsPreviousWakeTimeAccessible = xPortIsAuthorizedToAccessBuffer( pxPreviousWakeTime, + sizeof( TickType_t ), + ( tskMPU_WRITE_PERMISSION | tskMPU_READ_PERMISSION ) ); + + if( xIsPreviousWakeTimeAccessible == pdTRUE ) + { + xReturn = xTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + } + } + + return xReturn; + } + + #endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t MPU_xTaskAbortDelayImpl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskAbortDelayImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskAbortDelay( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelay == 1 ) + + void MPU_vTaskDelayImpl( TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + + void MPU_vTaskDelayImpl( TickType_t xTicksToDelay ) /* PRIVILEGED_FUNCTION */ + { + vTaskDelay( xTicksToDelay ); + } + + #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t MPU_uxTaskPriorityGetImpl( const TaskHandle_t pxTask ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskPriorityGetImpl( const TaskHandle_t pxTask ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = configMAX_PRIORITIES; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( pxTask == NULL ) + { + uxReturn = uxTaskPriorityGet( pxTask ); + } + else + { + lIndex = ( int32_t ) pxTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskPriorityGet( xInternalTaskHandle ); + } + } + } + } + + return uxReturn; + } + + #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_eTaskGetState == 1 ) + + eTaskState MPU_eTaskGetStateImpl( TaskHandle_t pxTask ) PRIVILEGED_FUNCTION; + + eTaskState MPU_eTaskGetStateImpl( TaskHandle_t pxTask ) /* PRIVILEGED_FUNCTION */ + { + eTaskState eReturn = eInvalid; + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + lIndex = ( int32_t ) pxTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + eReturn = eTaskGetState( xInternalTaskHandle ); + } + } + } + + return eReturn; + } + + #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void MPU_vTaskGetInfoImpl( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) PRIVILEGED_FUNCTION; + + void MPU_vTaskGetInfoImpl( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xIsTaskStatusWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + xIsTaskStatusWriteable = xPortIsAuthorizedToAccessBuffer( pxTaskStatus, + sizeof( TaskStatus_t ), + tskMPU_WRITE_PERMISSION ); + + if( xIsTaskStatusWriteable == pdTRUE ) + { + if( xTask == NULL ) + { + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskGetInfo( xInternalTaskHandle, pxTaskStatus, xGetFreeStackSpace, eState ); + } + } + } + } + } + } + + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t MPU_xTaskGetIdleTaskHandleImpl( void ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xTaskGetIdleTaskHandleImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xIdleTaskHandle = NULL; + + xIdleTaskHandle = xTaskGetIdleTaskHandle(); + + return xIdleTaskHandle; + } + + #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + + void MPU_vTaskSuspendImpl( TaskHandle_t pxTaskToSuspend ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSuspendImpl( TaskHandle_t pxTaskToSuspend ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( pxTaskToSuspend == NULL ) + { + vTaskSuspend( pxTaskToSuspend ); + } + else + { + /* After the scheduler starts, only privileged tasks are allowed + * to suspend other tasks. */ + #if ( INCLUDE_xTaskGetSchedulerState == 1 ) + if( ( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED ) || ( portIS_TASK_PRIVILEGED() == pdTRUE ) ) + #else + if( portIS_TASK_PRIVILEGED() == pdTRUE ) + #endif + { + lIndex = ( int32_t ) pxTaskToSuspend; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSuspend( xInternalTaskHandle ); + } + } + } + } + } + } + + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskSuspend == 1 ) + + void MPU_vTaskResumeImpl( TaskHandle_t pxTaskToResume ) PRIVILEGED_FUNCTION; + + void MPU_vTaskResumeImpl( TaskHandle_t pxTaskToResume ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + lIndex = ( int32_t ) pxTaskToResume; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskResume( xInternalTaskHandle ); + } + } + } + } + + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + + TickType_t MPU_xTaskGetTickCountImpl( void ) PRIVILEGED_FUNCTION; + + TickType_t MPU_xTaskGetTickCountImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TickType_t xReturn; + + xReturn = xTaskGetTickCount(); + + return xReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxTaskGetNumberOfTasksImpl( void ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskGetNumberOfTasksImpl( void ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn; + + uxReturn = uxTaskGetNumberOfTasks(); + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + char * MPU_pcTaskGetNameImpl( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; + + char * MPU_pcTaskGetNameImpl( TaskHandle_t xTaskToQuery ) /* PRIVILEGED_FUNCTION */ + { + char * pcReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTaskToQuery == NULL ) + { + pcReturn = pcTaskGetName( xTaskToQuery ); + } + else + { + lIndex = ( int32_t ) xTaskToQuery; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + pcReturn = pcTaskGetName( xInternalTaskHandle ); + } + } + } + + return pcReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounterImpl( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounterImpl( const TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTask == NULL ) + { + xReturn = ulTaskGetRunTimeCounter( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = ulTaskGetRunTimeCounter( xInternalTaskHandle ); + } + } + } + } + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercentImpl( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercentImpl( const TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTask == NULL ) + { + xReturn = ulTaskGetRunTimePercent( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = ulTaskGetRunTimePercent( xInternalTaskHandle ); + } + } + } + } + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercentImpl( void ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercentImpl( void ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn; + + xReturn = ulTaskGetIdleRunTimePercent(); + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounterImpl( void ) PRIVILEGED_FUNCTION; + + configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounterImpl( void ) /* PRIVILEGED_FUNCTION */ + { + configRUN_TIME_COUNTER_TYPE xReturn; + + xReturn = ulTaskGetIdleRunTimeCounter(); + + return xReturn; + } + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void MPU_vTaskSetApplicationTaskTagImpl( TaskHandle_t xTask, + TaskHookFunction_t pxTagValue ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSetApplicationTaskTagImpl( TaskHandle_t xTask, + TaskHookFunction_t pxTagValue ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTask == NULL ) + { + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSetApplicationTaskTag( xInternalTaskHandle, pxTagValue ); + } + } + } + } + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTagImpl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTagImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + TaskHookFunction_t xReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTask == NULL ) + { + xReturn = xTaskGetApplicationTaskTag( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetApplicationTaskTag( xInternalTaskHandle ); + } + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void MPU_vTaskSetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTaskToSet == NULL ) + { + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + } + else + { + lIndex = ( int32_t ) xTaskToSet; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSetThreadLocalStoragePointer( xInternalTaskHandle, xIndex, pvValue ); + } + } + } + } + } + + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void * MPU_pvTaskGetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) PRIVILEGED_FUNCTION; + + void * MPU_pvTaskGetThreadLocalStoragePointerImpl( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) /* PRIVILEGED_FUNCTION */ + { + void * pvReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTaskToQuery == NULL ) + { + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + } + else + { + lIndex = ( int32_t ) xTaskToQuery; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + pvReturn = pvTaskGetThreadLocalStoragePointer( xInternalTaskHandle, xIndex ); + } + } + } + } + + return pvReturn; + } + + #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t MPU_uxTaskGetSystemStateImpl( TaskStatus_t * pxTaskStatusArray, + UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskGetSystemStateImpl( TaskStatus_t * pxTaskStatusArray, + UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + UBaseType_t xIsTaskStatusArrayWriteable = pdFALSE; + UBaseType_t xIsTotalRunTimeWriteable = pdFALSE; + uint32_t ulArraySize = ( uint32_t ) uxArraySize; + uint32_t ulTaskStatusSize = ( uint32_t ) sizeof( TaskStatus_t ); + + if( mpuMULTIPLY_UINT32_WILL_OVERFLOW( ulTaskStatusSize, ulArraySize ) == 0 ) + { + xIsTaskStatusArrayWriteable = xPortIsAuthorizedToAccessBuffer( pxTaskStatusArray, + ulTaskStatusSize * ulArraySize, + tskMPU_WRITE_PERMISSION ); + + if( pulTotalRunTime != NULL ) + { + xIsTotalRunTimeWriteable = xPortIsAuthorizedToAccessBuffer( pulTotalRunTime, + sizeof( configRUN_TIME_COUNTER_TYPE ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( xIsTaskStatusArrayWriteable == pdTRUE ) && + ( ( pulTotalRunTime == NULL ) || ( xIsTotalRunTimeWriteable == pdTRUE ) ) ) + { + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, ( UBaseType_t ) ulArraySize, pulTotalRunTime ); + } + } + + return uxReturn; + } + + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t MPU_uxTaskGetStackHighWaterMarkImpl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTaskGetStackHighWaterMarkImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTask == NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark( xInternalTaskHandle ); + } + } + } + } + + return uxReturn; + } + + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2Impl( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2Impl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + configSTACK_DEPTH_TYPE uxReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( xTask == NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark2( xInternalTaskHandle ); + } + } + } + } + + return uxReturn; + } + + #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t MPU_xTaskGetCurrentTaskHandleImpl( void ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xTaskGetCurrentTaskHandleImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + TaskHandle_t xExternalTaskHandle = NULL; + int32_t lIndex; + + xInternalTaskHandle = xTaskGetCurrentTaskHandle(); + + if( xInternalTaskHandle != NULL ) + { + lIndex = MPU_GetIndexForTaskHandle( xInternalTaskHandle ); + + if( lIndex != -1 ) + { + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + + return xExternalTaskHandle; + } + + #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetSchedulerState == 1 ) + + BaseType_t MPU_xTaskGetSchedulerStateImpl( void ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGetSchedulerStateImpl( void ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = taskSCHEDULER_NOT_STARTED; + + xReturn = xTaskGetSchedulerState(); + + return xReturn; + } + + #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskSetTimeOutStateImpl( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + + void MPU_vTaskSetTimeOutStateImpl( TimeOut_t * const pxTimeOut ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xIsTimeOutWriteable = pdFALSE; + + if( pxTimeOut != NULL ) + { + xIsTimeOutWriteable = xPortIsAuthorizedToAccessBuffer( pxTimeOut, + sizeof( TimeOut_t ), + tskMPU_WRITE_PERMISSION ); + + if( xIsTimeOutWriteable == pdTRUE ) + { + vTaskSetTimeOutState( pxTimeOut ); + } + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xTaskCheckForTimeOutImpl( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskCheckForTimeOutImpl( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + BaseType_t xIsTimeOutWriteable = pdFALSE; + BaseType_t xIsTicksToWaitWriteable = pdFALSE; + + if( ( pxTimeOut != NULL ) && ( pxTicksToWait != NULL ) ) + { + xIsTimeOutWriteable = xPortIsAuthorizedToAccessBuffer( pxTimeOut, + sizeof( TimeOut_t ), + tskMPU_WRITE_PERMISSION ); + xIsTicksToWaitWriteable = xPortIsAuthorizedToAccessBuffer( pxTicksToWait, + sizeof( TickType_t ), + tskMPU_WRITE_PERMISSION ); + + if( ( xIsTimeOutWriteable == pdTRUE ) && ( xIsTicksToWaitWriteable == pdTRUE ) ) + { + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn = pdFAIL; + xTaskGenericNotifyParams_t xParams; + + xParams.xTaskToNotify = xTaskToNotify; + xParams.uxIndexToNotify = uxIndexToNotify; + xParams.ulValue = ulValue; + xParams.eAction = eAction; + xParams.pulPreviousNotificationValue = pulPreviousNotificationValue; + + xReturn = MPU_xTaskGenericNotifyEntry( &( xParams ) ); + + return xReturn; + } + + BaseType_t MPU_xTaskGenericNotifyImpl( const xTaskGenericNotifyParams_t * pxParams ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGenericNotifyImpl( const xTaskGenericNotifyParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xIsPreviousNotificationValueWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + BaseType_t xAreParamsReadable = pdFALSE; + + if( pxParams != NULL ) + { + xAreParamsReadable = xPortIsAuthorizedToAccessBuffer( pxParams, + sizeof( xTaskGenericNotifyParams_t ), + tskMPU_READ_PERMISSION ); + } + + if( xAreParamsReadable == pdTRUE ) + { + if( ( pxParams->uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ) && + ( ( pxParams->eAction == eNoAction ) || + ( pxParams->eAction == eSetBits ) || + ( pxParams->eAction == eIncrement ) || + ( pxParams->eAction == eSetValueWithOverwrite ) || + ( pxParams->eAction == eSetValueWithoutOverwrite ) ) ) + { + if( pxParams->pulPreviousNotificationValue != NULL ) + { + xIsPreviousNotificationValueWriteable = xPortIsAuthorizedToAccessBuffer( pxParams->pulPreviousNotificationValue, + sizeof( uint32_t ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( pxParams->pulPreviousNotificationValue == NULL ) || + ( xIsPreviousNotificationValueWriteable == pdTRUE ) ) + { + lIndex = ( int32_t ) ( pxParams->xTaskToNotify ); + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotify( xInternalTaskHandle, + pxParams->uxIndexToNotify, + pxParams->ulValue, + pxParams->eAction, + pxParams->pulPreviousNotificationValue ); + } + } + } + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) + { + BaseType_t xReturn = pdFAIL; + xTaskGenericNotifyWaitParams_t xParams; + + xParams.uxIndexToWaitOn = uxIndexToWaitOn; + xParams.ulBitsToClearOnEntry = ulBitsToClearOnEntry; + xParams.ulBitsToClearOnExit = ulBitsToClearOnExit; + xParams.pulNotificationValue = pulNotificationValue; + xParams.xTicksToWait = xTicksToWait; + + xReturn = MPU_xTaskGenericNotifyWaitEntry( &( xParams ) ); + + return xReturn; + } + + BaseType_t MPU_xTaskGenericNotifyWaitImpl( const xTaskGenericNotifyWaitParams_t * pxParams ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGenericNotifyWaitImpl( const xTaskGenericNotifyWaitParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xIsNotificationValueWritable = pdFALSE; + BaseType_t xAreParamsReadable = pdFALSE; + + if( pxParams != NULL ) + { + xAreParamsReadable = xPortIsAuthorizedToAccessBuffer( pxParams, + sizeof( xTaskGenericNotifyWaitParams_t ), + tskMPU_READ_PERMISSION ); + } + + if( xAreParamsReadable == pdTRUE ) + { + if( pxParams->uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES ) + { + if( pxParams->pulNotificationValue != NULL ) + { + xIsNotificationValueWritable = xPortIsAuthorizedToAccessBuffer( pxParams->pulNotificationValue, + sizeof( uint32_t ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( pxParams->pulNotificationValue == NULL ) || + ( xIsNotificationValueWritable == pdTRUE ) ) + { + xReturn = xTaskGenericNotifyWait( pxParams->uxIndexToWaitOn, + pxParams->ulBitsToClearOnEntry, + pxParams->ulBitsToClearOnExit, + pxParams->pulNotificationValue, + pxParams->xTicksToWait ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t MPU_ulTaskGenericNotifyTakeImpl( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + uint32_t MPU_ulTaskGenericNotifyTakeImpl( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulReturn = 0; + + if( uxIndexToWaitOn < configTASK_NOTIFICATION_ARRAY_ENTRIES ) + { + ulReturn = ulTaskGenericNotifyTake( uxIndexToWaitOn, xClearCountOnExit, xTicksToWait ); + } + + return ulReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyStateClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTaskGenericNotifyStateClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ) + { + if( xTask == NULL ) + { + xReturn = xTaskGenericNotifyStateClear( xTask, uxIndexToClear ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotifyStateClear( xInternalTaskHandle, uxIndexToClear ); + } + } + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t MPU_ulTaskGenericNotifyValueClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + uint32_t MPU_ulTaskGenericNotifyValueClearImpl( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulReturn = 0; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; + + if( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ) + { + if( xTask == NULL ) + { + ulReturn = ulTaskGenericNotifyValueClear( xTask, uxIndexToClear, ulBitsToClear ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + ulReturn = ulTaskGenericNotifyValueClear( xInternalTaskHandle, uxIndexToClear, ulBitsToClear ); + } + } + } + } + } + + return ulReturn; + } + + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Task APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, + const char * const pcName, + uint16_t usStackDepth, + void * pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + /* xTaskCreate() can only be used to create privileged tasks in MPU port. */ + if( ( uxPriority & portPRIVILEGE_BIT ) != 0 ) + { + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, &( xInternalTaskHandle ) ); + + if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + if( pxCreatedTask != NULL ) + { + *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + } + + return xReturn; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xExternalTaskHandle = NULL; + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalTaskHandle = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + + if( xInternalTaskHandle != NULL ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + { + /* By default, an unprivileged task has access to itself. */ + if( ( uxPriority & portPRIVILEGE_BIT ) == 0 ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, lIndex ); + } + } + #endif + + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalTaskHandle; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_vTaskDelete == 1 ) + + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( pxTaskToDelete == NULL ) + { + xInternalTaskHandle = xTaskGetCurrentTaskHandle(); + lIndex = MPU_GetIndexForTaskHandle( xInternalTaskHandle ); + + vTaskDelete( xInternalTaskHandle ); + + if( lIndex != -1 ) + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + else + { + lIndex = ( int32_t ) pxTaskToDelete; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskDelete( xInternalTaskHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } + } + + #endif /* #if ( INCLUDE_vTaskDelete == 1 ) */ +/*-----------------------------------------------------------*/ + + + #if ( INCLUDE_vTaskPrioritySet == 1 ) + + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, + UBaseType_t uxNewPriority ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( pxTask == NULL ) + { + vTaskPrioritySet( pxTask, uxNewPriority ); + } + else + { + lIndex = ( int32_t ) pxTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskPrioritySet( xInternalTaskHandle, uxNewPriority ); + } + } + } + } + + #endif /* if ( INCLUDE_vTaskPrioritySet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + TaskHandle_t xExternalTaskHandle = NULL; + int32_t lIndex; + + xInternalTaskHandle = xTaskGetHandle( pcNameToQuery ); + + if( xInternalTaskHandle != NULL ) + { + lIndex = MPU_GetIndexForTaskHandle( xInternalTaskHandle ); + + if( lIndex != -1 ) + { + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + + return xExternalTaskHandle; + } + + #endif /* if ( INCLUDE_xTaskGetHandle == 1 ) */ +/*-----------------------------------------------------------*/ + + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskCallApplicationTaskHook( xInternalTaskHandle, pvParameter ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xReturn = xTaskCreateRestricted( pxTaskDefinition, &( xInternalTaskHandle ) ); + + if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + { + /* By default, an unprivileged task has access to itself. */ + if( ( pxTaskDefinition->uxPriority & portPRIVILEGE_BIT ) == 0 ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, lIndex ); + } + } + #endif + + if( pxCreatedTask != NULL ) + { + *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xReturn; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xReturn = xTaskCreateRestrictedStatic( pxTaskDefinition, &( xInternalTaskHandle ) ); + + if( ( xReturn == pdPASS ) && ( xInternalTaskHandle != NULL ) ) + { + MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + { + /* By default, an unprivileged task has access to itself. */ + if( ( pxTaskDefinition->uxPriority & portPRIVILEGE_BIT ) == 0 ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, lIndex ); + } + } + #endif + + if( pxCreatedTask != NULL ) + { + *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xReturn; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + void MPU_vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, + const MemoryRegion_t * const xRegions ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + + if( xTaskToModify == NULL ) + { + vTaskAllocateMPURegions( xTaskToModify, xRegions ); + } + else + { + lIndex = ( int32_t ) xTaskToModify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskAllocateMPURegions( xInternalTaskHandle, xRegions ); + } + } + } + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xInternalTaskHandle = NULL; + int32_t lIndex; + BaseType_t xReturn = pdFALSE; + + if( xTask == NULL ) + { + xInternalTaskHandle = xTaskGetCurrentTaskHandle(); + xReturn = xTaskGetStaticBuffers( xInternalTaskHandle, ppuxStackBuffer, ppxTaskBuffer ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetStaticBuffers( xInternalTaskHandle, ppuxStackBuffer, ppxTaskBuffer ); + } + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = configMAX_PRIORITIES; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + uxReturn = uxTaskPriorityGetFromISR( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskPriorityGetFromISR( xInternalTaskHandle ); + } + } + } + + return uxReturn; + } + + #endif /* #if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) xTaskToResume; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskResumeFromISR( xInternalTaskHandle ); + } + } + + return xReturn; + } + + #endif /* #if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )*/ +/*---------------------------------------------------------------------------------------*/ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ + { + TaskHookFunction_t xReturn = NULL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( xTask == NULL ) + { + xReturn = xTaskGetApplicationTaskTagFromISR( xTask ); + } + else + { + lIndex = ( int32_t ) xTask; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetApplicationTaskTagFromISR( xInternalTaskHandle ); + } + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*---------------------------------------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) xTaskToNotify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotifyFromISR( xInternalTaskHandle, uxIndexToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + + #endif /* #if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*---------------------------------------------------------------------------------------*/ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + lIndex = ( int32_t ) xTaskToNotify; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskGenericNotifyGiveFromISR( xInternalTaskHandle, uxIndexToNotify, pxHigherPriorityTaskWoken ); + } + } + } + #endif /*#if ( configUSE_TASK_NOTIFICATIONS == 1 )*/ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for queue APIs. */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericSendImpl( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueGenericSendImpl( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + BaseType_t xCopyPosition ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + BaseType_t xIsItemToQueueReadable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + UBaseType_t uxQueueItemSize, uxQueueLength; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + uxQueueLength = uxQueueGetQueueLength( xInternalQueueHandle ); + + if( ( !( ( pvItemToQueue == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) && + ( !( ( xCopyPosition == queueOVERWRITE ) && ( uxQueueLength != ( UBaseType_t ) 1U ) ) ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) + { + if( pvItemToQueue != NULL ) + { + xIsItemToQueueReadable = xPortIsAuthorizedToAccessBuffer( pvItemToQueue, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_READ_PERMISSION ); + } + + if( ( pvItemToQueue == NULL ) || ( xIsItemToQueueReadable == pdTRUE ) ) + { + xReturn = xQueueGenericSend( xInternalQueueHandle, pvItemToQueue, xTicksToWait, xCopyPosition ); + } + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueMessagesWaitingImpl( const QueueHandle_t pxQueue ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxQueueMessagesWaitingImpl( const QueueHandle_t pxQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + UBaseType_t uxReturn = 0; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) pxQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueMessagesWaiting( xInternalQueueHandle ); + } + } + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueSpacesAvailableImpl( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxQueueSpacesAvailableImpl( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + UBaseType_t uxReturn = 0; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueSpacesAvailable( xInternalQueueHandle ); + } + } + } + + return uxReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueReceiveImpl( QueueHandle_t pxQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueReceiveImpl( QueueHandle_t pxQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + BaseType_t xIsReceiveBufferWritable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + UBaseType_t uxQueueItemSize; + + lIndex = ( int32_t ) pxQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + + if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) + { + xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_WRITE_PERMISSION ); + + if( xIsReceiveBufferWritable == pdTRUE ) + { + xReturn = xQueueReceive( xInternalQueueHandle, pvBuffer, xTicksToWait ); + } + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueuePeekImpl( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueuePeekImpl( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + BaseType_t xIsReceiveBufferWritable = pdFALSE; + UBaseType_t uxQueueItemSize; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + + if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) + { + xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_WRITE_PERMISSION ); + + if( xIsReceiveBufferWritable == pdTRUE ) + { + xReturn = xQueuePeek( xInternalQueueHandle, pvBuffer, xTicksToWait ); + } + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueSemaphoreTakeImpl( QueueHandle_t xQueue, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueSemaphoreTakeImpl( QueueHandle_t xQueue, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + UBaseType_t uxQueueItemSize; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + + if( ( uxQueueItemSize == 0 ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) + { + xReturn = xQueueSemaphoreTake( xInternalQueueHandle, xTicksToWait ); + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t MPU_xQueueGetMutexHolderImpl( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xQueueGetMutexHolderImpl( QueueHandle_t xSemaphore ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xMutexHolderTaskInternalHandle = NULL; + TaskHandle_t xMutexHolderTaskExternalHandle = NULL; + int32_t lIndex, lMutexHolderTaskIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + + lIndex = ( int32_t ) xSemaphore; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xMutexHolderTaskInternalHandle = xQueueGetMutexHolder( xInternalQueueHandle ); + + if( xMutexHolderTaskInternalHandle != NULL ) + { + lMutexHolderTaskIndex = MPU_GetIndexForTaskHandle( xMutexHolderTaskInternalHandle ); + + if( lMutexHolderTaskIndex != -1 ) + { + xMutexHolderTaskExternalHandle = ( TaskHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lMutexHolderTaskIndex ) ); + } + } + } + } + } + + return xMutexHolderTaskExternalHandle; + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t MPU_xQueueTakeMutexRecursiveImpl( QueueHandle_t xMutex, + TickType_t xBlockTime ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueTakeMutexRecursiveImpl( QueueHandle_t xMutex, + TickType_t xBlockTime ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + UBaseType_t uxQueueItemSize; + + lIndex = ( int32_t ) xMutex; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + + if( uxQueueItemSize == 0 ) + { + xReturn = xQueueTakeMutexRecursive( xInternalQueueHandle, xBlockTime ); + } + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t MPU_xQueueGiveMutexRecursiveImpl( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueGiveMutexRecursiveImpl( QueueHandle_t xMutex ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xMutex; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGiveMutexRecursive( xInternalQueueHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t MPU_xQueueSelectFromSetImpl( QueueSetHandle_t xQueueSet, + TickType_t xBlockTimeTicks ) PRIVILEGED_FUNCTION; + + QueueSetMemberHandle_t MPU_xQueueSelectFromSetImpl( QueueSetHandle_t xQueueSet, + TickType_t xBlockTimeTicks ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetMemberHandle_t xSelectedMemberInternal = NULL; + QueueSetMemberHandle_t xSelectedMemberExternal = NULL; + int32_t lIndexQueueSet, lIndexSelectedMember; + BaseType_t xCallingTaskIsAuthorizedToAccessQueueSet = pdFALSE; + + lIndexQueueSet = ( int32_t ) xQueueSet; + + if( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueueSet = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + + if( xCallingTaskIsAuthorizedToAccessQueueSet == pdTRUE ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + + if( xInternalQueueSetHandle != NULL ) + { + xSelectedMemberInternal = xQueueSelectFromSet( xInternalQueueSetHandle, xBlockTimeTicks ); + + if( xSelectedMemberInternal != NULL ) + { + lIndexSelectedMember = MPU_GetIndexForQueueSetMemberHandle( xSelectedMemberInternal ); + + if( lIndexSelectedMember != -1 ) + { + xSelectedMemberExternal = ( QueueSetMemberHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lIndexSelectedMember ) ); + } + } + } + } + } + + return xSelectedMemberExternal; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t MPU_xQueueAddToSetImpl( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xQueueAddToSetImpl( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + QueueSetMemberHandle_t xInternalQueueSetMemberHandle = NULL; + QueueSetHandle_t xInternalQueueSetHandle = NULL; + int32_t lIndexQueueSet, lIndexQueueSetMember; + BaseType_t xCallingTaskIsAuthorizedToAccessQueueSet = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessQueueSetMember = pdFALSE; + + lIndexQueueSet = ( int32_t ) xQueueSet; + lIndexQueueSetMember = ( int32_t ) xQueueOrSemaphore; + + if( ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) && + ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSetMember ) != pdFALSE ) ) + { + xCallingTaskIsAuthorizedToAccessQueueSet = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xCallingTaskIsAuthorizedToAccessQueueSetMember = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + + if( ( xCallingTaskIsAuthorizedToAccessQueueSet == pdTRUE ) && ( xCallingTaskIsAuthorizedToAccessQueueSetMember == pdTRUE ) ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xInternalQueueSetMemberHandle = MPU_GetQueueSetMemberHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + + if( ( xInternalQueueSetHandle != NULL ) && ( xInternalQueueSetMemberHandle != NULL ) ) + { + xReturn = xQueueAddToSet( xInternalQueueSetMemberHandle, xInternalQueueSetHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + + void MPU_vQueueAddToRegistryImpl( QueueHandle_t xQueue, + const char * pcName ) PRIVILEGED_FUNCTION; + + void MPU_vQueueAddToRegistryImpl( QueueHandle_t xQueue, + const char * pcName ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueAddToRegistry( xInternalQueueHandle, pcName ); + } + } + } + } + + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + + void MPU_vQueueUnregisterQueueImpl( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + void MPU_vQueueUnregisterQueueImpl( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueUnregisterQueue( xInternalQueueHandle ); + } + } + } + } + + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + + #if configQUEUE_REGISTRY_SIZE > 0 + + const char * MPU_pcQueueGetNameImpl( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + const char * MPU_pcQueueGetNameImpl( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + const char * pcReturn = NULL; + QueueHandle_t xInternalQueueHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + pcReturn = pcQueueGetName( xInternalQueueHandle ); + } + } + } + + return pcReturn; + } + + #endif /* if configQUEUE_REGISTRY_SIZE > 0 */ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Queue APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + void MPU_vQueueDelete( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueDelete( xInternalQueueHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateMutex( ucQueueType ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, + UBaseType_t uxInitialCount ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, + UBaseType_t uxItemSize, + uint8_t ucQueueType ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) /* PRIVILEGED_FUNCTION */ + { + QueueHandle_t xInternalQueueHandle = NULL; + QueueHandle_t xExternalQueueHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueHandle = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + + if( xInternalQueueHandle != NULL ) + { + MPU_StoreQueueHandleAtIndex( lIndex, xInternalQueueHandle ); + xExternalQueueHandle = ( QueueHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueHandle; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFAIL; + + lIndex = ( uint32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGenericReset( xInternalQueueHandle, xNewQueue ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetHandle_t xExternalQueueSetHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalQueueSetHandle = xQueueCreateSet( uxEventQueueLength ); + + if( xInternalQueueSetHandle != NULL ) + { + MPU_StoreQueueSetHandleAtIndex( lIndex, xInternalQueueSetHandle ); + xExternalQueueSetHandle = ( QueueSetHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalQueueSetHandle; + } + + #endif /* if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + QueueSetMemberHandle_t xInternalQueueSetMemberHandle = NULL; + QueueSetHandle_t xInternalQueueSetHandle = NULL; + int32_t lIndexQueueSet, lIndexQueueSetMember; + + lIndexQueueSet = ( int32_t ) xQueueSet; + lIndexQueueSetMember = ( int32_t ) xQueueOrSemaphore; + + if( ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) && + ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSetMember ) != pdFALSE ) ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xInternalQueueSetMemberHandle = MPU_GetQueueSetMemberHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + + if( ( xInternalQueueSetHandle != NULL ) && ( xInternalQueueSetMemberHandle != NULL ) ) + { + xReturn = xQueueRemoveFromSet( xInternalQueueSetMemberHandle, xInternalQueueSetHandle ); + } + } + + return xReturn; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) /* PRIVILEGED_FUNCTION */ + { + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xReturn = pdFALSE; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGenericGetStaticBuffers( xInternalQueueHandle, ppucQueueStorage, ppxStaticQueue ); + } + } + + return xReturn; + } + + #endif /*if ( configSUPPORT_STATIC_ALLOCATION == 1 )*/ +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue, + const void * const pvItemToQueue, + BaseType_t * const pxHigherPriorityTaskWoken, + const BaseType_t xCopyPosition ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGenericSendFromISR( xInternalQueueHandle, pvItemToQueue, pxHigherPriorityTaskWoken, xCopyPosition ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGiveFromISR( xInternalQueueHandle, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue, + void * const pvBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueuePeekFromISR( xInternalQueueHandle, pvBuffer ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue, + void * const pvBuffer, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueReceiveFromISR( xInternalQueueHandle, pvBuffer, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueIsQueueEmptyFromISR( xInternalQueueHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFAIL; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueIsQueueFullFromISR( xInternalQueueHandle ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + int32_t lIndex; + QueueHandle_t xInternalQueueHandle = NULL; + + lIndex = ( int32_t ) xQueue; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueMessagesWaitingFromISR( xInternalQueueHandle ); + } + } + + return uxReturn; + } + +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xMutexHolderTaskInternalHandle = NULL; + TaskHandle_t xMutexHolderTaskExternalHandle = NULL; + int32_t lIndex, lMutexHolderTaskIndex; + QueueHandle_t xInternalSemaphoreHandle = NULL; + + lIndex = ( int32_t ) xSemaphore; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalSemaphoreHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalSemaphoreHandle != NULL ) + { + xMutexHolderTaskInternalHandle = xQueueGetMutexHolder( xInternalSemaphoreHandle ); + + if( xMutexHolderTaskInternalHandle != NULL ) + { + lMutexHolderTaskIndex = MPU_GetIndexForTaskHandle( xMutexHolderTaskInternalHandle ); + + if( lMutexHolderTaskIndex != -1 ) + { + xMutexHolderTaskExternalHandle = ( TaskHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lMutexHolderTaskIndex ) ); + } + } + } + } + + return xMutexHolderTaskExternalHandle; + } + + #endif /* #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) /* PRIVILEGED_FUNCTION */ + { + QueueSetHandle_t xInternalQueueSetHandle = NULL; + QueueSetMemberHandle_t xSelectedMemberInternal = NULL; + QueueSetMemberHandle_t xSelectedMemberExternal = NULL; + int32_t lIndexQueueSet, lIndexSelectedMember; + + lIndexQueueSet = ( int32_t ) xQueueSet; + + if( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) + { + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + + if( xInternalQueueSetHandle != NULL ) + { + xSelectedMemberInternal = xQueueSelectFromSetFromISR( xInternalQueueSetHandle ); + + if( xSelectedMemberInternal != NULL ) + { + lIndexSelectedMember = MPU_GetIndexForQueueSetMemberHandle( xSelectedMemberInternal ); + + if( lIndexSelectedMember != -1 ) + { + xSelectedMemberExternal = ( QueueSetMemberHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lIndexSelectedMember ) ); + } + } + } + } + + return xSelectedMemberExternal; + } + + #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for timers APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void * MPU_pvTimerGetTimerIDImpl( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + void * MPU_pvTimerGetTimerIDImpl( const TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + void * pvReturn = NULL; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + pvReturn = pvTimerGetTimerID( xInternalTimerHandle ); + } + } + } + + return pvReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void MPU_vTimerSetTimerIDImpl( TimerHandle_t xTimer, + void * pvNewID ) PRIVILEGED_FUNCTION; + + void MPU_vTimerSetTimerIDImpl( TimerHandle_t xTimer, + void * pvNewID ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + vTimerSetTimerID( xInternalTimerHandle, pvNewID ); + } + } + } + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerIsTimerActiveImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerIsTimerActiveImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerIsTimerActive( xInternalTimerHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandleImpl( void ) PRIVILEGED_FUNCTION; + + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandleImpl( void ) /* PRIVILEGED_FUNCTION */ + { + TaskHandle_t xReturn; + + xReturn = xTimerGetTimerDaemonTaskHandle(); + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn = pdFALSE; + xTimerGenericCommandParams_t xParams; + + xParams.xTimer = xTimer; + xParams.xCommandID = xCommandID; + xParams.xOptionalValue = xOptionalValue; + xParams.pxHigherPriorityTaskWoken = pxHigherPriorityTaskWoken; + xParams.xTicksToWait = xTicksToWait; + + xReturn = MPU_xTimerGenericCommandEntry( &( xParams ) ); + + return xReturn; + } + + BaseType_t MPU_xTimerGenericCommandImpl( const xTimerGenericCommandParams_t * pxParams ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerGenericCommandImpl( const xTimerGenericCommandParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xIsHigherPriorityTaskWokenWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + BaseType_t xAreParamsReadable = pdFALSE; + + if( pxParams != NULL ) + { + xAreParamsReadable = xPortIsAuthorizedToAccessBuffer( pxParams, + sizeof( xTimerGenericCommandParams_t ), + tskMPU_READ_PERMISSION ); + } + + if( xAreParamsReadable == pdTRUE ) + { + if( pxParams->pxHigherPriorityTaskWoken != NULL ) + { + xIsHigherPriorityTaskWokenWriteable = xPortIsAuthorizedToAccessBuffer( pxParams->pxHigherPriorityTaskWoken, + sizeof( BaseType_t ), + tskMPU_WRITE_PERMISSION ); + } + + if( ( pxParams->pxHigherPriorityTaskWoken == NULL ) || + ( xIsHigherPriorityTaskWokenWriteable == pdTRUE ) ) + { + lIndex = ( int32_t ) ( pxParams->xTimer ); + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGenericCommand( xInternalTimerHandle, + pxParams->xCommandID, + pxParams->xOptionalValue, + pxParams->pxHigherPriorityTaskWoken, + pxParams->xTicksToWait ); + } + } + } + } + } + + return xReturn; + } + + BaseType_t MPU_xTimerGenericCommandPrivImpl( const xTimerGenericCommandParams_t * pxParams ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerGenericCommandPrivImpl( const xTimerGenericCommandParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + if( pxParams != NULL ) + { + lIndex = ( int32_t ) ( pxParams->xTimer ); + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGenericCommand( xInternalTimerHandle, + pxParams->xCommandID, + pxParams->xOptionalValue, + pxParams->pxHigherPriorityTaskWoken, + pxParams->xTicksToWait ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + const char * MPU_pcTimerGetNameImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + const char * MPU_pcTimerGetNameImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + const char * pcReturn = NULL; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + pcReturn = pcTimerGetName( xInternalTimerHandle ); + } + } + } + + return pcReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, + const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + + void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, + const UBaseType_t uxAutoReload ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + vTimerSetReloadMode( xInternalTimerHandle, uxAutoReload ); + } + } + } + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGetReloadModeImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xTimerGetReloadModeImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetReloadMode( xInternalTimerHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + UBaseType_t MPU_uxTimerGetReloadModeImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxTimerGetReloadModeImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t uxReturn = 0; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + uxReturn = uxTimerGetReloadMode( xInternalTimerHandle ); + } + } + } + + return uxReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TickType_t MPU_xTimerGetPeriodImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + TickType_t MPU_xTimerGetPeriodImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + TickType_t xReturn = 0; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetPeriod( xInternalTimerHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TIMERS == 1 ) + + TickType_t MPU_xTimerGetExpiryTimeImpl( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + + TickType_t MPU_xTimerGetExpiryTimeImpl( TimerHandle_t xTimer ) /* PRIVILEGED_FUNCTION */ + { + TickType_t xReturn = 0; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetExpiryTime( xInternalTimerHandle ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Timer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) + + TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + TimerHandle_t xExternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalTimerHandle = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback ); + + if( xInternalTimerHandle != NULL ) + { + MPU_StoreTimerHandleAtIndex( lIndex, xInternalTimerHandle, pxCallbackFunction ); + xExternalTimerHandle = ( TimerHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalTimerHandle; + } + + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) + + TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t * pxTimerBuffer ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + TimerHandle_t xExternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalTimerHandle = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback, pxTimerBuffer ); + + if( xInternalTimerHandle != NULL ) + { + MPU_StoreTimerHandleAtIndex( lIndex, xInternalTimerHandle, pxCallbackFunction ); + xExternalTimerHandle = ( TimerHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalTimerHandle; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) /* PRIVILEGED_FUNCTION */ + { + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + BaseType_t xReturn = pdFALSE; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetStaticBuffer( xInternalTimerHandle, ppxTimerBuffer ); + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for event group APIs. */ +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + EventBits_t xReturn = 0; + xEventGroupWaitBitsParams_t xParams; + + xParams.xEventGroup = xEventGroup; + xParams.uxBitsToWaitFor = uxBitsToWaitFor; + xParams.xClearOnExit = xClearOnExit; + xParams.xWaitForAllBits = xWaitForAllBits; + xParams.xTicksToWait = xTicksToWait; + + xReturn = MPU_xEventGroupWaitBitsEntry( &( xParams ) ); + + return xReturn; + } + + EventBits_t MPU_xEventGroupWaitBitsImpl( const xEventGroupWaitBitsParams_t * pxParams ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupWaitBitsImpl( const xEventGroupWaitBitsParams_t * pxParams ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + BaseType_t xAreParamsReadable = pdFALSE; + + if( pxParams != NULL ) + { + xAreParamsReadable = xPortIsAuthorizedToAccessBuffer( pxParams, + sizeof( xEventGroupWaitBitsParams_t ), + tskMPU_READ_PERMISSION ); + } + + if( xAreParamsReadable == pdTRUE ) + { + if( ( ( pxParams->uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) && + ( pxParams->uxBitsToWaitFor != 0 ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( pxParams->xTicksToWait != 0 ) ) ) + #endif + ) + { + lIndex = ( int32_t ) ( pxParams->xEventGroup ); + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupWaitBits( xInternalEventGroupHandle, + pxParams->uxBitsToWaitFor, + pxParams->xClearOnExit, + pxParams->xWaitForAllBits, + pxParams->xTicksToWait ); + } + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupClearBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + + if( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) + { + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupClearBits( xInternalEventGroupHandle, uxBitsToClear ); + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupSetBitsImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + + if( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) + { + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSetBits( xInternalEventGroupHandle, uxBitsToSet ); + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + EventBits_t MPU_xEventGroupSyncImpl( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + + if( ( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) && + ( uxBitsToWaitFor != 0 ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) + { + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSync( xInternalEventGroupHandle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t MPU_uxEventGroupGetNumberImpl( void * xEventGroup ) PRIVILEGED_FUNCTION; + + UBaseType_t MPU_uxEventGroupGetNumberImpl( void * xEventGroup ) /* PRIVILEGED_FUNCTION */ + { + UBaseType_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = uxEventGroupGetNumber( xInternalEventGroupHandle ); + } + } + } + + return xReturn; + } + + #endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void MPU_vEventGroupSetNumberImpl( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; + + void MPU_vEventGroupSetNumberImpl( void * xEventGroup, + UBaseType_t uxEventGroupNumber ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + vEventGroupSetNumber( xInternalEventGroupHandle, uxEventGroupNumber ); + } + } + } + } + + #endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Event Group APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t MPU_xEventGroupCreate( void ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + EventGroupHandle_t xExternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalEventGroupHandle = xEventGroupCreate(); + + if( xInternalEventGroupHandle != NULL ) + { + MPU_StoreEventGroupHandleAtIndex( lIndex, xInternalEventGroupHandle ); + xExternalEventGroupHandle = ( EventGroupHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalEventGroupHandle; + } + + #endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + EventGroupHandle_t xExternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalEventGroupHandle = xEventGroupCreateStatic( pxEventGroupBuffer ); + + if( xInternalEventGroupHandle != NULL ) + { + MPU_StoreEventGroupHandleAtIndex( lIndex, xInternalEventGroupHandle ); + xExternalEventGroupHandle = ( EventGroupHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + + return xExternalEventGroupHandle; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ + { + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + vEventGroupDelete( xInternalEventGroupHandle ); + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupGetStaticBuffer( xInternalEventGroupHandle, ppxEventGroupBuffer ); + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupClearBitsFromISR( xInternalEventGroupHandle, uxBitsToClear ); + } + } + + return xReturn; + } + + #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + + #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSetBitsFromISR( xInternalEventGroupHandle, uxBitsToSet, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + + #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + + EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) /* PRIVILEGED_FUNCTION */ + { + EventBits_t xReturn = 0; + EventGroupHandle_t xInternalEventGroupHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xEventGroup; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupGetBitsFromISR( xInternalEventGroupHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* MPU wrappers for stream buffer APIs. */ +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferSendImpl( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xIsTxDataBufferReadable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + if( pvTxData != NULL ) + { + xIsTxDataBufferReadable = xPortIsAuthorizedToAccessBuffer( pvTxData, + xDataLengthBytes, + tskMPU_READ_PERMISSION ); + + if( xIsTxDataBufferReadable == pdTRUE ) + { + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSend( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, xTicksToWait ); + } + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferReceiveImpl( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xIsRxDataBufferWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + if( pvRxData != NULL ) + { + xIsRxDataBufferWriteable = xPortIsAuthorizedToAccessBuffer( pvRxData, + xBufferLengthBytes, + tskMPU_WRITE_PERMISSION ); + + if( xIsRxDataBufferWriteable == pdTRUE ) + { + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceive( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, xTicksToWait ); + } + } + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xStreamBufferIsFullImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsFull( xInternalStreamBufferHandle ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xStreamBufferIsEmptyImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsEmpty( xInternalStreamBufferHandle ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferSpacesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSpacesAvailable( xInternalStreamBufferHandle ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferBytesAvailableImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferBytesAvailable( xInternalStreamBufferHandle ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + + BaseType_t MPU_xStreamBufferSetTriggerLevelImpl( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSetTriggerLevel( xInternalStreamBufferHandle, xTriggerLevel ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + + size_t MPU_xStreamBufferNextMessageLengthBytesImpl( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferNextMessageLengthBytes( xInternalStreamBufferHandle ); + } + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + +/* Privileged only wrappers for Stream Buffer APIs. These are needed so that + * the application can use opaque handles maintained in mpu_wrappers.c + * with all the APIs. */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* PRIVILEGED_FUNCTION */ + { + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + StreamBufferHandle_t xExternalStreamBufferHandle = NULL; + int32_t lIndex; + + /** + * Stream buffer application level callback functionality is disabled for MPU + * enabled ports. + */ + configASSERT( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ); + + if( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ) + { + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalStreamBufferHandle = xStreamBufferGenericCreate( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + NULL, + NULL ); + + if( xInternalStreamBufferHandle != NULL ) + { + MPU_StoreStreamBufferHandleAtIndex( lIndex, xInternalStreamBufferHandle ); + xExternalStreamBufferHandle = ( StreamBufferHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + xExternalStreamBufferHandle = NULL; + } + + return xExternalStreamBufferHandle; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) /* PRIVILEGED_FUNCTION */ + { + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + StreamBufferHandle_t xExternalStreamBufferHandle = NULL; + int32_t lIndex; + + /** + * Stream buffer application level callback functionality is disabled for MPU + * enabled ports. + */ + configASSERT( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ); + + if( ( pxSendCompletedCallback == NULL ) && + ( pxReceiveCompletedCallback == NULL ) ) + { + lIndex = MPU_GetFreeIndexInKernelObjectPool(); + + if( lIndex != -1 ) + { + xInternalStreamBufferHandle = xStreamBufferGenericCreateStatic( xBufferSizeBytes, + xTriggerLevelBytes, + xIsMessageBuffer, + pucStreamBufferStorageArea, + pxStaticStreamBuffer, + NULL, + NULL ); + + if( xInternalStreamBufferHandle != NULL ) + { + MPU_StoreStreamBufferHandleAtIndex( lIndex, xInternalStreamBufferHandle ); + xExternalStreamBufferHandle = ( StreamBufferHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); + } + else + { + MPU_SetIndexFreeInKernelObjectPool( lIndex ); + } + } + } + else + { + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + xExternalStreamBufferHandle = NULL; + } + + return xExternalStreamBufferHandle; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + vStreamBufferDelete( xInternalStreamBufferHandle ); + } + + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReset( xInternalStreamBufferHandle ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers, + uint8_t * ppucStreamBufferStorageArea, + StaticStreamBuffer_t * ppxStaticStreamBuffer ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffers; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = MPU_xStreamBufferGetStaticBuffers( xInternalStreamBufferHandle, ppucStreamBufferStorageArea, ppxStaticStreamBuffer ); + } + } + + return xReturn; + } + + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSendFromISR( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + size_t xReturn = 0; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceiveFromISR( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSendCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) /*PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + StreamBufferHandle_t xInternalStreamBufferHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xStreamBuffer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceiveCompletedFromISR( xInternalStreamBufferHandle, pxHigherPriorityTaskWoken ); + } + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + +/* Functions that the application writer wants to execute in privileged mode + * can be defined in application_defined_privileged_functions.h. */ + + #if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" + #endif +/*-----------------------------------------------------------*/ + +/** + * @brief Array of system call implementation functions. + * + * The index in the array MUST match the corresponding system call number + * defined in mpu_wrappers.h. + */ + PRIVILEGED_DATA UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ] = + { + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + ( UBaseType_t ) MPU_xTaskGenericNotifyImpl, /* SYSTEM_CALL_xTaskGenericNotify. */ + ( UBaseType_t ) MPU_xTaskGenericNotifyWaitImpl, /* SYSTEM_CALL_xTaskGenericNotifyWait. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGenericNotify. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGenericNotifyWait. */ + #endif + + #if ( configUSE_TIMERS == 1 ) + ( UBaseType_t ) MPU_xTimerGenericCommandImpl, /* SYSTEM_CALL_xTimerGenericCommand. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGenericCommand. */ + #endif + + ( UBaseType_t ) MPU_xEventGroupWaitBitsImpl, /* SYSTEM_CALL_xEventGroupWaitBits. */ + + /* The system calls above this line take 5 parameters. */ + + #if ( INCLUDE_xTaskDelayUntil == 1 ) + ( UBaseType_t ) MPU_xTaskDelayUntilImpl, /* SYSTEM_CALL_xTaskDelayUntil. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskDelayUntil. */ + #endif + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + ( UBaseType_t ) MPU_xTaskAbortDelayImpl, /* SYSTEM_CALL_xTaskAbortDelay. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskAbortDelay. */ + #endif + + #if ( INCLUDE_vTaskDelay == 1 ) + ( UBaseType_t ) MPU_vTaskDelayImpl, /* SYSTEM_CALL_vTaskDelay. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTaskDelay. */ + #endif + + #if ( INCLUDE_uxTaskPriorityGet == 1 ) + ( UBaseType_t ) MPU_uxTaskPriorityGetImpl, /* SYSTEM_CALL_uxTaskPriorityGet. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxTaskPriorityGet. */ + #endif + + #if ( INCLUDE_eTaskGetState == 1 ) + ( UBaseType_t ) MPU_eTaskGetStateImpl, /* SYSTEM_CALL_eTaskGetState. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_eTaskGetState. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + ( UBaseType_t ) MPU_vTaskGetInfoImpl, /* SYSTEM_CALL_vTaskGetInfo. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTaskGetInfo. */ + #endif + + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + ( UBaseType_t ) MPU_xTaskGetIdleTaskHandleImpl, /* SYSTEM_CALL_xTaskGetIdleTaskHandle. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGetIdleTaskHandle. */ + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + ( UBaseType_t ) MPU_vTaskSuspendImpl, /* SYSTEM_CALL_vTaskSuspend. */ + ( UBaseType_t ) MPU_vTaskResumeImpl, /* SYSTEM_CALL_vTaskResume. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTaskSuspend. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTaskResume. */ + #endif + + ( UBaseType_t ) MPU_xTaskGetTickCountImpl, /* SYSTEM_CALL_xTaskGetTickCount. */ + ( UBaseType_t ) MPU_uxTaskGetNumberOfTasksImpl, /* SYSTEM_CALL_uxTaskGetNumberOfTasks. */ + ( UBaseType_t ) MPU_pcTaskGetNameImpl, /* SYSTEM_CALL_pcTaskGetName. */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + ( UBaseType_t ) MPU_ulTaskGetRunTimeCounterImpl, /* SYSTEM_CALL_ulTaskGetRunTimeCounter. */ + ( UBaseType_t ) MPU_ulTaskGetRunTimePercentImpl, /* SYSTEM_CALL_ulTaskGetRunTimePercent. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_ulTaskGetRunTimeCounter. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_ulTaskGetRunTimePercent. */ + #endif + + #if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + ( UBaseType_t ) MPU_ulTaskGetIdleRunTimePercentImpl, /* SYSTEM_CALL_ulTaskGetIdleRunTimePercent. */ + ( UBaseType_t ) MPU_ulTaskGetIdleRunTimeCounterImpl, /* SYSTEM_CALL_ulTaskGetIdleRunTimeCounter. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_ulTaskGetIdleRunTimePercent. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_ulTaskGetIdleRunTimeCounter. */ + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + ( UBaseType_t ) MPU_vTaskSetApplicationTaskTagImpl, /* SYSTEM_CALL_vTaskSetApplicationTaskTag. */ + ( UBaseType_t ) MPU_xTaskGetApplicationTaskTagImpl, /* SYSTEM_CALL_xTaskGetApplicationTaskTag. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTaskSetApplicationTaskTag. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGetApplicationTaskTag. */ + #endif + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + ( UBaseType_t ) MPU_vTaskSetThreadLocalStoragePointerImpl, /* SYSTEM_CALL_vTaskSetThreadLocalStoragePointer. */ + ( UBaseType_t ) MPU_pvTaskGetThreadLocalStoragePointerImpl, /* SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTaskSetThreadLocalStoragePointer. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + ( UBaseType_t ) MPU_uxTaskGetSystemStateImpl, /* SYSTEM_CALL_uxTaskGetSystemState. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxTaskGetSystemState. */ + #endif + + #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + ( UBaseType_t ) MPU_uxTaskGetStackHighWaterMarkImpl, /* SYSTEM_CALL_uxTaskGetStackHighWaterMark. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxTaskGetStackHighWaterMark. */ + #endif + + #if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + ( UBaseType_t ) MPU_uxTaskGetStackHighWaterMark2Impl, /* SYSTEM_CALL_uxTaskGetStackHighWaterMark2. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxTaskGetStackHighWaterMark2. */ + #endif + + #if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + ( UBaseType_t ) MPU_xTaskGetCurrentTaskHandleImpl, /* SYSTEM_CALL_xTaskGetCurrentTaskHandle. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGetCurrentTaskHandle. */ + #endif + + #if ( INCLUDE_xTaskGetSchedulerState == 1 ) + ( UBaseType_t ) MPU_xTaskGetSchedulerStateImpl, /* SYSTEM_CALL_xTaskGetSchedulerState. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGetSchedulerState. */ + #endif + + ( UBaseType_t ) MPU_vTaskSetTimeOutStateImpl, /* SYSTEM_CALL_vTaskSetTimeOutState. */ + ( UBaseType_t ) MPU_xTaskCheckForTimeOutImpl, /* SYSTEM_CALL_xTaskCheckForTimeOut. */ + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + ( UBaseType_t ) MPU_ulTaskGenericNotifyTakeImpl, /* SYSTEM_CALL_ulTaskGenericNotifyTake. */ + ( UBaseType_t ) MPU_xTaskGenericNotifyStateClearImpl, /* SYSTEM_CALL_xTaskGenericNotifyStateClear. */ + ( UBaseType_t ) MPU_ulTaskGenericNotifyValueClearImpl, /* SYSTEM_CALL_ulTaskGenericNotifyValueClear. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_ulTaskGenericNotifyTake. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTaskGenericNotifyStateClear. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_ulTaskGenericNotifyValueClear. */ + #endif + + ( UBaseType_t ) MPU_xQueueGenericSendImpl, /* SYSTEM_CALL_xQueueGenericSend. */ + ( UBaseType_t ) MPU_uxQueueMessagesWaitingImpl, /* SYSTEM_CALL_uxQueueMessagesWaiting. */ + ( UBaseType_t ) MPU_uxQueueSpacesAvailableImpl, /* SYSTEM_CALL_uxQueueSpacesAvailable. */ + ( UBaseType_t ) MPU_xQueueReceiveImpl, /* SYSTEM_CALL_xQueueReceive. */ + ( UBaseType_t ) MPU_xQueuePeekImpl, /* SYSTEM_CALL_xQueuePeek. */ + ( UBaseType_t ) MPU_xQueueSemaphoreTakeImpl, /* SYSTEM_CALL_xQueueSemaphoreTake. */ + + #if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + ( UBaseType_t ) MPU_xQueueGetMutexHolderImpl, /* SYSTEM_CALL_xQueueGetMutexHolder. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xQueueGetMutexHolder. */ + #endif + + #if ( configUSE_RECURSIVE_MUTEXES == 1 ) + ( UBaseType_t ) MPU_xQueueTakeMutexRecursiveImpl, /* SYSTEM_CALL_xQueueTakeMutexRecursive. */ + ( UBaseType_t ) MPU_xQueueGiveMutexRecursiveImpl, /* SYSTEM_CALL_xQueueGiveMutexRecursive. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xQueueTakeMutexRecursive. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xQueueGiveMutexRecursive. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + ( UBaseType_t ) MPU_xQueueSelectFromSetImpl, /* SYSTEM_CALL_xQueueSelectFromSet. */ + ( UBaseType_t ) MPU_xQueueAddToSetImpl, /* SYSTEM_CALL_xQueueAddToSet. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_xQueueSelectFromSet. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xQueueAddToSet. */ + #endif + + #if configQUEUE_REGISTRY_SIZE > 0 + ( UBaseType_t ) MPU_vQueueAddToRegistryImpl, /* SYSTEM_CALL_vQueueAddToRegistry. */ + ( UBaseType_t ) MPU_vQueueUnregisterQueueImpl, /* SYSTEM_CALL_vQueueUnregisterQueue. */ + ( UBaseType_t ) MPU_pcQueueGetNameImpl, /* SYSTEM_CALL_pcQueueGetName. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_vQueueAddToRegistry. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_vQueueUnregisterQueue. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_pcQueueGetName. */ + #endif + + #if ( configUSE_TIMERS == 1 ) + ( UBaseType_t ) MPU_pvTimerGetTimerIDImpl, /* SYSTEM_CALL_pvTimerGetTimerID. */ + ( UBaseType_t ) MPU_vTimerSetTimerIDImpl, /* SYSTEM_CALL_vTimerSetTimerID. */ + ( UBaseType_t ) MPU_xTimerIsTimerActiveImpl, /* SYSTEM_CALL_xTimerIsTimerActive. */ + ( UBaseType_t ) MPU_xTimerGetTimerDaemonTaskHandleImpl, /* SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle. */ + ( UBaseType_t ) MPU_pcTimerGetNameImpl, /* SYSTEM_CALL_pcTimerGetName. */ + ( UBaseType_t ) MPU_vTimerSetReloadModeImpl, /* SYSTEM_CALL_vTimerSetReloadMode. */ + ( UBaseType_t ) MPU_xTimerGetReloadModeImpl, /* SYSTEM_CALL_xTimerGetReloadMode. */ + ( UBaseType_t ) MPU_uxTimerGetReloadModeImpl, /* SYSTEM_CALL_uxTimerGetReloadMode. */ + ( UBaseType_t ) MPU_xTimerGetPeriodImpl, /* SYSTEM_CALL_xTimerGetPeriod. */ + ( UBaseType_t ) MPU_xTimerGetExpiryTimeImpl, /* SYSTEM_CALL_xTimerGetExpiryTime. */ + #else /* if ( configUSE_TIMERS == 1 ) */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_pvTimerGetTimerID. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTimerSetTimerID. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerIsTimerActive. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_pcTimerGetName. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_vTimerSetReloadMode. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGetReloadMode. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxTimerGetReloadMode. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGetPeriod. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_xTimerGetExpiryTime. */ + #endif /* if ( configUSE_TIMERS == 1 ) */ + + ( UBaseType_t ) MPU_xEventGroupClearBitsImpl, /* SYSTEM_CALL_xEventGroupClearBits. */ + ( UBaseType_t ) MPU_xEventGroupSetBitsImpl, /* SYSTEM_CALL_xEventGroupSetBits. */ + ( UBaseType_t ) MPU_xEventGroupSyncImpl, /* SYSTEM_CALL_xEventGroupSync. */ + + #if ( configUSE_TRACE_FACILITY == 1 ) + ( UBaseType_t ) MPU_uxEventGroupGetNumberImpl, /* SYSTEM_CALL_uxEventGroupGetNumber. */ + ( UBaseType_t ) MPU_vEventGroupSetNumberImpl, /* SYSTEM_CALL_vEventGroupSetNumber. */ + #else + ( UBaseType_t ) 0, /* SYSTEM_CALL_uxEventGroupGetNumber. */ + ( UBaseType_t ) 0, /* SYSTEM_CALL_vEventGroupSetNumber. */ + #endif + + ( UBaseType_t ) MPU_xStreamBufferSendImpl, /* SYSTEM_CALL_xStreamBufferSend. */ + ( UBaseType_t ) MPU_xStreamBufferReceiveImpl, /* SYSTEM_CALL_xStreamBufferReceive. */ + ( UBaseType_t ) MPU_xStreamBufferIsFullImpl, /* SYSTEM_CALL_xStreamBufferIsFull. */ + ( UBaseType_t ) MPU_xStreamBufferIsEmptyImpl, /* SYSTEM_CALL_xStreamBufferIsEmpty. */ + ( UBaseType_t ) MPU_xStreamBufferSpacesAvailableImpl, /* SYSTEM_CALL_xStreamBufferSpacesAvailable. */ + ( UBaseType_t ) MPU_xStreamBufferBytesAvailableImpl, /* SYSTEM_CALL_xStreamBufferBytesAvailable. */ + ( UBaseType_t ) MPU_xStreamBufferSetTriggerLevelImpl, /* SYSTEM_CALL_xStreamBufferSetTriggerLevel. */ + ( UBaseType_t ) MPU_xStreamBufferNextMessageLengthBytesImpl /* SYSTEM_CALL_xStreamBufferNextMessageLengthBytes. */ + }; +/*-----------------------------------------------------------*/ + +#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c new file mode 100644 index 0000000..73430b5 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c @@ -0,0 +1,857 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/*----------------------------------------------------------- +* Implementation of functions defined in portable.h for the ARM CM4F port. +*----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __VFP_FP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( *( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( *( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SHPR3_REG ( *( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_SET_BIT ( 1UL << 26UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 + * r0p1 port. */ +#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) +#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) +#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) + +#define portMIN_INTERRUPT_PRIORITY ( 255UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) portMIN_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( *( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0xFFUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXC_RETURN ( 0xfffffffd ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* For strict compliance with the Cortex-M spec the task start address should + * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have + * occurred while the SysTick counter is stopped during tickless idle + * calculations. */ +#define portMISSED_COUNTS_FACTOR ( 94UL ) + +/* Let the user override the default SysTick clock rate. If defined by the + * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the + * configuration register. */ +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ ) + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( portNVIC_SYSTICK_CLK_BIT ) +#else + /* Select the option to clock SysTick not at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT_CONFIG ( 0 ) +#endif + +/* Let the user override the pre-loading of the initial LR with the address of + * prvTaskExitError() in case it messes up unwinding of the stack in the + * debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__( ( naked ) ); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__( ( naked ) ); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__( ( naked ) ); + +/* + * Function to enable the VFP. + */ +static void vPortEnableVFP( void ) __attribute__( ( naked ) ); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* Each task maintains its own interrupt status in the critical nesting + * variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * The number of SysTick increments that make up one tick period. + */ +#if ( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if ( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if ( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + * interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + * of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + * own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + volatile uint32_t ulDummy = 0; + + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). + * + * Artificially force an assert() to be triggered if configASSERT() is + * defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + * started to remove a compiler warning about the function being defined + * but never called. ulDummy is used purely to quieten other warnings + * about code appearing after this function is called - making ulDummy + * volatile makes the compiler think the function could return and + * therefore not output an 'unreachable code' warning for code that appears + * after it. */ + } +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + /* Start the first task. This also clears the bit that indicates the FPU is + * in use in case the FPU was used before the scheduler was started - which + * would otherwise result in the unnecessary leaving of space in the SVC stack + * for lazy saving of FPU registers. */ + __asm volatile ( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr control, r0 \n" + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + " .ltorg \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* This port can be used on all revisions of the Cortex-M7 core other than + * the r0p1 parts. r0p1 parts should use the port from the + * /source/portable/GCC/ARM_CM7/r0p1 directory. */ + configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); + configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); + + #if ( configASSERT_DEFINED == 1 ) + { + volatile uint8_t ucOriginalPriority; + volatile uint32_t ulImplementedPrioBits = 0; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + * functions can be called. ISR safe functions are those that end in + * "FromISR". FreeRTOS maintains separate thread and ISR API functions to + * ensure interrupt entry is as fast and simple as possible. + * + * Save the interrupt priority value that is about to be clobbered. */ + ucOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + * possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Check that the maximum system call priority is nonzero after + * accounting for the number of priority bits supported by the + * hardware. A priority of 0 is invalid because setting the BASEPRI + * register to 0 unmasks all interrupts, and interrupts with priority 0 + * cannot be masked using BASEPRI. + * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ucMaxSysCallPriority ); + + /* Check that the bits not implemented in hardware are zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( ~ucMaxPriorityValue ) ) == 0U ); + + /* Calculate the maximum acceptable priority group value for the number + * of bits read back. */ + + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulImplementedPrioBits++; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + if( ulImplementedPrioBits == 8 ) + { + /* When the hardware implements 8 priority bits, there is no way for + * the software to configure PRIGROUP to not have sub-priorities. As + * a result, the least significant bit is always used for sub-priority + * and there are 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. + * + * The following assert ensures that the sub-priority bit in the + * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned + * confusion. */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); + ulMaxPRIGROUPValue = 0; + } + else + { + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; + } + + /* Shift the priority group value back to its position within the AIRCR + * register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + * value. */ + *pucFirstUserPriorityRegister = ucOriginalPriority; + } + #endif /* configASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; + portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + * here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + * exit error function to prevent compiler warnings about a static function + * not being called in the case that the application writer overrides this + * functionality by defining configTASK_RETURN_ADDRESS. Call + * vTaskSwitchContext() so link time optimisation does not remove the + * symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + * assert() if it is being called from an interrupt context. Only API + * functions that end in "FromISR" can be used in an interrupt. Only assert if + * the critical nesting count is 1 to protect against recursive calls if the + * assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + " \n" + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r0, r3} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r0, r3} \n" + " \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" + " \n" + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" + " \n" + " msr psp, r0 \n" + " isb \n" + " \n" + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ + #if WORKAROUND_PMU_CM001 == 1 + " push { r14 } \n" + " pop { pc } \n" + #endif + #endif + " \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + * executes all interrupts must be unmasked. There is therefore no need to + * save and then restore the interrupt mask value as its value is already + * known. */ + portDISABLE_INTERRUPTS(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + * the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portENABLE_INTERRUPTS(); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + + __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Re-enable interrupts - see comments above the cpsid instruction + * above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + else + { + /* Stop the SysTick momentarily. The time the SysTick is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Use the SysTick current-value register to determine the number of + * SysTick decrements remaining until the next tick interrupt. If the + * current-value register is zero, then there are actually + * ulTimerCountsForOneTick decrements remaining, not zero, because the + * SysTick requests the interrupt when decrementing from 1 to 0. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulTimerCountsForOneTick; + } + + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. -1 is used because this code normally executes part + * way through the first tick period. But if the SysTick IRQ is now + * pending, then clear the IRQ, suppressing the first tick, and correct + * the reload value to reflect that the second tick period is already + * underway. The expected idle time is always at least two ticks. */ + ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + + if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 ) + { + portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT; + ulReloadValue -= ulTimerCountsForOneTick; + } + + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + * zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + + if( xModifiableIdleTime > 0 ) + { + __asm volatile ( "dsb" ::: "memory" ); + __asm volatile ( "wfi" ); + __asm volatile ( "isb" ); + } + + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + * out of sleep mode to execute immediately. See comments above + * the cpsid instruction above. */ + __asm volatile ( "cpsie i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + * and interrupts that execute while the clock is stopped will increase + * any slippage between the time maintained by the RTOS and calendar + * time. */ + __asm volatile ( "cpsid i" ::: "memory" ); + __asm volatile ( "dsb" ); + __asm volatile ( "isb" ); + + /* Disable the SysTick clock without reading the + * portNVIC_SYSTICK_CTRL_REG register to ensure the + * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + * the time the SysTick is stopped for is accounted for as best it can + * be, but using the tickless mode will inevitably result in some tiny + * drift of the time maintained by the kernel with respect to calendar + * time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT ); + + /* Determine whether the SysTick has already counted to zero. */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt ended the sleep (or is now pending), and + * a new tick period has started. Reset portNVIC_SYSTICK_LOAD_REG + * with whatever remains of the new tick period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + * underflowed because the post sleep hook did something + * that took too long or because the SysTick current-value register + * is zero. */ + if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + * function exits, the tick value maintained by the tick is stepped + * forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. */ + + /* Use the SysTick current-value register to determine the + * number of SysTick decrements remaining until the expected idle + * time would have ended. */ + ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT ) + { + /* If the SysTick is not using the core clock, the current- + * value register might still be zero here. In that case, the + * SysTick didn't load from the reload register, and there are + * ulReloadValue decrements remaining in the expected idle + * time, not zero. */ + if( ulSysTickDecrementsLeft == 0 ) + { + ulSysTickDecrementsLeft = ulReloadValue; + } + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part + * ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft; + + /* How many complete tick periods passed while the processor + * was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + * period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, + * then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If + * the SysTick is not using the core clock, temporarily configure it to + * use the core clock. This configuration forces the SysTick to load + * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next + * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready + * to receive the standard value immediately. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT ) + { + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + #else + { + /* The temporary usage of the core clock has served its purpose, + * as described above. Resume usage of the other clock. */ + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT; + + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + /* The partial tick period already ended. Be sure the SysTick + * counts it only once. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0; + } + + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; + } + #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */ + + /* Step the tick to account for any tick periods that elapsed. */ + vTaskStepTick( ulCompleteTickPeriods ); + + /* Exit with interrupts enabled. */ + __asm volatile ( "cpsie i" ::: "memory" ); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if ( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and clear the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vPortEnableVFP( void ) +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 \n" + " .ltorg \n" + ); +} +/*-----------------------------------------------------------*/ + +#if ( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + * an interrupt that has been assigned a priority above + * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + * function. ISR safe FreeRTOS API functions must *only* be called + * from interrupts that have been assigned a priority at or below + * configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * Numerically low interrupt priority numbers represent logically high + * interrupt priorities, therefore the priority of the interrupt must + * be set to a value equal to or numerically *higher* than + * configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * Interrupts that use the FreeRTOS API must not be left at their + * default priority of zero as that is the highest possible priority, + * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + * and therefore also guaranteed to be invalid. + * + * FreeRTOS maintains separate thread and ISR API functions to ensure + * interrupt entry is as fast and simple as possible. + * + * The following links provide detailed information: + * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html + * https://www.FreeRTOS.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + * that define each interrupt's priority to be split between bits that + * define the interrupt's pre-emption priority bits and bits that define + * the interrupt's sub-priority. For simplicity all bits must be defined + * to be pre-emption priority bits. The following assertion will fail if + * this is not the case (if some bits represent a sub-priority). + * + * If the application only uses CMSIS libraries for interrupt + * configuration then the correct setting can be achieved on all Cortex-M + * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + * scheduler. Note however that some vendor specific peripheral libraries + * assume a non-zero priority group setting, in which cases using a value + * of zero will result in unpredictable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h b/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..ec9cfc9 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h @@ -0,0 +1,254 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + +#ifndef PORTMACRO_H + #define PORTMACRO_H + +/* *INDENT-OFF* */ +#ifdef __cplusplus + extern "C" { +#endif +/* *INDENT-ON* */ + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ + #define portCHAR char + #define portFLOAT float + #define portDOUBLE double + #define portLONG long + #define portSHORT short + #define portSTACK_TYPE uint32_t + #define portBASE_TYPE long + + typedef portSTACK_TYPE StackType_t; + typedef long BaseType_t; + typedef unsigned long UBaseType_t; + + #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + * not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 + #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + typedef uint64_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffffffffffULL + #else + #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width. + #endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ + #define portSTACK_GROWTH ( -1 ) + #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) + #define portBYTE_ALIGNMENT 8 + #define portDONT_DISCARD __attribute__( ( used ) ) +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ + #define portYIELD() \ + { \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + * within the specified behaviour for the architecture. */ \ + __asm volatile ( "dsb" ::: "memory" ); \ + __asm volatile ( "isb" ); \ + } + + #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) + #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) + #define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD(); } while( 0 ) + #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ + extern void vPortEnterCritical( void ); + extern void vPortExitCritical( void ); + #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortSetBASEPRI( x ) + #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() + #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) + #define portENTER_CRITICAL() vPortEnterCritical() + #define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are + * not necessary for to use this port. They are defined so the common demo files + * (which build with all the ports) will build. */ + #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) + #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ + #ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) + #endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ + #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 + #endif + + #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + +/* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); + + return ucReturn; + } + +/* Check the configuration. */ + #if ( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + +/* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + +/*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + + #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + + #ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() + #endif + +/* portNOP() is not required by this port. */ + #define portNOP() + + #define portINLINE __inline + + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__( ( always_inline ) ) + #endif + + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) + { + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; + } + +/*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortRaiseBASEPRI( void ) + { + uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n"\ + " msr basepri, %0 \n"\ + " isb \n"\ + " dsb \n"\ + : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); + } + +/*-----------------------------------------------------------*/ + + portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) + { + uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n"\ + " mov %1, %2 \n"\ + " msr basepri, %1 \n"\ + " isb \n"\ + " dsb \n"\ + : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); + + /* This return will not be reached but is necessary to prevent compiler + * warnings. */ + return ulOriginalBASEPRI; + } +/*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) + { + __asm volatile + ( + " msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory" + ); + } +/*-----------------------------------------------------------*/ + + #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ + +#endif /* PORTMACRO_H */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c b/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c new file mode 100644 index 0000000..013364f --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c @@ -0,0 +1,555 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of https://www.FreeRTOS.org for more information. + */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +#ifndef configHEAP_CLEAR_MEMORY_ON_FREE + #define configHEAP_CLEAR_MEMORY_ON_FREE 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Max value that fits in a size_t type. */ +#define heapSIZE_MAX ( ~( ( size_t ) 0 ) ) + +/* Check if multiplying a and b will result in overflow. */ +#define heapMULTIPLY_WILL_OVERFLOW( a, b ) ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) ) + +/* Check if adding a and b will result in overflow. */ +#define heapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( heapSIZE_MAX - ( b ) ) ) + +/* MSB of the xBlockSize member of an BlockLink_t structure is used to track + * the allocation status of a block. When MSB of the xBlockSize member of + * an BlockLink_t structure is set then the block belongs to the application. + * When the bit is free the block is still part of the free heap space. */ +#define heapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) ) +#define heapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 ) +#define heapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 ) +#define heapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK ) +#define heapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK ) + +/*-----------------------------------------------------------*/ + +/* Allocate the memory for the heap. */ +#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) + +/* The application writer has already defined the array used for the RTOS +* heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#else + PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Define the linked list structure. This is used to link free blocks in order + * of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */ + size_t xBlockSize; /**< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION; + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory + * block must by correctly byte aligned. */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +PRIVILEGED_DATA static BlockLink_t xStart; +PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL; + +/* Keeps track of the number of calls to allocate and free memory as well as the + * number of free bytes remaining, but says nothing about fragmentation. */ +PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; +PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; + +/*-----------------------------------------------------------*/ + +void * pvPortMalloc( size_t xWantedSize ) +{ + BlockLink_t * pxBlock; + BlockLink_t * pxPreviousBlock; + BlockLink_t * pxNewBlockLink; + void * pvReturn = NULL; + size_t xAdditionalRequiredSize; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + * initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWantedSize > 0 ) + { + /* The wanted size must be increased so it can contain a BlockLink_t + * structure in addition to the requested amount of bytes. */ + if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + * of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ); + + if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 ) + { + xWantedSize += xAdditionalRequiredSize; + } + else + { + xWantedSize = 0; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xWantedSize = 0; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the block size we are trying to allocate is not so large that the + * top bit is set. The top bit of the block size member of the BlockLink_t + * structure is used to determine who owns the block - the application or + * the kernel, so it must be free. */ + if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 ) + { + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + * one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + * was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + * BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + * of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + * two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + * block following the number of bytes requested. The void + * cast is used to prevent byte alignment warnings from the + * compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the + * single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + * by the application and has no "next" block. */ + heapALLOCATE_BLOCK( pxBlock ); + pxBlock->pxNextFreeBlock = NULL; + xNumberOfSuccessfulAllocations++; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */ + + configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void * pv ) +{ + uint8_t * puc = ( uint8_t * ) pv; + BlockLink_t * pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + * before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + * allocated. */ + heapFREE_BLOCK( pxLink ); + #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 ) + { + ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize ); + } + #endif + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + xNumberOfSuccessfulFrees++; + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +void * pvPortCalloc( size_t xNum, + size_t xSize ) +{ + void * pv = NULL; + + if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 ) + { + pv = pvPortMalloc( xNum * xSize ); + + if( pv != NULL ) + { + ( void ) memset( pv, 0, xNum * xSize ); + } + } + + return pv; +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ +{ + BlockLink_t * pxFirstFreeBlock; + uint8_t * pucAlignedHeap; + portPOINTER_SIZE_TYPE uxAddress; + size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( portPOINTER_SIZE_TYPE ) ucHeap; + + if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( portBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) ucHeap ); + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + * blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + * at the end of the heap space. */ + uxAddress = ( portPOINTER_SIZE_TYPE ) ( pucAlignedHeap + xTotalHeapSize ); + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ); + pxEnd = ( BlockLink_t * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + * entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( BlockLink_t * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = ( size_t ) ( uxAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlock ); + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */ +{ + BlockLink_t * pxIterator; + uint8_t * puc; + + /* Iterate through the list until a block is found that has a higher address + * than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + * before and the block after, then it's pxNextFreeBlock pointer will have + * already been set, and should not be set here as that would make it point + * to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void vPortGetHeapStats( HeapStats_t * pxHeapStats ) +{ + BlockLink_t * pxBlock; + size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ + + vTaskSuspendAll(); + { + pxBlock = xStart.pxNextFreeBlock; + + /* pxBlock will be NULL if the heap has not been initialised. The heap + * is initialised automatically when the first allocation is made. */ + if( pxBlock != NULL ) + { + while( pxBlock != pxEnd ) + { + /* Increment the number of blocks and record the largest block seen + * so far. */ + xBlocks++; + + if( pxBlock->xBlockSize > xMaxSize ) + { + xMaxSize = pxBlock->xBlockSize; + } + + if( pxBlock->xBlockSize < xMinSize ) + { + xMinSize = pxBlock->xBlockSize; + } + + /* Move to the next block in the chain until the last block is + * reached. */ + pxBlock = pxBlock->pxNextFreeBlock; + } + } + } + ( void ) xTaskResumeAll(); + + pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; + pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; + pxHeapStats->xNumberOfFreeBlocks = xBlocks; + + taskENTER_CRITICAL(); + { + pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining; + pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations; + pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees; + pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/queue.c b/Middlewares/Third_Party/FreeRTOS/Source/queue.c new file mode 100644 index 0000000..40edbe4 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/queue.c @@ -0,0 +1,3148 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified + * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined + * for the header files above, but not in this file, in order to generate the + * correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( int8_t ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 ) +#define queueINT8_MAX ( ( int8_t ) 127 ) + +/* When the Queue_t structure is used to represent a base queue its pcHead and + * pcTail members are used as pointers into the queue storage area. When the + * Queue_t structure is used to represent a mutex pcHead and pcTail pointers are + * not necessary, and the pcHead pointer is set to NULL to indicate that the + * structure instead holds a pointer to the mutex holder (if any). Map alternative + * names to the pcHead and structure member to ensure the readability of the code + * is maintained. The QueuePointers_t and SemaphoreData_t types are used to form + * a union as their usage is mutually exclusive dependent on what the queue is + * being used for. */ +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +typedef struct QueuePointers +{ + int8_t * pcTail; /**< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t * pcReadFrom; /**< Points to the last place that a queued item was read from when the structure is used as a queue. */ +} QueuePointers_t; + +typedef struct SemaphoreData +{ + TaskHandle_t xMutexHolder; /**< The handle of the task that holds the mutex. */ + UBaseType_t uxRecursiveCallCount; /**< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ +} SemaphoreData_t; + +/* Semaphores do not actually store or copy data, so have an item size of + * zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + +#if ( configUSE_PREEMPTION == 0 ) + +/* If the cooperative scheduler is being used then a yield should not be + * performed just because a higher priority task has been woken. */ + #define queueYIELD_IF_USING_PREEMPTION() +#else + #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. See the following link for the + * rationale: https://www.FreeRTOS.org/Embedded-RTOS-Queues.html + */ +typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + int8_t * pcHead; /**< Points to the beginning of the queue storage area. */ + int8_t * pcWriteTo; /**< Points to the free next place in the storage area. */ + + union + { + QueuePointers_t xQueue; /**< Data required exclusively when this structure is used as a queue. */ + SemaphoreData_t xSemaphore; /**< Data required exclusively when this structure is used as a semaphore. */ + } u; + + List_t xTasksWaitingToSend; /**< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /**< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting; /**< The number of items currently in the queue. */ + UBaseType_t uxLength; /**< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /**< The size of each items that the queue will hold. */ + + volatile int8_t cRxLock; /**< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /**< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition * pxQueueSetContainer; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t + * name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + +/* The type stored within the queue registry array. This allows a name + * to be assigned to each queue making kernel aware debugging a little + * more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + const char * pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + QueueHandle_t xHandle; + } xQueueRegistryItem; + +/* The old xQueueRegistryItem name is maintained above then typedefed to the + * new xQueueRegistryItem name below to enable the use of older kernel aware + * debuggers. */ + typedef xQueueRegistryItem QueueRegistryItem_t; + +/* The queue registry is simply an array of QueueRegistryItem_t structures. + * The pcQueueName member of a structure being NULL is indicative of the + * array position being vacant. */ + PRIVILEGED_DATA QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static BaseType_t prvIsQueueEmpty( const Queue_t * pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static BaseType_t prvIsQueueFull( const Queue_t * pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, + const void * pvItemToQueue, + const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( Queue_t * const pxQueue, + void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + +/* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * Called after a Queue_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + const uint8_t ucQueueType, + Queue_t * pxNewQueue ) PRIVILEGED_FUNCTION; + +/* + * Mutexes are a special type of queue. When a mutex is created, first the + * queue is created, then prvInitialiseMutex() is called to configure the queue + * as a mutex. + */ +#if ( configUSE_MUTEXES == 1 ) + static void prvInitialiseMutex( Queue_t * pxNewQueue ) PRIVILEGED_FUNCTION; +#endif + +#if ( configUSE_MUTEXES == 1 ) + +/* + * If a task waiting for a mutex causes the mutex holder to inherit a + * priority, but the waiting task times out, then the holder should + * disinherit the priority - but only down to the highest priority of any + * other tasks that are waiting for the same mutex. This function returns + * that priority. + */ + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; +#endif +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->cRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->cTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() + +/* + * Macro to increment cTxLock member of the queue data structure. It is + * capped at the number of tasks in the system as we cannot unblock more + * tasks than the number of tasks in the system. + */ +#define prvIncrementQueueTxLock( pxQueue, cTxLock ) \ + do { \ + const UBaseType_t uxNumberOfTasks = uxTaskGetNumberOfTasks(); \ + if( ( UBaseType_t ) ( cTxLock ) < uxNumberOfTasks ) \ + { \ + configASSERT( ( cTxLock ) != queueINT8_MAX ); \ + ( pxQueue )->cTxLock = ( int8_t ) ( ( cTxLock ) + ( int8_t ) 1 ); \ + } \ + } while( 0 ) + +/* + * Macro to increment cRxLock member of the queue data structure. It is + * capped at the number of tasks in the system as we cannot unblock more + * tasks than the number of tasks in the system. + */ +#define prvIncrementQueueRxLock( pxQueue, cRxLock ) \ + do { \ + const UBaseType_t uxNumberOfTasks = uxTaskGetNumberOfTasks(); \ + if( ( UBaseType_t ) ( cRxLock ) < uxNumberOfTasks ) \ + { \ + configASSERT( ( cRxLock ) != queueINT8_MAX ); \ + ( pxQueue )->cRxLock = ( int8_t ) ( ( cRxLock ) + ( int8_t ) 1 ); \ + } \ + } while( 0 ) +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, + BaseType_t xNewQueue ) +{ + BaseType_t xReturn = pdPASS; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + if( ( pxQueue != NULL ) && + ( pxQueue->uxLength >= 1U ) && + /* Check for multiplication overflow. */ + ( ( SIZE_MAX / pxQueue->uxLength ) >= pxQueue->uxItemSize ) ) + { + taskENTER_CRITICAL(); + { + pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->cRxLock = queueUNLOCKED; + pxQueue->cTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + * the tasks will remain blocked as after this function exits the queue + * will still be empty. If there are tasks blocked waiting to write to + * the queue, then one should be unblocked as after this function exits + * it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + } + else + { + xReturn = pdFAIL; + } + + configASSERT( xReturn != pdFAIL ); + + /* A value is returned for calling semantic consistency with previous + * versions. */ + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + StaticQueue_t * pxStaticQueue, + const uint8_t ucQueueType ) + { + Queue_t * pxNewQueue = NULL; + + /* The StaticQueue_t structure and the queue storage area must be + * supplied. */ + configASSERT( pxStaticQueue ); + + if( ( uxQueueLength > ( UBaseType_t ) 0 ) && + ( pxStaticQueue != NULL ) && + + /* A queue storage area should be provided if the item size is not 0, and + * should not be provided if the item size is 0. */ + ( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ) && + ( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ) ) + { + #if ( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + * variable of type StaticQueue_t or StaticSemaphore_t equals the size of + * the real queue and semaphore structures. */ + volatile size_t xSize = sizeof( StaticQueue_t ); + + /* This assertion cannot be branch covered in unit tests */ + configASSERT( xSize == sizeof( Queue_t ) ); /* LCOV_EXCL_BR_LINE */ + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* The address of a statically allocated queue was passed in, use it. + * The address of a statically allocated storage area was also passed in + * but is already set. */ + pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Queues can be allocated wither statically or dynamically, so + * note this queue was allocated statically in case the queue is + * later deleted. */ + pxNewQueue->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + configASSERT( pxNewQueue ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue, + uint8_t ** ppucQueueStorage, + StaticQueue_t ** ppxStaticQueue ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( ppxStaticQueue ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Check if the queue was statically allocated. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) + { + if( ppucQueueStorage != NULL ) + { + *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead; + } + + *ppxStaticQueue = ( StaticQueue_t * ) pxQueue; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* configSUPPORT_DYNAMIC_ALLOCATION */ + { + /* Queue must have been statically allocated. */ + if( ppucQueueStorage != NULL ) + { + *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead; + } + + *ppxStaticQueue = ( StaticQueue_t * ) pxQueue; + xReturn = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + return xReturn; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + const uint8_t ucQueueType ) + { + Queue_t * pxNewQueue = NULL; + size_t xQueueSizeInBytes; + uint8_t * pucQueueStorage; + + if( ( uxQueueLength > ( UBaseType_t ) 0 ) && + /* Check for multiplication overflow. */ + ( ( SIZE_MAX / uxQueueLength ) >= uxItemSize ) && + /* Check for addition overflow. */ + ( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) ) ) + { + /* Allocate enough space to hold the maximum number of items that + * can be in the queue at any time. It is valid for uxItemSize to be + * zero in the case the queue is used as a semaphore. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Allocate the queue and storage area. Justification for MISRA + * deviation as follows: pvPortMalloc() always ensures returned memory + * blocks are aligned per the requirements of the MCU stack. In this case + * pvPortMalloc() must return a pointer that is guaranteed to meet the + * alignment requirements of the Queue_t structure - which in this case + * is an int8_t *. Therefore, whenever the stack alignment requirements + * are greater than or equal to the pointer to char requirements the cast + * is safe. In other cases alignment requirements are not strict (one or + * two bytes). */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */ + + if( pxNewQueue != NULL ) + { + /* Jump past the queue structure to find the location of the queue + * storage area. */ + pucQueueStorage = ( uint8_t * ) pxNewQueue; + pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Queues can be created either statically or dynamically, so + * note this task was created dynamically in case it is later + * deleted. */ + pxNewQueue->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + configASSERT( pxNewQueue ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, + uint8_t * pucQueueStorage, + const uint8_t ucQueueType, + Queue_t * pxNewQueue ) +{ + /* Remove compiler warnings about unused parameters should + * configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* No RAM was allocated for the queue storage area, but PC head cannot + * be set to NULL because NULL is used as a key to say the queue is used as + * a mutex. Therefore just set pcHead to point to the queue as a benign + * value that is known to be within the memory map. */ + pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; + } + else + { + /* Set the head to the start of the queue storage area. */ + pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; + } + + /* Initialise the queue members as described where the queue type is + * defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if ( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + static void prvInitialiseMutex( Queue_t * pxNewQueue ) + { + if( pxNewQueue != NULL ) + { + /* The queue create function will set all the queue structure members + * correctly for a generic queue, but this function is creating a + * mutex. Overwrite those members that need to be set differently - + * in particular the information required for priority inheritance. */ + pxNewQueue->u.xSemaphore.xMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* In case this is a recursive mutex. */ + pxNewQueue->u.xSemaphore.uxRecursiveCallCount = 0; + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + xNewQueue = xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, + StaticQueue_t * pxStaticQueue ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + /* Prevent compiler warnings about unused parameters if + * configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + xNewQueue = xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore; + + configASSERT( xSemaphore ); + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + * be called directly. Note: This is a good way of determining if the + * calling task is the mutex holder, but not a good way of determining the + * identity of the mutex holder, as the holder may change between the + * following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( pxSemaphore->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = pxSemaphore->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + + configASSERT( xSemaphore ); + + /* Mutexes cannot be used in interrupt service routines, so the mutex + * holder should not change in an ISR, and therefore a critical section is + * not required here. */ + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( ( Queue_t * ) xSemaphore )->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then xMutexHolder will not + * change outside of this task. If this task does not hold the mutex then + * pxMutexHolder can never coincidentally equal the tasks handle, and as + * this is the only condition we are interested in it does not matter if + * pxMutexHolder is accessed simultaneously by another task. Therefore no + * mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if xMutexHolder is equal to + * the task handle, therefore no underflow check is required. Also, + * uxRecursiveCallCount is only modified by the mutex holder, and as + * there can only be one, no mutual exclusion is required to modify the + * uxRecursiveCallCount member. */ + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )--; + + /* Has the recursive call count unwound to 0? */ + if( pxMutex->u.xSemaphore.uxRecursiveCallCount == ( UBaseType_t ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + * task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + /* The mutex cannot be given because the calling task is not the + * holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, + TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + * xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait ); + + /* pdPASS will only be returned if the mutex was successfully + * obtained. The calling task may have entered the Blocked state + * before reaching here. */ + if( xReturn != pdFAIL ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, + StaticQueue_t * pxStaticQueue ) + { + QueueHandle_t xHandle = NULL; + + if( ( uxMaxCount != 0 ) && + ( uxInitialCount <= uxMaxCount ) ) + { + xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + } + else + { + configASSERT( xHandle ); + mtCOVERAGE_TEST_MARKER(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount ) + { + QueueHandle_t xHandle = NULL; + + if( ( uxMaxCount != 0 ) && + ( uxInitialCount <= uxMaxCount ) ) + { + xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + } + else + { + configASSERT( xHandle ); + mtCOVERAGE_TEST_MARKER(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) +{ + BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; + TimeOut_t xTimeOut; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + /*lint -save -e904 This function relaxes the coding standard somewhat to + * allow return statements within the function itself. This is done in the + * interest of execution time efficiency. */ + for( ; ; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be the + * highest priority task wanting to access the queue. If the head item + * in the queue is to be overwritten then it does not matter if the + * queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; + + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) + { + /* Do not notify the queue set as an existing item + * was overwritten in the queue so the number of items + * in the queue has not changed. */ + mtCOVERAGE_TEST_MARKER(); + } + else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + * to the queue set caused a higher priority task to + * unblock. A context switch is required. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + * queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + * our own so yield immediately. Yes it is ok to + * do this from within the critical section - the + * kernel takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + * executed if the task was holding multiple mutexes + * and the mutexes were given back in an order that is + * different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + * queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + * our own so yield immediately. Yes it is ok to do + * this from within the critical section - the kernel + * takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + * executed if the task was holding multiple mutexes and + * the mutexes were given back in an order that is + * different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was full and no block time is specified (or + * the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + * the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + * configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + * now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + * event list. It is possible that interrupts occurring now + * remove this task from the event list again - but as the + * scheduler is suspended the task will go onto the pending + * ready list instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + * ready list into the ready list - so it is feasible that this + * task is already in the ready list before it yields - in which + * case the yield will not cause a context switch unless there + * is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, + const void * const pvItemToQueue, + BaseType_t * const pxHigherPriorityTaskWoken, + const BaseType_t xCopyPosition ) +{ + BaseType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + * system call (or maximum API call) interrupt priority. Interrupts that are + * above the maximum system call priority are kept permanently enabled, even + * when the RTOS kernel is in a critical section, but cannot make any calls to + * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has been + * assigned a priority above the configured maximum system call priority. + * Only FreeRTOS functions that end in FromISR can be called from interrupts + * that have been assigned a priority at or (logically) below the maximum + * system call interrupt priority. FreeRTOS maintains a separate interrupt + * safe API to ensure interrupt entry is as fast and as simple as possible. + * More information (albeit Cortex-M specific) is provided on the following + * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except without blocking if there is no room + * in the queue. Also don't directly wake a task that was blocked on a queue + * read, instead return a flag to say whether a context switch is required or + * not (i.e. has a task with a higher priority than us been woken by this + * post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + const int8_t cTxLock = pxQueue->cTxLock; + const UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a + * semaphore or mutex. That means prvCopyDataToQueue() cannot result + * in a task disinheriting a priority and prvCopyDataToQueue() can be + * called here even though the disinherit function does not check if + * the scheduler is suspended before accessing the ready lists. */ + ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* The event list is not altered if the queue is locked. This will + * be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) + { + /* Do not notify the queue set as an existing item + * was overwritten in the queue so the number of items + * in the queue has not changed. */ + mtCOVERAGE_TEST_MARKER(); + } + else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + * to the queue set caused a higher priority task to + * unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + * record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + * context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Not used in this path. */ + ( void ) uxPreviousMessagesWaiting; + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + * knows that data was posted while it was locked. */ + prvIncrementQueueTxLock( pxQueue, cTxLock ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ + BaseType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + Queue_t * const pxQueue = xQueue; + + /* Similar to xQueueGenericSendFromISR() but used with semaphores where the + * item size is 0. Don't directly wake a task that was blocked on a queue + * read, instead return a flag to say whether a context switch is required or + * not (i.e. has a task with a higher priority than us been woken by this + * post). */ + + configASSERT( pxQueue ); + + /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() + * if the item size is not 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Normally a mutex would not be given from an interrupt, especially if + * there is a mutex holder, as priority inheritance makes no sense for an + * interrupts, only tasks. */ + configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + * system call (or maximum API call) interrupt priority. Interrupts that are + * above the maximum system call priority are kept permanently enabled, even + * when the RTOS kernel is in a critical section, but cannot make any calls to + * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has been + * assigned a priority above the configured maximum system call priority. + * Only FreeRTOS functions that end in FromISR can be called from interrupts + * that have been assigned a priority at or (logically) below the maximum + * system call interrupt priority. FreeRTOS maintains a separate interrupt + * safe API to ensure interrupt entry is as fast and as simple as possible. + * More information (albeit Cortex-M specific) is provided on the following + * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* When the queue is used to implement a semaphore no data is ever + * moved through the queue but it is still valid to see if the queue 'has + * space'. */ + if( uxMessagesWaiting < pxQueue->uxLength ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* A task can only have an inherited priority if it is a mutex + * holder - and if there is a mutex holder then the mutex cannot be + * given from an ISR. As this is the ISR version of the function it + * can be assumed there is no mutex holder and no need to determine if + * priority disinheritance is needed. Simply increase the count of + * messages (semaphores) available. */ + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + /* The event list is not altered if the queue is locked. This will + * be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) + { + /* The semaphore is a member of a queue set, and + * posting to the queue set caused a higher priority + * task to unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + * record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + * context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + * knows that data was posted while it was locked. */ + prvIncrementQueueTxLock( pxQueue, cTxLock ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) +{ + BaseType_t xEntryTimeSet = pdFALSE; + TimeOut_t xTimeOut; + Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + * is zero (so no data is copied into the buffer). */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + /*lint -save -e904 This function relaxes the coding standard somewhat to + * allow return statements within the function itself. This is done in the + * interest of execution time efficiency. */ + for( ; ; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + * must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data available, remove one item. */ + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_RECEIVE( pxQueue ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* There is now space in the queue, were any tasks waiting to + * post to the queue? If so, unblock the highest priority waiting + * task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + * the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + * configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + * now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* The timeout has not expired. If the queue is still empty place + * the task on the list of tasks waiting to receive from the queue. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The queue contains data again. Loop back to try and read the + * data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. If there is no data in the queue exit, otherwise loop + * back and attempt to read the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, + TickType_t xTicksToWait ) +{ + BaseType_t xEntryTimeSet = pdFALSE; + TimeOut_t xTimeOut; + Queue_t * const pxQueue = xQueue; + + #if ( configUSE_MUTEXES == 1 ) + BaseType_t xInheritanceOccurred = pdFALSE; + #endif + + /* Check the queue pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* Check this really is a semaphore, in which case the item size will be + * 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + /*lint -save -e904 This function relaxes the coding standard somewhat to allow return + * statements within the function itself. This is done in the interest + * of execution time efficiency. */ + for( ; ; ) + { + taskENTER_CRITICAL(); + { + /* Semaphores are queues with an item size of 0, and where the + * number of messages in the queue is the semaphore's count value. */ + const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + * must be the highest priority task wanting to access the queue. */ + if( uxSemaphoreCount > ( UBaseType_t ) 0 ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Semaphores are queues with a data size of zero and where the + * messages waiting is the semaphore's count. Reduce the count. */ + pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1; + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + * priority inheritance should it become necessary. */ + pxQueue->u.xSemaphore.xMutexHolder = pvTaskIncrementMutexHeldCount(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + + /* Check to see if other tasks are blocked waiting to give the + * semaphore, and if so, unblock the highest priority such task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The semaphore count was 0 and no block time is specified + * (or the block time has expired) so exit now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The semaphore count was 0 and a block time was specified + * so configure the timeout structure ready to block. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can give to and take from the semaphore + * now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* A block time is specified and not expired. If the semaphore + * count is 0 then enter the Blocked state to wait for a semaphore to + * become available. As semaphores are implemented with queues the + * queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* if ( configUSE_MUTEXES == 1 ) */ + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There was no timeout and the semaphore count was not 0, so + * attempt to take the semaphore again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* If the semaphore count is 0 exit now as the timeout has + * expired. Otherwise return to attempt to take the semaphore that is + * known to be available. As semaphores are implemented by queues the + * queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + #if ( configUSE_MUTEXES == 1 ) + { + /* xInheritanceOccurred could only have be set if + * pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to + * test the mutex type again to check it is actually a mutex. */ + if( xInheritanceOccurred != pdFALSE ) + { + taskENTER_CRITICAL(); + { + UBaseType_t uxHighestWaitingPriority; + + /* This task blocking on the mutex caused another + * task to inherit this task's priority. Now this task + * has timed out the priority should be disinherited + * again, but only as low as the next highest priority + * task that is waiting for the same mutex. */ + uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue ); + vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority ); + } + taskEXIT_CRITICAL(); + } + } + #endif /* configUSE_MUTEXES */ + + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) +{ + BaseType_t xEntryTimeSet = pdFALSE; + TimeOut_t xTimeOut; + int8_t * pcOriginalReadPosition; + Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + * is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + /*lint -save -e904 This function relaxes the coding standard somewhat to + * allow return statements within the function itself. This is done in the + * interest of execution time efficiency. */ + for( ; ; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + * must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember the read position so it can be reset after the data + * is read from the queue as this function is only peeking the + * data, not removing it. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read pointer. */ + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + * any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + * the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + * configure the timeout structure ready to enter the blocked + * state. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + * now that the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* Timeout has not expired yet, check to see if there is data in the + * queue now, and if not enter the Blocked state to wait for data. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_PEEK( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There is data in the queue now, so don't enter the blocked + * state, instead return to try and obtain the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. If there is still no data in the queue + * exit, otherwise go back and try to read the data again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, + void * const pvBuffer, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ + BaseType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + * system call (or maximum API call) interrupt priority. Interrupts that are + * above the maximum system call priority are kept permanently enabled, even + * when the RTOS kernel is in a critical section, but cannot make any calls to + * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has been + * assigned a priority above the configured maximum system call priority. + * Only FreeRTOS functions that end in FromISR can be called from interrupts + * that have been assigned a priority at or (logically) below the maximum + * system call interrupt priority. FreeRTOS maintains a separate interrupt + * safe API to ensure interrupt entry is as fast and as simple as possible. + * More information (albeit Cortex-M specific) is provided on the following + * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Cannot block in an ISR, so check there is data available. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + const int8_t cRxLock = pxQueue->cRxLock; + + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* If the queue is locked the event list will not be modified. + * Instead update the lock count so the task that unlocks the queue + * will know that an ISR has removed data while the queue was + * locked. */ + if( cRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + * force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + * knows that data was removed while it was locked. */ + prvIncrementQueueRxLock( pxQueue, cRxLock ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, + void * const pvBuffer ) +{ + BaseType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + int8_t * pcOriginalReadPosition; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ + + /* RTOS ports that support interrupt nesting have the concept of a maximum + * system call (or maximum API call) interrupt priority. Interrupts that are + * above the maximum system call priority are kept permanently enabled, even + * when the RTOS kernel is in a critical section, but cannot make any calls to + * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has been + * assigned a priority above the configured maximum system call priority. + * Only FreeRTOS functions that end in FromISR can be called from interrupts + * that have been assigned a priority at or (logically) below the maximum + * system call interrupt priority. FreeRTOS maintains a separate interrupt + * safe API to ensure interrupt entry is as fast and as simple as possible. + * More information (albeit Cortex-M specific) is provided on the following + * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + * actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ + UBaseType_t uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ + UBaseType_t uxReturn; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) +{ + UBaseType_t uxReturn; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void vQueueDelete( QueueHandle_t xQueue ) +{ + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + traceQUEUE_DELETE( pxQueue ); + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The queue can only have been allocated dynamically - free it + * again. */ + vPortFree( pxQueue ); + } + #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The queue could have been allocated statically or dynamically, so + * check before attempting to free the memory. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxQueue ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #else /* if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) */ + { + /* The queue must have been statically allocated, so is not going to be + * deleted. Avoid compiler warnings about the unused parameter. */ + ( void ) pxQueue; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vQueueSetQueueNumber( QueueHandle_t xQueue, + UBaseType_t uxQueueNumber ) + { + ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueGetQueueItemSize( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ +{ + return ( ( Queue_t * ) xQueue )->uxItemSize; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueGetQueueLength( QueueHandle_t xQueue ) /* PRIVILEGED_FUNCTION */ +{ + return ( ( Queue_t * ) xQueue )->uxLength; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) + { + UBaseType_t uxHighestPriorityOfWaitingTasks; + + /* If a task waiting for a mutex causes the mutex holder to inherit a + * priority, but the waiting task times out, then the holder should + * disinherit the priority - but only down to the highest priority of any + * other tasks that are waiting for the same mutex. For this purpose, + * return the priority of the highest priority task that is waiting for the + * mutex. */ + if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0U ) + { + uxHighestPriorityOfWaitingTasks = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) ); + } + else + { + uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY; + } + + return uxHighestPriorityOfWaitingTasks; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, + const void * pvItemToQueue, + const BaseType_t xPosition ) +{ + BaseType_t xReturn = pdFALSE; + UBaseType_t uxMessagesWaiting; + + /* This function is called from a critical section. */ + + uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + xReturn = xTaskPriorityDisinherit( pxQueue->u.xSemaphore.xMutexHolder ); + pxQueue->u.xSemaphore.xMutexHolder = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + + if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */ + pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize; + + if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.xQueue.pcReadFrom = ( pxQueue->u.xQueue.pcTail - pxQueue->uxItemSize ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xPosition == queueOVERWRITE ) + { + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* An item is not being added but overwritten, so subtract + * one from the recorded number of items in the queue so when + * one is added again below the number of recorded items remains + * correct. */ + --uxMessagesWaiting; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( Queue_t * const pxQueue, + void * const pvBuffer ) +{ + if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) + { + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( Queue_t * const pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + * removed from the queue while the queue was locked. When a queue is + * locked items can be added or removed, but the event lists cannot be + * updated. */ + taskENTER_CRITICAL(); + { + int8_t cTxLock = pxQueue->cTxLock; + + /* See if data was added to the queue while it was locked. */ + while( cTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + * blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting to + * the queue set caused a higher priority task to unblock. + * A context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Tasks that are removed from the event list will get + * added to the pending ready list as the scheduler is still + * suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + * context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + * the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that + * a context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --cTxLock; + } + + pxQueue->cTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + int8_t cRxLock = pxQueue->cRxLock; + + while( cRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --cRxLock; + } + else + { + break; + } + } + + pxQueue->cRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueEmpty( const Queue_t * pxQueue ) +{ + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) +{ + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueFull( const Queue_t * pxQueue ) +{ + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) +{ + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, + const void * pvItemToQueue, + TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already full we may have to block. A critical section + * is required to prevent an interrupt removing something from the queue + * between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + * posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + * return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + * into the ready list as we are within a critical section. + * Instead the same pending ready list mechanism is used as if + * the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + * that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, + void * pvBuffer, + TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already empty we may have to block. A critical section + * is required to prevent an interrupt adding something to the queue + * between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + * leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + * indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + * into the ready list as we are within a critical section. + * Instead the same pending ready list mechanism is used as if + * the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, + const void * pvItemToQueue, + BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + * exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + * co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, + void * pvBuffer, + BaseType_t * pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* We cannot block from an ISR, so check there is data available. If + * not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueAddToRegistry( QueueHandle_t xQueue, + const char * pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + QueueRegistryItem_t * pxEntryToWrite = NULL; + + configASSERT( xQueue ); + + if( pcQueueName != NULL ) + { + /* See if there is an empty space in the registry. A NULL name denotes + * a free slot. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + /* Replace an existing entry if the queue is already in the registry. */ + if( xQueue == xQueueRegistry[ ux ].xHandle ) + { + pxEntryToWrite = &( xQueueRegistry[ ux ] ); + break; + } + /* Otherwise, store in the next empty location */ + else if( ( pxEntryToWrite == NULL ) && ( xQueueRegistry[ ux ].pcQueueName == NULL ) ) + { + pxEntryToWrite = &( xQueueRegistry[ ux ] ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + + if( pxEntryToWrite != NULL ) + { + /* Store the information on this queue. */ + pxEntryToWrite->pcQueueName = pcQueueName; + pxEntryToWrite->xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + const char * pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + const char * pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + configASSERT( xQueue ); + + /* Note there is nothing here to protect against another task adding or + * removing entries from the registry while it is being searched. */ + + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + pcReturn = xQueueRegistry[ ux ].pcQueueName; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return pcReturn; + } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + UBaseType_t ux; + + configASSERT( xQueue ); + + /* See if the handle of the queue being unregistered in actually in the + * registry. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + + /* Set the handle to NULL to ensure the same queue handle cannot + * appear in the registry twice if it is added, removed, then + * added again. */ + xQueueRegistry[ ux ].xHandle = ( QueueHandle_t ) 0; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, + TickType_t xTicksToWait, + const BaseType_t xWaitIndefinitely ) + { + Queue_t * const pxQueue = xQueue; + + /* This function should not be called by application code hence the + * 'Restricted' in its name. It is not part of the public API. It is + * designed for use by kernel code, and has special calling requirements. + * It can result in vListInsert() being called on a list that can only + * possibly ever have one item in it, so the list will be fast, but even + * so it should be called with the scheduler locked and not from a critical + * section. */ + + /* Only do anything if there are no messages in the queue. This function + * will not actually cause the task to block, just place it on a blocked + * list. It will not block until the scheduler is unlocked - at which + * time a yield will be performed. If an item is added to the queue while + * the queue is locked, and the calling task blocks on the queue, then the + * calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + * items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + * not empty because the queue set will still hold pending events for + * the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + TickType_t const xTicksToWait ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) + { + Queue_t * pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; + + /* This function must be called form a critical section. */ + + /* The following line is not reachable in unit tests because every call + * to prvNotifyQueueSetContainer is preceded by a check that + * pxQueueSetContainer != NULL */ + configASSERT( pxQueueSetContainer ); /* LCOV_EXCL_BR_LINE */ + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + const int8_t cTxLock = pxQueueSetContainer->cTxLock; + + traceQUEUE_SET_SEND( pxQueueSetContainer ); + + /* The data copied is the handle of the queue that contains data. */ + xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, queueSEND_TO_BACK ); + + if( cTxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + prvIncrementQueueTxLock( pxQueueSetContainer, cTxLock ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c b/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c new file mode 100644 index 0000000..53208ac --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c @@ -0,0 +1,1455 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "stream_buffer.h" + +#if ( configUSE_TASK_NOTIFICATIONS != 1 ) + #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c +#endif + +#if ( INCLUDE_xTaskGetCurrentTaskHandle != 1 ) + #error INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 to build stream_buffer.c +#endif + +/* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified + * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined + * for the header files above, but not in this file, in order to generate the + * correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* If the user has not provided application specific Rx notification macros, + * or #defined the notification macros away, then provide default implementations + * that uses task notifications. */ +/*lint -save -e9026 Function like macros allowed and needed here so they can be overridden. */ +#ifndef sbRECEIVE_COMPLETED + #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll() +#endif /* sbRECEIVE_COMPLETED */ + +/* If user has provided a per-instance receive complete callback, then + * invoke the callback else use the receive complete macro which is provided by default for all instances. + */ +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvRECEIVE_COMPLETED( pxStreamBuffer ) \ + do { \ + if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ + { \ + ( pxStreamBuffer )->pxReceiveCompletedCallback( ( pxStreamBuffer ), pdFALSE, NULL ); \ + } \ + else \ + { \ + sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ); \ + } \ + } while( 0 ) +#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvRECEIVE_COMPLETED( pxStreamBuffer ) sbRECEIVE_COMPLETED( ( pxStreamBuffer ) ) +#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + +#ifndef sbRECEIVE_COMPLETED_FROM_ISR + #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ + do { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction, \ + ( pxHigherPriorityTaskWoken ) ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } while( 0 ) +#endif /* sbRECEIVE_COMPLETED_FROM_ISR */ + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ + do { \ + if( ( pxStreamBuffer )->pxReceiveCompletedCallback != NULL ) \ + { \ + ( pxStreamBuffer )->pxReceiveCompletedCallback( ( pxStreamBuffer ), pdTRUE, ( pxHigherPriorityTaskWoken ) ); \ + } \ + else \ + { \ + sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ + } \ + } while( 0 ) +#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + sbRECEIVE_COMPLETED_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) +#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + +/* If the user has not provided an application specific Tx notification macro, + * or #defined the notification macro away, then provide a default + * implementation that uses task notifications. + */ +#ifndef sbSEND_COMPLETED + #define sbSEND_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll() +#endif /* sbSEND_COMPLETED */ + +/* If user has provided a per-instance send completed callback, then + * invoke the callback else use the send complete macro which is provided by default for all instances. + */ +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvSEND_COMPLETED( pxStreamBuffer ) \ + do { \ + if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ + { \ + pxStreamBuffer->pxSendCompletedCallback( ( pxStreamBuffer ), pdFALSE, NULL ); \ + } \ + else \ + { \ + sbSEND_COMPLETED( ( pxStreamBuffer ) ); \ + } \ + } while( 0 ) +#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvSEND_COMPLETED( pxStreamBuffer ) sbSEND_COMPLETED( ( pxStreamBuffer ) ) +#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + + +#ifndef sbSEND_COMPLETE_FROM_ISR + #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + do { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction, \ + ( pxHigherPriorityTaskWoken ) ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } while( 0 ) +#endif /* sbSEND_COMPLETE_FROM_ISR */ + + +#if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + do { \ + if( ( pxStreamBuffer )->pxSendCompletedCallback != NULL ) \ + { \ + ( pxStreamBuffer )->pxSendCompletedCallback( ( pxStreamBuffer ), pdTRUE, ( pxHigherPriorityTaskWoken ) ); \ + } \ + else \ + { \ + sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ); \ + } \ + } while( 0 ) +#else /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + #define prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + sbSEND_COMPLETE_FROM_ISR( ( pxStreamBuffer ), ( pxHigherPriorityTaskWoken ) ) +#endif /* if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) */ + +/*lint -restore (9026) */ + +/* The number of bytes used to hold the length of a message in the buffer. */ +#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + +/* Bits stored in the ucFlags field of the stream buffer. */ +#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ +#define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ + +/*-----------------------------------------------------------*/ + +/* Structure that hold state information on the buffer. */ +typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */ +{ + volatile size_t xTail; /* Index to the next item to read within the buffer. */ + volatile size_t xHead; /* Index to the next item to write within the buffer. */ + size_t xLength; /* The length of the buffer pointed to by pucBuffer. */ + size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */ + volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */ + volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */ + uint8_t * pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */ + uint8_t ucFlags; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ + #endif + + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + StreamBufferCallbackFunction_t pxSendCompletedCallback; /* Optional callback called on send complete. sbSEND_COMPLETED is called if this is NULL. */ + StreamBufferCallbackFunction_t pxReceiveCompletedCallback; /* Optional callback called on receive complete. sbRECEIVE_COMPLETED is called if this is NULL. */ + #endif +} StreamBuffer_t; + +/* + * The number of bytes available to be read from the buffer. + */ +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION; + +/* + * Add xCount bytes from pucData into the pxStreamBuffer's data storage area. + * This function does not update the buffer's xHead pointer, so multiple writes + * may be chained together "atomically". This is useful for Message Buffers where + * the length and data bytes are written in two separate chunks, and we don't want + * the reader to see the buffer as having grown until after all data is copied over. + * This function takes a custom xHead value to indicate where to write to (necessary + * for chaining) and returns the the resulting xHead position. + * To mark the write as complete, manually set the buffer's xHead field with the + * returned xHead from this function. + */ +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, + const uint8_t * pucData, + size_t xCount, + size_t xHead ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then reads an entire + * message out of the buffer. If the stream buffer is being used as a stream + * buffer then read as many bytes as possible from the buffer. + * prvReadBytesFromBuffer() is called to actually extract the bytes from the + * buffer's data storage area. + */ +static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then writes an entire + * message to the buffer. If the stream buffer is being used as a stream + * buffer then write as many bytes as possible to the buffer. + * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's + * data storage area. + */ +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) PRIVILEGED_FUNCTION; + +/* + * Copies xCount bytes from the pxStreamBuffer's data storage area to pucData. + * This function does not update the buffer's xTail pointer, so multiple reads + * may be chained together "atomically". This is useful for Message Buffers where + * the length and data bytes are read in two separate chunks, and we don't want + * the writer to see the buffer as having more free space until after all data is + * copied over, especially if we have to abort the read due to insufficient receiving space. + * This function takes a custom xTail value to indicate where to read from (necessary + * for chaining) and returns the the resulting xTail position. + * To mark the read as complete, manually set the buffer's xTail field with the + * returned xTail from this function. + */ +static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer, + uint8_t * pucData, + size_t xCount, + size_t xTail ) PRIVILEGED_FUNCTION; + +/* + * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to + * initialise the members of the newly created stream buffer structure. + */ +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) + { + void * pvAllocatedMemory; + uint8_t ucFlags; + + /* In case the stream buffer is going to be used as a message buffer + * (that is, it will hold discrete messages with a little meta data that + * says how big the next message is) check the buffer will be large enough + * to hold at least one message. */ + if( xIsMessageBuffer == pdTRUE ) + { + /* Is a message buffer but not statically allocated. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* Not a message buffer and not statically allocated. */ + ucFlags = 0; + configASSERT( xBufferSizeBytes > 0 ); + } + + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + * the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + /* A stream buffer requires a StreamBuffer_t structure and a buffer. + * Both are allocated in a single call to pvPortMalloc(). The + * StreamBuffer_t structure is placed at the start of the allocated memory + * and the buffer follows immediately after. The requested size is + * incremented so the free space is returned as the user would expect - + * this is a quirk of the implementation that means otherwise the free + * space would be reported as one byte smaller than would be logically + * expected. */ + if( xBufferSizeBytes < ( xBufferSizeBytes + 1 + sizeof( StreamBuffer_t ) ) ) + { + xBufferSizeBytes++; + pvAllocatedMemory = pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); + } + else + { + pvAllocatedMemory = NULL; + } + + if( pvAllocatedMemory != NULL ) + { + prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pvAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */ + ( ( uint8_t * ) pvAllocatedMemory ) + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */ + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags, + pxSendCompletedCallback, + pxReceiveCompletedCallback ); + + traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pvAllocatedMemory ), xIsMessageBuffer ); + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + } + + return ( StreamBufferHandle_t ) pvAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */ + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) + { + StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */ + StreamBufferHandle_t xReturn; + uint8_t ucFlags; + + configASSERT( pucStreamBufferStorageArea ); + configASSERT( pxStaticStreamBuffer ); + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + * the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + if( xIsMessageBuffer != pdFALSE ) + { + /* Statically allocated message buffer. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; + } + else + { + /* Statically allocated stream buffer. */ + ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED; + } + + /* In case the stream buffer is going to be used as a message buffer + * (that is, it will hold discrete messages with a little meta data that + * says how big the next message is) check the buffer will be large enough + * to hold at least one message. */ + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + + #if ( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + * variable of type StaticStreamBuffer_t equals the size of the real + * message buffer structure. */ + volatile size_t xSize = sizeof( StaticStreamBuffer_t ); + configASSERT( xSize == sizeof( StreamBuffer_t ) ); + } /*lint !e529 xSize is referenced is configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pucStreamBufferStorageArea, + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags, + pxSendCompletedCallback, + pxReceiveCompletedCallback ); + + /* Remember this was statically allocated in case it is ever deleted + * again. */ + pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED; + + traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ); + + xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */ + } + else + { + xReturn = NULL; + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + } + + return xReturn; + } +#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer, + uint8_t ** ppucStreamBufferStorageArea, + StaticStreamBuffer_t ** ppxStaticStreamBuffer ) + { + BaseType_t xReturn; + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + configASSERT( ppucStreamBufferStorageArea ); + configASSERT( ppxStaticStreamBuffer ); + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) != ( uint8_t ) 0 ) + { + *ppucStreamBufferStorageArea = pxStreamBuffer->pucBuffer; + *ppxStaticStreamBuffer = ( StaticStreamBuffer_t * ) pxStreamBuffer; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) +{ + StreamBuffer_t * pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + traceSTREAM_BUFFER_DELETE( xStreamBuffer ); + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE ) + { + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both the structure and the buffer were allocated using a single call + * to pvPortMalloc(), hence only one call to vPortFree() is required. */ + vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */ + } + #else + { + /* Should not be possible to get here, ucFlags must be corrupt. + * Force an assert. */ + configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 ); + } + #endif + } + else + { + /* The structure and buffer were not allocated dynamically and cannot be + * freed - just scrub the structure so future use will assert. */ + ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + BaseType_t xReturn = pdFAIL; + StreamBufferCallbackFunction_t pxSendCallback = NULL, pxReceiveCallback = NULL; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; + #endif + + configASSERT( pxStreamBuffer ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Store the stream buffer number so it can be restored after the + * reset. */ + uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber; + } + #endif + + /* Can only reset a message buffer if there are no tasks blocked on it. */ + taskENTER_CRITICAL(); + { + if( ( pxStreamBuffer->xTaskWaitingToReceive == NULL ) && ( pxStreamBuffer->xTaskWaitingToSend == NULL ) ) + { + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + { + pxSendCallback = pxStreamBuffer->pxSendCompletedCallback; + pxReceiveCallback = pxStreamBuffer->pxReceiveCompletedCallback; + } + #endif + + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags, + pxSendCallback, + pxReceiveCallback ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + #endif + + traceSTREAM_BUFFER_RESET( xStreamBuffer ); + + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + BaseType_t xReturn; + + configASSERT( pxStreamBuffer ); + + /* It is not valid for the trigger level to be 0. */ + if( xTriggerLevel == ( size_t ) 0 ) + { + xTriggerLevel = ( size_t ) 1; + } + + /* The trigger level is the number of bytes that must be in the stream + * buffer before a task that is waiting for data is unblocked. */ + if( xTriggerLevel < pxStreamBuffer->xLength ) + { + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel; + xReturn = pdPASS; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ + const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xSpace; + size_t xOriginalTail; + + configASSERT( pxStreamBuffer ); + + /* The code below reads xTail and then xHead. This is safe if the stream + * buffer is updated once between the two reads - but not if the stream buffer + * is updated more than once between the two reads - hence the loop. */ + do + { + xOriginalTail = pxStreamBuffer->xTail; + xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail; + xSpace -= pxStreamBuffer->xHead; + } while( xOriginalTail != pxStreamBuffer->xTail ); + + xSpace -= ( size_t ) 1; + + if( xSpace >= pxStreamBuffer->xLength ) + { + xSpace -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xSpace; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ + const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xReturn; + + configASSERT( pxStreamBuffer ); + + xReturn = prvBytesInBuffer( pxStreamBuffer ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xReturn, xSpace = 0; + size_t xRequiredSpace = xDataLengthBytes; + TimeOut_t xTimeOut; + size_t xMaxReportedSpace = 0; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* The maximum amount of space a stream buffer will ever report is its length + * minus 1. */ + xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1; + + /* This send function is used to write to both message buffers and stream + * buffers. If this is a message buffer then the space needed must be + * increased by the amount of bytes needed to store the length of the + * message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + + /* Overflow? */ + configASSERT( xRequiredSpace > xDataLengthBytes ); + + /* If this is a message buffer then it must be possible to write the + * whole message. */ + if( xRequiredSpace > xMaxReportedSpace ) + { + /* The message would not fit even if the entire buffer was empty, + * so don't wait for space. */ + xTicksToWait = ( TickType_t ) 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If this is a stream buffer then it is acceptable to write only part + * of the message to the buffer. Cap the length to the total length of + * the buffer. */ + if( xRequiredSpace > xMaxReportedSpace ) + { + xRequiredSpace = xMaxReportedSpace; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + vTaskSetTimeOutState( &xTimeOut ); + + do + { + /* Wait until the required number of bytes are free in the message + * buffer. */ + taskENTER_CRITICAL(); + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + + if( xSpace < xRequiredSpace ) + { + /* Clear notification state as going to wait for space. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one writer. */ + configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); + pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle(); + } + else + { + taskEXIT_CRITICAL(); + break; + } + } + taskEXIT_CRITICAL(); + + traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToSend = NULL; + } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xSpace == ( size_t ) 0 ) + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ); + + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + prvSEND_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xReturn, xSpace; + size_t xRequiredSpace = xDataLengthBytes; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + * buffers. If this is a message buffer then the space needed must be + * increased by the amount of bytes needed to store the length of the + * message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + prvSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) +{ + size_t xNextHead = pxStreamBuffer->xHead; + configMESSAGE_BUFFER_LENGTH_TYPE xMessageLength; + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + /* This is a message buffer, as opposed to a stream buffer. */ + + /* Convert xDataLengthBytes to the message length type. */ + xMessageLength = ( configMESSAGE_BUFFER_LENGTH_TYPE ) xDataLengthBytes; + + /* Ensure the data length given fits within configMESSAGE_BUFFER_LENGTH_TYPE. */ + configASSERT( ( size_t ) xMessageLength == xDataLengthBytes ); + + if( xSpace >= xRequiredSpace ) + { + /* There is enough space to write both the message length and the message + * itself into the buffer. Start by writing the length of the data, the data + * itself will be written later in this function. */ + xNextHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xMessageLength ), sbBYTES_TO_STORE_MESSAGE_LENGTH, xNextHead ); + } + else + { + /* Not enough space, so do not write data to the buffer. */ + xDataLengthBytes = 0; + } + } + else + { + /* This is a stream buffer, as opposed to a message buffer, so writing a + * stream of bytes rather than discrete messages. Plan to write as many + * bytes as possible. */ + xDataLengthBytes = configMIN( xDataLengthBytes, xSpace ); + } + + if( xDataLengthBytes != ( size_t ) 0 ) + { + /* Write the data to the buffer. */ + pxStreamBuffer->xHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes, xNextHead ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alignment and access. */ + } + + return xDataLengthBytes; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + * discrete messages, and stream buffers, which store a continuous stream of + * bytes. Discrete messages include an additional + * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + * message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + /* Checking if there is data and clearing the notification state must be + * performed atomically. */ + taskENTER_CRITICAL(); + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* If this function was invoked by a message buffer read then + * xBytesToStoreMessageLength holds the number of bytes used to hold + * the length of the next discrete message. If this function was + * invoked by a stream buffer read then xBytesToStoreMessageLength will + * be 0. */ + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Clear notification state as going to wait for data. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one reader. */ + configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); + pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Wait for data to be available. */ + traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToReceive = NULL; + + /* Recheck the data available after blocking. */ + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + * holds the number of bytes used to store the message length) or a stream of + * bytes (where xBytesToStoreMessageLength is zero), the number of bytes + * available must be greater than xBytesToStoreMessageLength to be able to + * read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ); + prvRECEIVE_COMPLETED( xStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ); + mtCOVERAGE_TEST_MARKER(); + } + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xReturn, xBytesAvailable; + configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn; + + configASSERT( pxStreamBuffer ); + + /* Ensure the stream buffer is being used as a message buffer. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH ) + { + /* The number of bytes available is greater than the number of bytes + * required to hold the length of the next message, so another message + * is available. */ + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, pxStreamBuffer->xTail ); + xReturn = ( size_t ) xTempReturn; + } + else + { + /* The minimum amount of bytes in a message buffer is + * ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is + * less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid + * value is 0. */ + configASSERT( xBytesAvailable == 0 ); + xReturn = 0; + } + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + * discrete messages, and stream buffers, which store a continuous stream of + * bytes. Discrete messages include an additional + * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + * message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + * holds the number of bytes used to store the message length) or a stream of + * bytes (where xBytesToStoreMessageLength is zero), the number of bytes + * available must be greater than xBytesToStoreMessageLength to be able to + * read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + prvRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ); + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable ) +{ + size_t xCount, xNextMessageLength; + configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength; + size_t xNextTail = pxStreamBuffer->xTail; + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + /* A discrete message is being received. First receive the length + * of the message. */ + xNextTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, sbBYTES_TO_STORE_MESSAGE_LENGTH, xNextTail ); + xNextMessageLength = ( size_t ) xTempNextMessageLength; + + /* Reduce the number of bytes available by the number of bytes just + * read out. */ + xBytesAvailable -= sbBYTES_TO_STORE_MESSAGE_LENGTH; + + /* Check there is enough space in the buffer provided by the + * user. */ + if( xNextMessageLength > xBufferLengthBytes ) + { + /* The user has provided insufficient space to read the message. */ + xNextMessageLength = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* A stream of bytes is being received (as opposed to a discrete + * message), so read as many bytes as possible. */ + xNextMessageLength = xBufferLengthBytes; + } + + /* Use the minimum of the wanted bytes and the available bytes. */ + xCount = configMIN( xNextMessageLength, xBytesAvailable ); + + if( xCount != ( size_t ) 0 ) + { + /* Read the actual data and update the tail to mark the data as officially consumed. */ + pxStreamBuffer->xTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xCount, xNextTail ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */ + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) +{ + const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + BaseType_t xReturn; + size_t xTail; + + configASSERT( pxStreamBuffer ); + + /* True if no bytes are available. */ + xTail = pxStreamBuffer->xTail; + + if( pxStreamBuffer->xHead == xTail ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) +{ + BaseType_t xReturn; + size_t xBytesToStoreMessageLength; + const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + /* This generic version of the receive function is used by both message + * buffers, which store discrete messages, and stream buffers, which store a + * continuous stream of bytes. Discrete messages include an additional + * sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + /* True if the available space equals zero. */ + if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + BaseType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, + BaseType_t * pxHigherPriorityTaskWoken ) +{ + StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + BaseType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, + const uint8_t * pucData, + size_t xCount, + size_t xHead ) +{ + size_t xFirstLength; + + configASSERT( xCount > ( size_t ) 0 ); + + /* Calculate the number of bytes that can be added in the first write - + * which may be less than the total number of bytes that need to be added if + * the buffer will wrap back to the beginning. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xHead, xCount ); + + /* Write as many bytes as can be written in the first write. */ + configASSERT( ( xHead + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) ( &( pxStreamBuffer->pucBuffer[ xHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the number of bytes written was less than the number that could be + * written in the first write... */ + if( xCount > xFirstLength ) + { + /* ...then write the remaining bytes to the start of the buffer. */ + configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xHead += xCount; + + if( xHead >= pxStreamBuffer->xLength ) + { + xHead -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xHead; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadBytesFromBuffer( StreamBuffer_t * pxStreamBuffer, + uint8_t * pucData, + size_t xCount, + size_t xTail ) +{ + size_t xFirstLength; + + configASSERT( xCount != ( size_t ) 0 ); + + /* Calculate the number of bytes that can be read - which may be + * less than the number wanted if the data wraps around to the start of + * the buffer. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xTail, xCount ); + + /* Obtain the number of bytes it is possible to obtain in the first + * read. Asserts check bounds of read and write. */ + configASSERT( xFirstLength <= xCount ); + configASSERT( ( xTail + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the total number of wanted bytes is greater than the number + * that could be read in the first read... */ + if( xCount > xFirstLength ) + { + /* ...then read the remaining bytes from the start of the buffer. */ + ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Move the tail pointer to effectively remove the data read from the buffer. */ + xTail += xCount; + + if( xTail >= pxStreamBuffer->xLength ) + { + xTail -= pxStreamBuffer->xLength; + } + + return xTail; +} +/*-----------------------------------------------------------*/ + +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) +{ +/* Returns the distance between xTail and xHead. */ + size_t xCount; + + xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead; + xCount -= pxStreamBuffer->xTail; + + if( xCount >= pxStreamBuffer->xLength ) + { + xCount -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags, + StreamBufferCallbackFunction_t pxSendCompletedCallback, + StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) +{ + /* Assert here is deliberately writing to the entire buffer to ensure it can + * be written to without generating exceptions, and is setting the buffer to a + * known value to assist in development/debugging. */ + #if ( configASSERT_DEFINED == 1 ) + { + /* The value written just has to be identifiable when looking at the + * memory. Don't use 0xA5 as that is the stack fill value and could + * result in confusion as to what is actually being observed. */ + #define STREAM_BUFFER_BUFFER_WRITE_VALUE ( 0x55 ) + configASSERT( memset( pucBuffer, ( int ) STREAM_BUFFER_BUFFER_WRITE_VALUE, xBufferSizeBytes ) == pucBuffer ); + } + #endif + + ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ + pxStreamBuffer->pucBuffer = pucBuffer; + pxStreamBuffer->xLength = xBufferSizeBytes; + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; + pxStreamBuffer->ucFlags = ucFlags; + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + { + pxStreamBuffer->pxSendCompletedCallback = pxSendCompletedCallback; + pxStreamBuffer->pxReceiveCompletedCallback = pxReceiveCompletedCallback; + } + #else + { + ( void ) pxSendCompletedCallback; + ( void ) pxReceiveCompletedCallback; + } + #endif +} + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) + { + return xStreamBuffer->uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, + UBaseType_t uxStreamBufferNumber ) + { + xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) + { + return( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ); + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/tasks.c b/Middlewares/Third_Party/FreeRTOS/Source/tasks.c new file mode 100644 index 0000000..afb7009 --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/tasks.c @@ -0,0 +1,5534 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "stack_macros.h" + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified + * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined + * for the header files above, but not in this file, in order to generate the + * correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting + * functions but without including stdio.h here. */ +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + +/* At the bottom of this file are two optional functions that can be used + * to generate human readable text from the raw data generated by the + * uxTaskGetSystemState() function. Note the formatting functions are provided + * for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ + +#if ( configUSE_PREEMPTION == 0 ) + +/* If the cooperative scheduler is being used then a yield should not be + * performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() +#else + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* Values that can be assigned to the ucNotifyState member of the TCB. */ +#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) /* Must be zero as it is the initialised value. */ +#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) +#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* Bits used to record how a task's stack and TCB were allocated. */ +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + +/* If any of the following are set then task stacks are filled with a known + * value so the high water mark can be determined. If none of the following are + * set then don't fill the stack so there is no unnecessary dependency on memset. */ +#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1 +#else + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 +#endif + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskRUNNING_CHAR ( 'X' ) +#define tskBLOCKED_CHAR ( 'B' ) +#define tskREADY_CHAR ( 'R' ) +#define tskDELETED_CHAR ( 'D' ) +#define tskSUSPENDED_CHAR ( 'S' ) + +/* + * Some kernel aware debuggers require the data the debugger needs access to to + * be global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/* The name allocated to the Idle task. This can be overridden by defining + * configIDLE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configIDLE_TASK_NAME + #define configIDLE_TASK_NAME "IDLE" +#endif + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + +/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + * performed in a generic way that is not optimised to any particular + * microcontroller architecture. */ + +/* uxTopReadyPriority holds the priority of the highest priority ready + * state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + do { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } while( 0 ) /* taskRECORD_READY_PRIORITY */ + +/*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + do { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + * the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ + +/*-----------------------------------------------------------*/ + +/* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + * they are only required when a port optimised method of task selection is + * being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + * performed in a way that is tailored to the particular microcontroller + * architecture being used. */ + +/* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( ( uxPriority ), uxTopReadyPriority ) + +/*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + do { \ + UBaseType_t uxTopPriority; \ + \ + /* Find the highest priority list that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } while( 0 ) + +/*-----------------------------------------------------------*/ + +/* A port optimised version is provided, call it only if the TCB being reset + * is being referenced from a ready list. If it is referenced from a delayed + * or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + do { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } while( 0 ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick + * count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ + do { \ + List_t * pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + prvResetNextTaskUnblockTime(); \ + } while( 0 ) + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + do { \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + listINSERT_END( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ + tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ); \ + } while( 0 ) +/*-----------------------------------------------------------*/ + +/* + * Several functions take a TaskHandle_t parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) ) + +/* The item value of the event list item is normally used to hold the priority + * of the task to which it belongs (coded to allow it to be held in reverse + * priority order). However, it is occasionally borrowed for other purposes. It + * is important its value is not updated due to a task priority change while it is + * being used for another purpose. The following bit definition is used to inform + * the scheduler that the value should not be changed - in which case it is the + * responsibility of whichever module is using the value to ensure it gets set back + * to its original value when it is released. */ +#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000000000000000ULL +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + volatile StackType_t * pxTopOfStack; /**< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /**< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /**< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /**< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /**< The priority of the task. 0 is the lowest priority. */ + StackType_t * pxStack; /**< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ]; /**< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t * pxEndOfStack; /**< Points to the highest valid address for the stack. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /**< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /**< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /**< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /**< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /**< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + configTLS_BLOCK_TYPE xTLSBlock; /**< Memory block used as Thread Local Storage (TLS) Block for the task. */ + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + #endif + + /* See the comments in FreeRTOS.h with the definition of + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + + #if ( configUSE_POSIX_ERRNO == 1 ) + int iTaskErrno; + #endif +} tskTCB; + +/* The old tskTCB name is maintained above then typedefed to the new TCB_t name + * below to enable the use of older kernel aware debuggers. */ +typedef tskTCB TCB_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine + * which static variables must be declared volatile. */ +portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. -------------------- + * xDelayedTaskList1 and xDelayedTaskList2 could be moved to function scope but + * doing so breaks some kernel aware debuggers and debuggers that rely on removing + * the static qualifier. */ +PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; /**< Prioritised ready tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList1; /**< Delayed tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList2; /**< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /**< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /**< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t xPendingReadyList; /**< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ + +#if ( INCLUDE_vTaskDelete == 1 ) + + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /**< Tasks that have been deleted - but their memory not yet freed. */ + PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + + PRIVILEGED_DATA static List_t xSuspendedTaskList; /**< Tasks that are currently suspended. */ + +#endif + +/* Global POSIX errno. Its value is changed upon context switching to match + * the errno of the currently running task. */ +#if ( configUSE_POSIX_ERRNO == 1 ) + int FreeRTOS_errno = 0; +#endif + +/* Other file private variables. --------------------------------*/ +PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; +PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U; +PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; +PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /**< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +/* Improve support for OpenOCD. The kernel tracks Ready tasks via priority lists. + * For tracking the state of remote threads, OpenOCD uses uxTopUsedPriority + * to determine the number of priority lists to read back from the remote target. */ +const volatile UBaseType_t uxTopUsedPriority = configMAX_PRIORITIES - 1U; + +/* Context switches are held pending while the scheduler is suspended. Also, + * interrupts must not manipulate the xStateListItem of a TCB, or any of the + * lists the xStateListItem can be referenced from, if the scheduler is suspended. + * If an interrupt needs to unblock a task while the scheduler is suspended then it + * moves the task's event list item into the xPendingReadyList, ready for the + * kernel to move the task from the pending ready list into the real ready list + * when the scheduler is unsuspended. The pending ready list itself can only be + * accessed from a critical section. */ +PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) 0U; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +/* Do not move these variables to function scope as doing so prevents the + * code working with debuggers that need to remove the static qualifier. */ + PRIVILEGED_DATA static configRUN_TIME_COUNTER_TYPE ulTaskSwitchedInTime = 0UL; /**< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime = 0UL; /**< Holds the total amount of execution time as defined by the run time counter clock. */ + +#endif + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +/* File private functions. --------------------------------*/ + +/** + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + */ +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +#endif /* INCLUDE_vTaskSuspend */ + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t * pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, + const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * Fills an TaskStatus_t structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t * pxTaskStatusArray, + List_t * pxList, + eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Searches pxList for a task with name pcNameToQuery - returning a handle to + * the task if it is found, or NULL if the task is not found. + */ +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, + const char pcNameToQuery[] ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Set xNextTaskUnblockTime to the time at which the next Blocked state task + * will exit the Blocked state. + */ +static void prvResetNextTaskUnblockTime( void ) PRIVILEGED_FUNCTION; + +#if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) + +/* + * Helper function used to pad task names with spaces when printing out + * human readable tables of task information. + */ + static char * prvWriteNameToBuffer( char * pcBuffer, + const char * pcTaskName ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Called after a Task_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t * pxNewTCB, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; + +/* + * Called after a new task has been created and initialised to place the task + * under the control of the scheduler. + */ +static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; + +/* + * freertos_tasks_c_additions_init() should only be called if the user definable + * macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro + * called by the function. + */ +#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + + static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION; + +#endif + +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) + { + TCB_t * pxNewTCB; + TaskHandle_t xReturn; + + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + #if ( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + * variable of type StaticTask_t equals the size of the real task + * structure. */ + volatile size_t xSize = sizeof( StaticTask_t ); + configASSERT( xSize == sizeof( TCB_t ) ); + ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */ + } + #endif /* configASSERT_DEFINED */ + + if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) + { + /* The memory used for the task's TCB and stack are passed into this + * function - use them. */ + pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; + + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + * task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + } + else + { + xReturn = NULL; + } + + return xReturn; + } + +#endif /* SUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) + { + TCB_t * pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer != NULL ); + configASSERT( pxTaskDefinition->pxTaskBuffer != NULL ); + + if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) ) + { + /* Allocate space for the TCB. Where the memory comes from depends + * on the implementation of the port malloc function and whether or + * not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + * task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + + return xReturn; + } + +#endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, + TaskHandle_t * pxCreatedTask ) + { + TCB_t * pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer ); + + if( pxTaskDefinition->puxStackBuffer != NULL ) + { + /* Allocate space for the TCB. Where the memory comes from depends + * on the implementation of the port malloc function and whether or + * not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note + * this task had a statically allocated stack in case it is + * later deleted. The TCB was allocated dynamically. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + } + + return xReturn; + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) + { + TCB_t * pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + * does not grow into the TCB. Likewise if the stack grows up then allocate + * the TCB then the stack. */ + #if ( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + * the implementation of the port malloc function and whether or not static + * allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + + /* Allocate space for the stack used by the task being created. + * The base of the stack memory stored in the TCB so the task can + * be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } + } + #else /* portSTACK_GROWTH */ + { + StackType_t * pxStack; + + /* Allocate space for the stack used by the task being created. */ + pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ + + if( pxNewTCB != NULL ) + { + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + * it again. */ + vPortFreeStack( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + } + #endif /* portSTACK_GROWTH */ + + if( pxNewTCB != NULL ) + { + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + * task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t * pxNewTCB, + const MemoryRegion_t * const xRegions ) +{ + StackType_t * pxTopOfStack; + UBaseType_t x; + + #if ( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Avoid dependency on memset() if it is not required. */ + #if ( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) + { + /* Fill the stack with a known value to assist debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + } + #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */ + + /* Calculate the top of stack address. This depends on whether the stack + * grows from high memory to low (as per the 80x86) or vice versa. + * portSTACK_GROWTH is used to make the result positive or negative as required + * by the port. */ + #if ( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 !e9033 !e9078 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. Checked by assert(). */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + #if ( configRECORD_STACK_HIGH_ADDRESS == 1 ) + { + /* Also record the stack's high address, which may assist + * debugging. */ + pxNewTCB->pxEndOfStack = pxTopOfStack; + } + #endif /* configRECORD_STACK_HIGH_ADDRESS */ + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* The other extreme of the stack space is required if stack checking is + * performed. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Store the task name in the TCB. */ + if( pcName != NULL ) + { + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + * configMAX_TASK_NAME_LEN characters just in case the memory after the + * string is not accessible (extremely unlikely). */ + if( pcName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Ensure the name string is terminated in the case that the string length + * was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* This is used as an array index so must ensure it's not too large. */ + configASSERT( uxPriority < configMAX_PRIORITIES ); + + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxNewTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxNewTCB->uxBasePriority = uxPriority; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxNewTCB->xStateListItem ) ); + vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); + + /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get + * back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + } + #else + { + /* Avoid compiler warning about unreferenced parameter. */ + ( void ) xRegions; + } + #endif + + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + { + /* Allocate and initialize memory for the task's TLS Block. */ + configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock, pxTopOfStack ); + } + #endif + + /* Initialize the TCB stack to look as if the task was already running, + * but had been interrupted by the scheduler. The return address is set + * to the start of the task function. Once the stack has been initialised + * the top of stack variable is updated. */ + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + /* If the port has capability to detect stack overflow, + * pass the stack end address to the stack initialization + * function as well. */ + #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if ( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged, &( pxNewTCB->xMPUSettings ) ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged, &( pxNewTCB->xMPUSettings ) ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged, &( pxNewTCB->xMPUSettings ) ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #else /* portUSING_MPU_WRAPPERS */ + { + /* If the port has capability to detect stack overflow, + * pass the stack end address to the stack initialization + * function as well. */ + #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if ( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( pxCreatedTask != NULL ) + { + /* Pass the handle out in an anonymous way. The handle can be used to + * change the created task's priority, delete the created task, etc.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) +{ + /* Ensure interrupts don't access the task lists while the lists are being + * updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + * the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) + { + /* This is the first task to be created so do the preliminary + * initialisation required. We will not recover if this call + * fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + * current task if it is the highest priority task to be created + * so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + * then it should run now. */ + if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( TaskHandle_t xTaskToDelete ) + { + TCB_t * pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the calling task that is + * being deleted. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready/delayed list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Increment the uxTaskNumber also so kernel aware debuggers can + * detect that the task lists need re-generating. This is done before + * portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will + * not return. */ + uxTaskNumber++; + + if( pxTCB == pxCurrentTCB ) + { + /* A task is deleting itself. This cannot complete within the + * task itself, as a context switch to another task is required. + * Place the task in the termination list. The idle task will + * check the termination list and free up any memory allocated by + * the scheduler for the TCB and stack of the deleted task. */ + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + * there is a task that has been deleted and that it should therefore + * check the xTasksWaitingTermination list. */ + ++uxDeletedTasksWaitingCleanUp; + + /* Call the delete hook before portPRE_TASK_DELETE_HOOK() as + * portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */ + traceTASK_DELETE( pxTCB ); + + /* The pre-delete hook is primarily for the Windows simulator, + * in which Windows specific clean up operations are performed, + * after which it is not possible to yield away from this task - + * hence xYieldPending is used to latch that a context switch is + * required. */ + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + } + else + { + --uxCurrentNumberOfTasks; + traceTASK_DELETE( pxTCB ); + + /* Reset the next expected unblock time in case it referred to + * the task that has just been deleted. */ + prvResetNextTaskUnblockTime(); + } + } + taskEXIT_CRITICAL(); + + /* If the task is not deleting itself, call prvDeleteTCB from outside of + * critical section. If a task deletes itself, prvDeleteTCB is called + * from prvCheckTasksWaitingTermination which is called from Idle task. */ + if( pxTCB != pxCurrentTCB ) + { + prvDeleteTCB( pxTCB ); + } + + /* Force a reschedule if it is the currently running task that has just + * been deleted. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + configASSERT( uxSchedulerSuspended == ( UBaseType_t ) 0U ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskDelayUntil == 1 ) + + BaseType_t xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == ( UBaseType_t ) 0U ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + * block. */ + const TickType_t xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + * lasted called. In this case the only time we should ever + * actually delay is if the wake time has also overflowed, + * and the wake time is greater than the tick time. When this + * is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The tick time has not overflowed. In this case we will + * delay if either the wake time has overflowed, and/or the + * tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL( xTimeToWake ); + + /* prvAddCurrentTaskToDelayedList() needs the block time, not + * the time to wake, so subtract the current tick count. */ + prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + * have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xShouldDelay; + } + +#endif /* INCLUDE_xTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( const TickType_t xTicksToDelay ) + { + BaseType_t xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( TickType_t ) 0U ) + { + configASSERT( uxSchedulerSuspended == ( UBaseType_t ) 0U ); + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + * scheduler is suspended will not get placed in the ready + * list or removed from the blocked list until the scheduler + * is resumed. + * + * This task cannot be in an event list as it is the currently + * executing task. */ + prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE ); + } + xAlreadyYielded = xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + * have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) ) + + eTaskState eTaskGetState( TaskHandle_t xTask ) + { + eTaskState eReturn; + List_t const * pxStateList; + List_t const * pxEventList; + List_t const * pxDelayedList; + List_t const * pxOverflowedDelayedList; + const TCB_t * const pxTCB = xTask; + + configASSERT( pxTCB ); + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); + pxEventList = listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ); + pxDelayedList = pxDelayedTaskList; + pxOverflowedDelayedList = pxOverflowDelayedTaskList; + } + taskEXIT_CRITICAL(); + + if( pxEventList == &xPendingReadyList ) + { + /* The task has been placed on the pending ready list, so its + * state is eReady regardless of what list the task's state list + * item is currently placed on. */ + eReturn = eReady; + } + else if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) + { + /* The task being queried is referenced from one of the Blocked + * lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + * list. Is it genuinely suspended or is it blocked + * indefinitely? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) + { + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + BaseType_t x; + + /* The task does not appear on the event list item of + * and of the RTOS objects, but could still be in the + * blocked state if it is waiting on its notification + * rather than waiting on an object. If not, is + * suspended. */ + eReturn = eSuspended; + + for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) + { + if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) + { + eReturn = eBlocked; + break; + } + } + } + #else /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ + { + eReturn = eSuspended; + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ + } + else + { + eReturn = eBlocked; + } + } + #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) + { + /* The task being queried is referenced from the deleted + * tasks list, or it is not referenced from any lists at + * all. */ + eReturn = eDeleted; + } + #endif + + else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */ + { + /* If the task is not in any other state, it must be in the + * Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) + { + TCB_t const * pxTCB; + UBaseType_t uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the task + * that called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) + { + TCB_t const * pxTCB; + UBaseType_t uxReturn; + UBaseType_t uxSavedInterruptState; + + /* RTOS ports that support interrupt nesting have the concept of a + * maximum system call (or maximum API call) interrupt priority. + * Interrupts that are above the maximum system call priority are keep + * permanently enabled, even when the RTOS kernel is in a critical section, + * but cannot make any calls to FreeRTOS API functions. If configASSERT() + * is defined in FreeRTOSConfig.h then + * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has + * been assigned a priority above the configured maximum system call + * priority. Only FreeRTOS functions that end in FromISR can be called + * from interrupts that have been assigned a priority at or (logically) + * below the maximum system call interrupt priority. FreeRTOS maintains a + * separate interrupt safe API to ensure interrupt entry is as fast and as + * simple as possible. More information (albeit Cortex-M specific) is + * provided on the following link: + * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* If null is passed in here then it is the priority of the calling + * task that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( TaskHandle_t xTask, + UBaseType_t uxNewPriority ) + { + TCB_t * pxTCB; + UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; + BaseType_t xYieldRequired = pdFALSE; + + configASSERT( uxNewPriority < configMAX_PRIORITIES ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + * task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + * priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + * running task is being raised. Is the priority being + * raised above that of the running task? */ + if( uxNewPriority > pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The priority of the running task is being raised, + * but the running task must already be the highest + * priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + * there may now be another task of higher priority that + * is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + * require a yield as the running task must be above the + * new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + * before its uxPriority member is changed so the + * taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + * currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else /* if ( configUSE_MUTEXES == 1 ) */ + { + pxTCB->uxPriority = uxNewPriority; + } + #endif /* if ( configUSE_MUTEXES == 1 ) */ + + /* Only reset the event list item value if the value is not + * being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task is in the blocked or suspended list we need do + * nothing more than change its priority variable. However, if + * the task is in a ready list it needs to be removed and placed + * in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before + * adding it to its new ready list. As we are in a critical + * section we can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + * there is no need to check again and the port level + * reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldRequired != pdFALSE ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Remove compiler warning about unused variables when the port + * optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( TaskHandle_t xTaskToSuspend ) + { + TCB_t * pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + * being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the + * suspended list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + BaseType_t x; + + for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ ) + { + if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION ) + { + /* The task was blocked to wait for a notification, but is + * now suspended, so no notification was received. */ + pxTCB->ucNotifyState[ x ] = taskNOT_WAITING_NOTIFICATION; + } + } + } + #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* Reset the next expected unblock time in case it referred to the + * task that is now in the Suspended state. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == ( UBaseType_t ) 0U ); + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + * to by pxCurrentTCB has just been suspended and pxCurrentTCB + * must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) /*lint !e931 Right has no side effect, just volatile. */ + { + /* No other tasks are ready, so set pxCurrentTCB back to + * NULL so when the next task is created pxCurrentTCB will + * be set to point to it no matter what its relative priority + * is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) + { + BaseType_t xReturn = pdFALSE; + const TCB_t * const pxTCB = xTask; + + /* Accesses xPendingReadyList so must be called from a critical + * section. */ + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task being resumed actually in the suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the Suspended + * state, or because is is blocked with no timeout? */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */ + { + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( TaskHandle_t xTaskToResume ) + { + TCB_t * const pxTCB = xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + * currently executing task. */ + if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) ) + { + taskENTER_CRITICAL(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME( pxTCB ); + + /* The ready list can be accessed even if the scheduler is + * suspended because this is inside a critical section. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* A higher priority task may have just been resumed. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, + * but will leave the lists in the correct state for the + * next yield. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) + { + BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxTCB = xTaskToResume; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + * maximum system call (or maximum API call) interrupt priority. + * Interrupts that are above the maximum system call priority are keep + * permanently enabled, even when the RTOS kernel is in a critical section, + * but cannot make any calls to FreeRTOS API functions. If configASSERT() + * is defined in FreeRTOSConfig.h then + * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has + * been assigned a priority above the configured maximum system call + * priority. Only FreeRTOS functions that end in FromISR can be called + * from interrupts that have been assigned a priority at or (logically) + * below the maximum system call interrupt priority. FreeRTOS maintains a + * separate interrupt safe API to ensure interrupt entry is as fast and as + * simple as possible. More information (albeit Cortex-M specific) is + * provided on the following link: + * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + /* Check the ready lists can be accessed. */ + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + /* Ready lists can be accessed so move the task from the + * suspended list to the ready list directly. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + + /* Mark that a yield is pending in case the user is not + * using the return value to initiate a context switch + * from the ISR using portYIELD_FROM_ISR. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed or ready lists cannot be accessed so the task + * is held in the pending ready list until the scheduler is + * unsuspended. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ + BaseType_t xReturn; + + /* Add the idle task at the lowest priority. */ + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t * pxIdleTaskTCBBuffer = NULL; + StackType_t * pxIdleTaskStackBuffer = NULL; + uint32_t ulIdleTaskStackSize; + + /* The Idle task is created using user provided RAM - obtain the + * address of the RAM then create the idle task. */ + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, + configIDLE_TASK_NAME, + ulIdleTaskStackSize, + ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + + if( xIdleTaskHandle != NULL ) + { + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + { + /* The Idle task is being created using dynamically allocated RAM. */ + xReturn = xTaskCreate( prvIdleTask, + configIDLE_TASK_NAME, + configMINIMAL_STACK_SIZE, + ( void * ) NULL, + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* freertos_tasks_c_additions_init() should only be called if the user + * definable macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is + * the only macro called by the function. */ + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + { + freertos_tasks_c_additions_init(); + } + #endif + + /* Interrupts are turned off here, to ensure a tick does not occur + * before or during the call to xPortStartScheduler(). The stacks of + * the created tasks contain a status word with interrupts switched on + * so interrupts will automatically get re-enabled when the first task + * starts to run. */ + portDISABLE_INTERRUPTS(); + + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + { + /* Switch C-Runtime's TLS Block to point to the TLS + * block specific to the task that will run first. */ + configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); + } + #endif + + xNextTaskUnblockTime = portMAX_DELAY; + xSchedulerRunning = pdTRUE; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + * macro must be defined to configure the timer/counter used to generate + * the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS + * is set to 0 and the following line fails to build then ensure you do not + * have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your + * FreeRTOSConfig.h file. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + traceTASK_SWITCHED_IN(); + + /* Setting up the timer tick is hardware specific and thus in the + * portable interface. */ + xPortStartScheduler(); + + /* In most cases, xPortStartScheduler() will not return. If it + * returns pdTRUE then there was not enough heap memory available + * to create either the Idle or the Timer task. If it returned + * pdFALSE, then the application called xTaskEndScheduler(). + * Most ports don't implement xTaskEndScheduler() as there is + * nothing to return to. */ + } + else + { + /* This line will only be reached if the kernel could not be started, + * because there was not enough FreeRTOS heap to create the idle task + * or the timer task. */ + configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); + } + + /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, + * meaning xIdleTaskHandle is not used anywhere else. */ + ( void ) xIdleTaskHandle; + + /* OpenOCD makes use of uxTopUsedPriority for thread debugging. Prevent uxTopUsedPriority + * from getting optimized out as it is no longer used by the kernel. */ + ( void ) uxTopUsedPriority; +} +/*-----------------------------------------------------------*/ + +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + * routine so the original ISRs can be restored if necessary. The port + * layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + vPortEndScheduler(); +} +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + * BaseType_t. Please read Richard Barry's reply in the following link to a + * post in the FreeRTOS support forum before reporting this as a bug! - + * https://goo.gl/wu4acr */ + + /* portSOFTWARE_BARRIER() is only implemented for emulated/simulated ports that + * do not otherwise exhibit real time behaviour. */ + portSOFTWARE_BARRIER(); + + /* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment + * is used to allow calls to vTaskSuspendAll() to nest. */ + ++uxSchedulerSuspended; + + /* Enforces ordering for ports and optimised compilers that may otherwise place + * the above increment elsewhere. */ + portMEMORY_BARRIER(); +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) + { + TickType_t xReturn; + UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + + /* uxHigherPriorityReadyTasks takes care of the case where + * configUSE_PREEMPTION is 0, so there may be tasks above the idle priority + * task that are in the Ready state, even though the idle task is + * running. */ + #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + { + if( uxTopReadyPriority > tskIDLE_PRIORITY ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #else + { + const UBaseType_t uxLeastSignificantBit = ( UBaseType_t ) 0x01; + + /* When port optimised task selection is used the uxTopReadyPriority + * variable is used as a bit map. If bits other than the least + * significant bit are set then there are tasks that have a priority + * above the idle priority that are in the Ready state. This takes + * care of the case where the co-operative scheduler is in use. */ + if( uxTopReadyPriority > uxLeastSignificantBit ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #endif /* if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) */ + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + * time slicing is used then the very next tick interrupt must be + * processed. */ + xReturn = 0; + } + else if( uxHigherPriorityReadyTasks != pdFALSE ) + { + /* There are tasks in the Ready state that have a priority above the + * idle priority. This path can only be reached if + * configUSE_PREEMPTION is 0. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskResumeAll( void ) +{ + TCB_t * pxTCB = NULL; + BaseType_t xAlreadyYielded = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + * previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended != ( UBaseType_t ) 0U ); + + /* It is possible that an ISR caused a task to be removed from an event + * list while the scheduler was suspended. If this was the case then the + * removed task will have been added to the xPendingReadyList. Once the + * scheduler has been resumed it is safe to move all the pending ready + * tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) + { + /* Move any readied tasks from the pending list into the + * appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + listREMOVE_ITEM( &( pxTCB->xEventListItem ) ); + portMEMORY_BARRIER(); + listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If the moved task has a priority higher than the current + * task then a yield must be performed. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( pxTCB != NULL ) + { + /* A task was unblocked while the scheduler was suspended, + * which may have prevented the next unblock time from being + * re-calculated, in which case re-calculate it now. Mainly + * important for low power tickless implementations, where + * this can prevent an unnecessary exit from low power + * state. */ + prvResetNextTaskUnblockTime(); + } + + /* If any ticks occurred while the scheduler was suspended then + * they should be processed now. This ensures the tick count does + * not slip, and that any delayed tasks are resumed at the correct + * time. */ + { + TickType_t xPendedCounts = xPendedTicks; /* Non-volatile copy. */ + + if( xPendedCounts > ( TickType_t ) 0U ) + { + do + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --xPendedCounts; + } while( xPendedCounts > ( TickType_t ) 0U ); + + xPendedTicks = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( xYieldPending != pdFALSE ) + { + #if ( configUSE_PREEMPTION != 0 ) + { + xAlreadyYielded = pdTRUE; + } + #endif + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCount( void ) +{ + TickType_t xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portTICK_TYPE_ENTER_CRITICAL(); + { + xTicks = xTickCount; + } + portTICK_TYPE_EXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCountFromISR( void ) +{ + TickType_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + * system call (or maximum API call) interrupt priority. Interrupts that are + * above the maximum system call priority are kept permanently enabled, even + * when the RTOS kernel is in a critical section, but cannot make any calls to + * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has been + * assigned a priority above the configured maximum system call priority. + * Only FreeRTOS functions that end in FromISR can be called from interrupts + * that have been assigned a priority at or (logically) below the maximum + * system call interrupt priority. FreeRTOS maintains a separate interrupt + * safe API to ensure interrupt entry is as fast and as simple as possible. + * More information (albeit Cortex-M specific) is provided on the following + * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = xTickCount; + } + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + * BaseType_t. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ + TCB_t * pxTCB; + + /* If null is passed in here then the name of the calling task is being + * queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList, + const char pcNameToQuery[] ) + { + TCB_t * pxNextTCB; + TCB_t * pxFirstTCB; + TCB_t * pxReturn = NULL; + UBaseType_t x; + char cNextChar; + BaseType_t xBreakLoop; + + /* This function is called with the scheduler suspended. */ + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Check each character in the name looking for a match or + * mismatch. */ + xBreakLoop = pdFALSE; + + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cNextChar = pxNextTCB->pcTaskName[ x ]; + + if( cNextChar != pcNameToQuery[ x ] ) + { + /* Characters didn't match. */ + xBreakLoop = pdTRUE; + } + else if( cNextChar == ( char ) 0x00 ) + { + /* Both strings terminated, a match must have been + * found. */ + pxReturn = pxNextTCB; + xBreakLoop = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xBreakLoop != pdFALSE ) + { + break; + } + } + + if( pxReturn != NULL ) + { + /* The handle has been found. */ + break; + } + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return pxReturn; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t uxQueue = configMAX_PRIORITIES; + TCB_t * pxTCB; + + /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ + configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); + + vTaskSuspendAll(); + { + /* Search the ready lists. */ + do + { + uxQueue--; + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); + + if( pxTCB != NULL ) + { + /* Found the handle. */ + break; + } + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); + } + + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the suspended list. */ + pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); + } + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the deleted list. */ + pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); + } + } + #endif + } + ( void ) xTaskResumeAll(); + + return pxTCB; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask, + StackType_t ** ppuxStackBuffer, + StaticTask_t ** ppxTaskBuffer ) + { + BaseType_t xReturn; + TCB_t * pxTCB; + + configASSERT( ppuxStackBuffer != NULL ); + configASSERT( ppxTaskBuffer != NULL ); + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) + { + if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ) + { + *ppuxStackBuffer = pxTCB->pxStack; + *ppxTaskBuffer = ( StaticTask_t * ) pxTCB; + xReturn = pdTRUE; + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + *ppuxStackBuffer = pxTCB->pxStack; + *ppxTaskBuffer = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */ + { + *ppuxStackBuffer = pxTCB->pxStack; + *ppxTaskBuffer = ( StaticTask_t * ) pxTCB; + xReturn = pdTRUE; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */ + + return xReturn; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) + { + UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an TaskStatus_t structure with information on each + * task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an TaskStatus_t structure with information on each + * task in the Blocked state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + * each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + * each task in the Suspended state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + if( pulTotalRunTime != NULL ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); + #else + *pulTotalRunTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + #endif + } + } + #else /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + * started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure vTaskStepTick() is available when user defined low power mode + * implementations require configUSE_TICKLESS_IDLE to be set to a value other than + * 1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void vTaskStepTick( TickType_t xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + * was suppressed. Note this does *not* call the tick hook function for + * each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + + if( ( xTickCount + xTicksToJump ) == xNextTaskUnblockTime ) + { + /* Arrange for xTickCount to reach xNextTaskUnblockTime in + * xTaskIncrementTick() when the scheduler resumes. This ensures + * that any delayed tasks are resumed at the correct time. */ + configASSERT( uxSchedulerSuspended != ( UBaseType_t ) 0U ); + configASSERT( xTicksToJump != ( TickType_t ) 0 ); + + /* Prevent the tick interrupt modifying xPendedTicks simultaneously. */ + taskENTER_CRITICAL(); + { + xPendedTicks++; + } + taskEXIT_CRITICAL(); + xTicksToJump--; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) +{ + BaseType_t xYieldOccurred; + + /* Must not be called with the scheduler suspended as the implementation + * relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */ + configASSERT( uxSchedulerSuspended == ( UBaseType_t ) 0U ); + + /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occurring when + * the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */ + vTaskSuspendAll(); + + /* Prevent the tick interrupt modifying xPendedTicks simultaneously. */ + taskENTER_CRITICAL(); + { + xPendedTicks += xTicksToCatchUp; + } + taskEXIT_CRITICAL(); + xYieldOccurred = xTaskResumeAll(); + + return xYieldOccurred; +} +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) + { + TCB_t * pxTCB = xTask; + BaseType_t xReturn; + + configASSERT( pxTCB ); + + vTaskSuspendAll(); + { + /* A task can only be prematurely removed from the Blocked state if + * it is actually in the Blocked state. */ + if( eTaskGetState( xTask ) == eBlocked ) + { + xReturn = pdPASS; + + /* Remove the reference to the task from the blocked list. An + * interrupt won't touch the xStateListItem because the + * scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove it from + * the event list too. Interrupts can touch the event list item, + * even though the scheduler is suspended, so a critical section + * is used. */ + taskENTER_CRITICAL(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + + /* This lets the task know it was forcibly removed from the + * blocked state so it should not re-evaluate its block time and + * then block again. */ + pxTCB->ucDelayAborted = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Place the unblocked task into the appropriate ready list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate context + * switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should only be + * performed if the unblocked task has a priority that is + * higher than the currently executing task. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Pend the yield to be performed when the scheduler + * is unsuspended. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + else + { + xReturn = pdFAIL; + } + } + ( void ) xTaskResumeAll(); + + return xReturn; + } + +#endif /* INCLUDE_xTaskAbortDelay */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskIncrementTick( void ) +{ + TCB_t * pxTCB; + TickType_t xItemValue; + BaseType_t xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + * Increments the tick then checks to see if the new tick value will cause any + * tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + /* Minor optimisation. The tick count cannot change in this + * block. */ + const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; + + /* Increment the RTOS tick, switching the delayed and overflowed + * delayed lists if it wraps to 0. */ + xTickCount = xConstTickCount; + + if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */ + { + taskSWITCH_DELAYED_LISTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in + * the queue in the order of their wake time - meaning once one task + * has been found whose block time has not expired there is no need to + * look any further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ; ; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime + * to the maximum possible value so it is extremely + * unlikely that the + * if( xTickCount >= xNextTaskUnblockTime ) test will pass + * next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + break; + } + else + { + /* The delayed list is not empty, get the value of the + * item at the head of the delayed list. This is the time + * at which the task at the head of the delayed list must + * be removed from the Blocked state. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the + * item value is the time at which the task at the head + * of the blocked list must be removed from the Blocked + * state - so record the item value in + * xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; /*lint !e9011 Code structure here is deemed easier to understand with multiple breaks. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* It is time to remove the item from the Blocked state. */ + listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove + * it from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + listREMOVE_ITEM( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Place the unblocked task into the appropriate ready + * list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate + * context switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should + * only be performed if the unblocked task's + * priority is higher than the currently executing + * task. + * The case of equal priority tasks sharing + * processing time (which happens when both + * preemption and time slicing are on) is + * handled below.*/ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + + /* Tasks of equal priority to the currently running task will share + * processing time (time slice) if preemption is on, and the application + * writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the pended tick + * count is being unwound (when the scheduler is being unlocked). */ + if( xPendedTicks == ( TickType_t ) 0 ) + { + vApplicationTickHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICK_HOOK */ + + #if ( configUSE_PREEMPTION == 1 ) + { + if( xYieldPending != pdFALSE ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + else + { + ++xPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + * scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + vApplicationTickHook(); + } + #endif + } + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) + { + TCB_t * xTCB; + + /* If xTask is NULL then it is the task hook of the calling task that is + * getting set. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + * the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xTCB->pxTaskTag = pxHookFunction; + } + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TCB_t * pxTCB; + TaskHookFunction_t xReturn; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + * the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xReturn = pxTCB->pxTaskTag; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) + { + TCB_t * pxTCB; + TaskHookFunction_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + * the value can be accessed from an interrupt. */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = pxTCB->pxTaskTag; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, + void * pvParameter ) + { + TCB_t * xTCB; + BaseType_t xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( UBaseType_t ) 0U ) + { + /* The scheduler is currently suspended - do not allow a context + * switch. */ + xYieldPending = pdTRUE; + } + else + { + xYieldPending = pdFALSE; + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + * accumulated time so far. The time the task started running was + * stored in ulTaskSwitchedInTime. Note that there is no overflow + * protection here so count values are only valid until the timer + * overflows. The guard against negative values is to protect + * against suspect run time stat counter implementations - which + * are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + /* Check for stack overflow, if configured. */ + taskCHECK_FOR_STACK_OVERFLOW(); + + /* Before the currently running task is switched out, save its errno. */ + #if ( configUSE_POSIX_ERRNO == 1 ) + { + pxCurrentTCB->iTaskErrno = FreeRTOS_errno; + } + #endif + + /* Select a new task to run using either the generic C or port + * optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + traceTASK_SWITCHED_IN(); + + /* After the new task is switched in, update the global errno. */ + #if ( configUSE_POSIX_ERRNO == 1 ) + { + FreeRTOS_errno = pxCurrentTCB->iTaskErrno; + } + #endif + + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + { + /* Switch C-Runtime's TLS Block to point to the TLS + * Block specific to this task. */ + configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( List_t * const pxEventList, + const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE + * SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ + + /* Place the event list item of the TCB in the appropriate event list. + * This is placed in the list in priority order so the highest priority task + * is the first to be woken by the event. + * + * Note: Lists are sorted in ascending order by ListItem_t.xItemValue. + * Normally, the xItemValue of a TCB's ListItem_t members is: + * xItemValue = ( configMAX_PRIORITIES - uxPriority ) + * Therefore, the event list is sorted in descending priority order. + * + * The queue that contains the event list is locked, preventing + * simultaneous access from interrupts. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, + const TickType_t xItemValue, + const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + * the event groups implementation. */ + configASSERT( uxSchedulerSuspended != ( UBaseType_t ) 0U ); + + /* Store the item value in the event list item. It is safe to access the + * event list item here as interrupts won't access the event list item of a + * task that is not in the Blocked state. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Place the event list item of the TCB at the end of the appropriate event + * list. It is safe to access the event list here because it is part of an + * event group implementation - and interrupts don't access event groups + * directly (instead they access them indirectly by pending function calls to + * the task level). */ + listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, + TickType_t xTicksToWait, + const BaseType_t xWaitIndefinitely ) + { + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + * 'Restricted' in its name. It is not part of the public API. It is + * designed for use by kernel code, and has special calling requirements - + * it should be called with the scheduler suspended. */ + + + /* Place the event list item of the TCB in the appropriate event list. + * In this case it is assume that this is the only task that is going to + * be waiting on this event list, so the faster vListInsertEnd() function + * can be used in place of vListInsert. */ + listINSERT_END( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* If the task should block indefinitely then set the block time to a + * value that will be recognised as an indefinite delay inside the + * prvAddCurrentTaskToDelayedList() function. */ + if( xWaitIndefinitely != pdFALSE ) + { + xTicksToWait = portMAX_DELAY; + } + + traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); + prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) +{ + TCB_t * pxUnblockedTCB; + BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be + * called from a critical section within an ISR. */ + + /* The event list is sorted in priority order, so the first in the list can + * be removed as it is known to be the highest priority. Remove the TCB from + * the delayed list, and add it to the ready list. + * + * If an event is for a queue that is locked then this function will never + * get called - the lock count on the queue will get modified instead. This + * means exclusive access to the event list is guaranteed here. + * + * This function assumes that a check has already been made to ensure that + * pxEventList is not empty. */ + pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked on a kernel object then xNextTaskUnblockTime + * might be set to the blocked task's time out time. If the task is + * unblocked for a reason other than a timeout xNextTaskUnblockTime is + * normally left unchanged, because it is automatically reset to a new + * value when the tick count equals xNextTaskUnblockTime. However if + * tickless idling is used it might be more important to enter sleep mode + * at the earliest possible time - so reset xNextTaskUnblockTime here to + * ensure it is updated at the earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + } + else + { + /* The delayed and ready lists cannot be accessed, so hold this task + * pending until the scheduler is resumed. */ + listINSERT_END( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has a higher + * priority than the calling task. This allows the calling task to know if + * it should force a context switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + * "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, + const TickType_t xItemValue ) +{ + TCB_t * pxUnblockedTCB; + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + * the event flags implementation. */ + configASSERT( uxSchedulerSuspended != ( UBaseType_t ) 0U ); + + /* Store the new item value in the event list. */ + listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Remove the event list form the event flag. Interrupts do not access + * event flags. */ + pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + listREMOVE_ITEM( pxEventListItem ); + + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked on a kernel object then xNextTaskUnblockTime + * might be set to the blocked task's time out time. If the task is + * unblocked for a reason other than a timeout xNextTaskUnblockTime is + * normally left unchanged, because it is automatically reset to a new + * value when the tick count equals xNextTaskUnblockTime. However if + * tickless idling is used it might be more important to enter sleep mode + * at the earliest possible time - so reset xNextTaskUnblockTime here to + * ensure it is updated at the earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + /* Remove the task from the delayed list and add it to the ready list. The + * scheduler is suspended so interrupts will not be accessing the ready + * lists. */ + listREMOVE_ITEM( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The unblocked task has a priority above that of the calling task, so + * a context switch is required. This function is called with the + * scheduler suspended so xYieldPending is set so the context switch + * occurs immediately that the scheduler is resumed (unsuspended). */ + xYieldPending = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + taskENTER_CRITICAL(); + { + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + /* For internal use only as it does not use a critical section. */ + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) +{ + BaseType_t xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const TickType_t xConstTickCount = xTickCount; + const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) + { + /* The delay was aborted, which is not the same as a time out, + * but has the same result. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + xReturn = pdTRUE; + } + else + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + if( *pxTicksToWait == portMAX_DELAY ) + { + /* If INCLUDE_vTaskSuspend is set to 1 and the block time + * specified is the maximum block time then the task should block + * indefinitely, and therefore never time out. */ + xReturn = pdFALSE; + } + else + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which + * vTaskSetTimeout() was called, but has also overflowed since + * vTaskSetTimeOut() was called. It must have wrapped all the way + * around and gone past again. This passed since vTaskSetTimeout() + * was called. */ + xReturn = pdTRUE; + *pxTicksToWait = ( TickType_t ) 0; + } + else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= xElapsedTime; + vTaskInternalSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + *pxTicksToWait = ( TickType_t ) 0; + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + TCB_t const * pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskSetTaskNumber( TaskHandle_t xTask, + const UBaseType_t uxHandle ) + { + TCB_t * pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ + +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE + * SCHEDULER IS STARTED. **/ + + /* In case a task that has a secure context deletes itself, in which case + * the idle task is responsible for deleting the task's secure context, if + * any. */ + portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); + + for( ; ; ) + { + /* See if any tasks have deleted themselves - if so then the idle task + * is responsible for freeing the deleted task's TCB and stack. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + * see if any other task has become available. If we are using + * preemption we don't need to do this as any task becoming available + * will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + * timesliced. If a task that is sharing the idle priority is ready + * to run then the idle task should yield before the end of the + * timeslice. + * + * A critical region is not required here as we are just reading from + * the list, and an occasional incorrect value will not matter. If + * the ready list at the idle priority contains more than one task + * then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) + { + taskYIELD(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + /* Call the user defined function from within the idle task. */ + vApplicationIdleHook(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + * to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + * user defined low power mode implementations require + * configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + TickType_t xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + * each iteration of the idle task. Therefore, a preliminary + * test of the expected idle time is performed without the + * scheduler suspended. The result here is not necessarily + * valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + * time can be sampled again, and this time its value can + * be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + /* Define the following macro to set xExpectedIdleTime to 0 + * if the application does not want + * portSUPPRESS_TICKS_AND_SLEEP() to be called. */ + configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + eSleepModeStatus eTaskConfirmSleepModeStatus( void ) + { + #if ( INCLUDE_vTaskSuspend == 1 ) + /* The idle task exists in addition to the application tasks. */ + const UBaseType_t uxNonApplicationTasks = 1; + #endif /* INCLUDE_vTaskSuspend */ + + eSleepModeStatus eReturn = eStandardSleep; + + /* This function must be called from a critical section. */ + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xPendedTicks != 0 ) + { + /* A tick interrupt has already occurred but was held pending + * because the scheduler is suspended. */ + eReturn = eAbortSleep; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + /* If all the tasks are in the suspended list (which might mean they + * have an infinite block time rather than actually being suspended) + * then it is safe to turn all clocks off and just wait for external + * interrupts. */ + eReturn = eNoTasksWaitingTimeout; + } + #endif /* INCLUDE_vTaskSuspend */ + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return eReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) + { + TCB_t * pxTCB; + + if( ( xIndex >= 0 ) && + ( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) + { + pxTCB = prvGetTCBFromHandle( xTaskToSet ); + configASSERT( pxTCB != NULL ); + pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; + } + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void * pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) + { + void * pvReturn = NULL; + TCB_t * pxTCB; + + if( ( xIndex >= 0 ) && + ( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) + { + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; + } + else + { + pvReturn = NULL; + } + + return pvReturn; + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, + const MemoryRegion_t * const xRegions ) + { + TCB_t * pxTCB; + + /* If null is passed in here then we are modifying the MPU settings of + * the calling task. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTaskLists( void ) +{ + UBaseType_t uxPriority; + + for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + * using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + /** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + TCB_t * pxTCB; + + /* uxDeletedTasksWaitingCleanUp is used to prevent taskENTER_CRITICAL() + * being called too often in the idle task. */ + while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) + { + taskENTER_CRITICAL(); + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + --uxCurrentNumberOfTasks; + --uxDeletedTasksWaitingCleanUp; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + #endif /* INCLUDE_vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) + { + TCB_t * pxTCB; + + /* xTask is NULL then get the state of the calling task. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB; + pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName[ 0 ] ); + pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority; + pxTaskStatus->pxStackBase = pxTCB->pxStack; + #if ( ( portSTACK_GROWTH > 0 ) && ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + pxTaskStatus->pxTopOfStack = pxTCB->pxTopOfStack; + pxTaskStatus->pxEndOfStack = pxTCB->pxEndOfStack; + #endif + pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; + } + #else + { + pxTaskStatus->uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + } + #else + { + pxTaskStatus->ulRunTimeCounter = ( configRUN_TIME_COUNTER_TYPE ) 0; + } + #endif + + /* Obtaining the task state is a little fiddly, so is only done if the + * value of eState passed into this function is eInvalid - otherwise the + * state is just set to whatever is passed in. */ + if( eState != eInvalid ) + { + if( pxTCB == pxCurrentTCB ) + { + pxTaskStatus->eCurrentState = eRunning; + } + else + { + pxTaskStatus->eCurrentState = eState; + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* If the task is in the suspended list then there is a + * chance it is actually just blocked indefinitely - so really + * it should be reported as being in the Blocked state. */ + if( eState == eSuspended ) + { + vTaskSuspendAll(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + pxTaskStatus->eCurrentState = eBlocked; + } + } + ( void ) xTaskResumeAll(); + } + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Tasks can be in pending ready list and other state list at the + * same time. These tasks are in ready state no matter what state + * list the task is in. */ + taskENTER_CRITICAL(); + { + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdFALSE ) + { + pxTaskStatus->eCurrentState = eReady; + } + } + taskEXIT_CRITICAL(); + } + } + else + { + pxTaskStatus->eCurrentState = eTaskGetState( pxTCB ); + } + + /* Obtaining the stack space takes some time, so the xGetFreeStackSpace + * parameter is provided to allow it to be skipped. */ + if( xGetFreeStackSpace != pdFALSE ) + { + #if ( portSTACK_GROWTH > 0 ) + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack ); + } + #else + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack ); + } + #endif + } + else + { + pxTaskStatus->usStackHighWaterMark = 0; + } + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t * pxTaskStatusArray, + List_t * pxList, + eTaskState eState ) + { + configLIST_VOLATILE TCB_t * pxNextTCB; + configLIST_VOLATILE TCB_t * pxFirstTCB; + UBaseType_t uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Populate an TaskStatus_t structure within the + * pxTaskStatusArray array for each task that is referenced from + * pxList. See the definition of TaskStatus_t in task.h for the + * meaning of each TaskStatus_t structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); + uxTask++; + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) + { + uint32_t ulCount = 0U; + + while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + ulCount++; + } + + ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ + + return ( configSTACK_DEPTH_TYPE ) ulCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +/* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. */ + configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + { + TCB_t * pxTCB; + uint8_t * pucEndOfStack; + configSTACK_DEPTH_TYPE uxReturn; + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are + * the same except for their return type. Using configSTACK_DEPTH_TYPE + * allows the user to determine the return type. It gets around the + * problem of the value overflowing on 8-bit types without breaking + * backward compatibility for applications that expect an 8-bit return + * type. */ + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + TCB_t * pxTCB; + uint8_t * pucEndOfStack; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t * pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + * above the vPortFree() calls. The call is also used by ports/demos that + * want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + { + /* Free up the memory allocated for the task's TLS Block. */ + configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); + } + #endif + + #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) + { + /* The task can only have been allocated dynamically - free both + * the stack and TCB. */ + vPortFreeStack( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + #elif ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* The task could have been allocated statically or dynamically, so + * check what was statically allocated before trying to free the + * memory. */ + if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) + { + /* Both the stack and TCB were allocated dynamically, so both + * must be freed. */ + vPortFreeStack( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + /* Only the stack was statically allocated, so the TCB is the + * only memory that must be freed. */ + vPortFree( pxTCB ); + } + else + { + /* Neither the stack nor the TCB were allocated dynamically, so + * nothing needs to be freed. */ + configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ); + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +static void prvResetNextTaskUnblockTime( void ) +{ + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set xNextTaskUnblockTime to + * the maximum possible value so it is extremely unlikely that the + * if( xTickCount >= xNextTaskUnblockTime ) test will pass until + * there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + * the item at the head of the delayed list. This is the time at + * which the task at the head of the delayed list should be removed + * from the Blocked state. */ + xNextTaskUnblockTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxDelayedTaskList ); + } +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + + /* A critical section is not required as this is not called from + * an interrupt and the current TCB will always be the same for any + * individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + BaseType_t xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxMutexHolderTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + /* If the mutex was given back by an interrupt while the queue was + * locked then the mutex holder might now be NULL. _RB_ Is this still + * needed as interrupts can no longer use mutexes? */ + if( pxMutexHolder != NULL ) + { + /* If the holder of the mutex has a priority below the priority of + * the task attempting to obtain the mutex then it will temporarily + * inherit the priority of the task attempting to obtain the mutex. */ + if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new + * priority. Only reset the event list item value if the value is + * not being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task being modified is in the ready state it will need + * to be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxMutexHolderTCB->uxPriority ] ), &( pxMutexHolderTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxMutexHolderTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + * there is no need to check again and the port level + * reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxMutexHolderTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Inherit the priority before being moved into the new list. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + prvAddTaskToReadyList( pxMutexHolderTCB ); + } + else + { + /* Just inherit the priority. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority ); + + /* Inheritance occurred. */ + xReturn = pdTRUE; + } + else + { + if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority ) + { + /* The base priority of the mutex holder is lower than the + * priority of the task attempting to take the mutex, but the + * current priority of the mutex holder is not lower than the + * priority of the task attempting to take the mutex. + * Therefore the mutex holder must have already inherited a + * priority, but inheritance would have occurred if that had + * not been the case. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + if( pxMutexHolder != NULL ) + { + /* A task can only have an inherited priority if it holds the mutex. + * If the mutex is held by a task then it cannot be given from an + * interrupt, and if a mutex is given by the holding task then it must + * be the running state task. */ + configASSERT( pxTCB == pxCurrentTCB ); + configASSERT( pxTCB->uxMutexesHeld ); + ( pxTCB->uxMutexesHeld )--; + + /* Has the holder of the mutex inherited the priority of another + * task? */ + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* Only disinherit if no other mutexes are held. */ + if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) + { + /* A task can only have an inherited priority if it holds + * the mutex. If the mutex is held by a task then it cannot be + * given from an interrupt, and if a mutex is given by the + * holding task then it must be the running state task. Remove + * the holding task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + portRESET_READY_PRIORITY( pxTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Disinherit the priority before adding the task into the + * new ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + + /* Reset the event list item value. It cannot be in use for + * any other purpose if this task is running, and it must be + * running to give back the mutex. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + prvAddTaskToReadyList( pxTCB ); + + /* Return true to indicate that a context switch is required. + * This is only actually required in the corner case whereby + * multiple mutexes were held and the mutexes were given back + * in an order different to that in which they were taken. + * If a context switch did not occur when the first mutex was + * returned, even if a task was waiting on it, then a context + * switch should occur when the last mutex is returned whether + * a task is waiting on it or not. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, + UBaseType_t uxHighestPriorityWaitingTask ) + { + TCB_t * const pxTCB = pxMutexHolder; + UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse; + const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1; + + if( pxMutexHolder != NULL ) + { + /* If pxMutexHolder is not NULL then the holder must hold at least + * one mutex. */ + configASSERT( pxTCB->uxMutexesHeld ); + + /* Determine the priority to which the priority of the task that + * holds the mutex should be set. This will be the greater of the + * holding task's base priority and the priority of the highest + * priority task that is waiting to obtain the mutex. */ + if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask ) + { + uxPriorityToUse = uxHighestPriorityWaitingTask; + } + else + { + uxPriorityToUse = pxTCB->uxBasePriority; + } + + /* Does the priority need to change? */ + if( pxTCB->uxPriority != uxPriorityToUse ) + { + /* Only disinherit if no other mutexes are held. This is a + * simplification in the priority inheritance implementation. If + * the task that holds the mutex is also holding other mutexes then + * the other mutexes may have caused the priority inheritance. */ + if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld ) + { + /* If a task has timed out because it already holds the + * mutex it was trying to obtain then it cannot of inherited + * its own priority. */ + configASSERT( pxTCB != pxCurrentTCB ); + + /* Disinherit the priority, remembering the previous + * priority to facilitate determining the subject task's + * state. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, uxPriorityToUse ); + uxPriorityUsedOnEntry = pxTCB->uxPriority; + pxTCB->uxPriority = uxPriorityToUse; + + /* Only reset the event list item value if the value is not + * being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the running task is not the task that holds the mutex + * then the task that holds the mutex could be in either the + * Ready, Blocked or Suspended states. Only remove the task + * from its current state list if it is in the Ready state as + * the task's priority is going to change and there is one + * Ready list per priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + * there is no need to check again and the port level + * reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + + /* This is not the interrupt safe version of the enter critical + * function so assert() if it is being called from an interrupt + * context. Only API functions that end in "FromISR" can be used in an + * interrupt. Only assert if the critical nesting count is 1 to + * protect against recursive calls if the assert function also uses a + * critical section. */ + if( pxCurrentTCB->uxCriticalNesting == 1 ) + { + portASSERT_IF_IN_ISR(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + portENABLE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) + + static char * prvWriteNameToBuffer( char * pcBuffer, + const char * pcTaskName ) + { + size_t x; + + /* Start by copying the entire string. */ + strcpy( pcBuffer, pcTaskName ); + + /* Pad the end of the string with spaces to ensure columns line up when + * printed out. */ + for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) + { + pcBuffer[ x ] = ' '; + } + + /* Terminate. */ + pcBuffer[ x ] = ( char ) 0x00; + + /* Return the new end of string. */ + return &( pcBuffer[ x ] ); + } + +#endif /* ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + void vTaskList( char * pcWriteBuffer ) + { + TaskStatus_t * pxTaskStatusArray; + UBaseType_t uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task: names, states, priority, stack usage and task number. + * Stack usage specified as the number of unused StackType_t words stack can hold + * on top of stack - not the number of bytes. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + * function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! if + * configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + * equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eRunning: + cStatus = tskRUNNING_CHAR; + break; + + case eReady: + cStatus = tskREADY_CHAR; + break; + + case eBlocked: + cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: + cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: + cStatus = tskDELETED_CHAR; + break; + + case eInvalid: /* Fall through. */ + default: /* Should not get here, but it is included + * to prevent static checking errors. */ + cStatus = ( char ) 0x00; + break; + } + + /* Write the task name to the string, padding with spaces so it + * can be printed in tabular form more easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + /* Write the rest of the string. */ + sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + * is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configUSE_TRACE_FACILITY == 1 ) ) + + void vTaskGetRunTimeStats( char * pcWriteBuffer ) + { + TaskStatus_t * pxTaskStatusArray; + UBaseType_t uxArraySize, x; + configRUN_TIME_COUNTER_TYPE ulTotalTime, ulStatsAsPercentage; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + * function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! If + * configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + * equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0UL ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + * This will always be rounded down to the nearest integer. + * ulTotalRunTime has already been divided by 100. */ + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; + + /* Write the task name to the string, padding with + * spaces so it can be printed in tabular form more + * easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + * printf() library can be used. */ + sprintf( pcWriteBuffer, "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ + } + #endif + } + else + { + /* If the percentage is zero here then the task has + * consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + * printf() library can be used. */ + sprintf( pcWriteBuffer, "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */ + } + #endif + } + + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + * is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ +/*-----------------------------------------------------------*/ + +TickType_t uxTaskResetEventItemValue( void ) +{ + TickType_t uxReturn; + + uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + + /* Reset the event list item to its normal value - so it can be used with + * queues and semaphores. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + TaskHandle_t pvTaskIncrementMutexHeldCount( void ) + { + /* If xSemaphoreCreateMutex() is called before any tasks have been created + * then pxCurrentTCB will be NULL. */ + if( pxCurrentTCB != NULL ) + { + ( pxCurrentTCB->uxMutexesHeld )++; + } + + return pxCurrentTCB; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t ulTaskGenericNotifyTake( UBaseType_t uxIndexToWait, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) + { + uint32_t ulReturn; + + configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + + taskENTER_CRITICAL(); + { + /* Only block if the notification count is not already non-zero. */ + if( pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] == 0UL ) + { + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_TAKE_BLOCK( uxIndexToWait ); + + /* All ports are written to allow a yield in a critical + * section (some will yield immediately, others wait until the + * critical section exits) - but it is not something that + * application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_TAKE( uxIndexToWait ); + ulReturn = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ]; + + if( ulReturn != 0UL ) + { + if( xClearCountOnExit != pdFALSE ) + { + pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = 0UL; + } + else + { + pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] = ulReturn - ( uint32_t ) 1; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return ulReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyWait( UBaseType_t uxIndexToWait, + uint32_t ulBitsToClearOnEntry, + uint32_t ulBitsToClearOnExit, + uint32_t * pulNotificationValue, + TickType_t xTicksToWait ) + { + BaseType_t xReturn; + + configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + + taskENTER_CRITICAL(); + { + /* Only block if a notification is not already pending. */ + if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED ) + { + /* Clear bits in the task's notification value as bits may get + * set by the notifying task or interrupt. This can be used to + * clear the value to zero. */ + pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnEntry; + + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait ); + + /* All ports are written to allow a yield in a critical + * section (some will yield immediately, others wait until the + * critical section exits) - but it is not something that + * application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_WAIT( uxIndexToWait ); + + if( pulNotificationValue != NULL ) + { + /* Output the current notification value, which may or may not + * have changed. */ + *pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ]; + } + + /* If ucNotifyValue is set then either the task never entered the + * blocked state (because a notification was already pending) or the + * task unblocked because of a notification. Otherwise the task + * unblocked because of a timeout. */ + if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED ) + { + /* A notification was not received. */ + xReturn = pdFALSE; + } + else + { + /* A notification was already pending or a notification was + * received while the task was waiting. */ + pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnExit; + xReturn = pdTRUE; + } + + pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue ) + { + TCB_t * pxTCB; + BaseType_t xReturn = pdPASS; + uint8_t ucOriginalNotifyState; + + configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + configASSERT( xTaskToNotify ); + pxTCB = xTaskToNotify; + + taskENTER_CRITICAL(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ]; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; + + pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits: + pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue; + break; + + case eIncrement: + ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++; + break; + + case eSetValueWithOverwrite: + pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; + break; + + case eSetValueWithoutOverwrite: + + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + + break; + + case eNoAction: + + /* The task is being notified without its notify value being + * updated. */ + break; + + default: + + /* Should not get here if all enums are handled. + * Artificially force an assert by testing a value the + * compiler can't assume is const. */ + configASSERT( xTickCount == ( TickType_t ) 0 ); + + break; + } + + traceTASK_NOTIFY( uxIndexToNotify ); + + /* If the task is in the blocked state specifically to wait for a + * notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + * xNextTaskUnblockTime might be set to the blocked task's time + * out time. If the task is unblocked for a reason other than + * a timeout xNextTaskUnblockTime is normally left unchanged, + * because it will automatically get reset to a new value when + * the tick count equals xNextTaskUnblockTime. However if + * tickless idling is used it might be more important to enter + * sleep mode at the earliest possible time - so reset + * xNextTaskUnblockTime here to ensure it is updated at the + * earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + * executing task so a yield is required. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + uint32_t ulValue, + eNotifyAction eAction, + uint32_t * pulPreviousNotificationValue, + BaseType_t * pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + BaseType_t xReturn = pdPASS; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + + /* RTOS ports that support interrupt nesting have the concept of a + * maximum system call (or maximum API call) interrupt priority. + * Interrupts that are above the maximum system call priority are keep + * permanently enabled, even when the RTOS kernel is in a critical section, + * but cannot make any calls to FreeRTOS API functions. If configASSERT() + * is defined in FreeRTOSConfig.h then + * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has + * been assigned a priority above the configured maximum system call + * priority. Only FreeRTOS functions that end in FromISR can be called + * from interrupts that have been assigned a priority at or (logically) + * below the maximum system call interrupt priority. FreeRTOS maintains a + * separate interrupt safe API to ensure interrupt entry is as fast and as + * simple as possible. More information (albeit Cortex-M specific) is + * provided on the following link: + * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ]; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; + pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits: + pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue; + break; + + case eIncrement: + ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++; + break; + + case eSetValueWithOverwrite: + pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; + break; + + case eSetValueWithoutOverwrite: + + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + + break; + + case eNoAction: + + /* The task is being notified without its notify value being + * updated. */ + break; + + default: + + /* Should not get here if all enums are handled. + * Artificially force an assert by testing a value the + * compiler can't assume is const. */ + configASSERT( xTickCount == ( TickType_t ) 0 ); + break; + } + + traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify ); + + /* If the task is in the blocked state specifically to wait for a + * notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + * this task pending until the scheduler is resumed. */ + listINSERT_END( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + * executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + * using the "xHigherPriorityTaskWoken" parameter to an ISR + * safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + void vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify, + UBaseType_t uxIndexToNotify, + BaseType_t * pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + + /* RTOS ports that support interrupt nesting have the concept of a + * maximum system call (or maximum API call) interrupt priority. + * Interrupts that are above the maximum system call priority are keep + * permanently enabled, even when the RTOS kernel is in a critical section, + * but cannot make any calls to FreeRTOS API functions. If configASSERT() + * is defined in FreeRTOSConfig.h then + * portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + * failure if a FreeRTOS API function is called from an interrupt that has + * been assigned a priority above the configured maximum system call + * priority. Only FreeRTOS functions that end in FromISR can be called + * from interrupts that have been assigned a priority at or (logically) + * below the maximum system call interrupt priority. FreeRTOS maintains a + * separate interrupt safe API to ensure interrupt entry is as fast and as + * simple as possible. More information (albeit Cortex-M specific) is + * provided on the following link: + * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ]; + pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + + /* 'Giving' is equivalent to incrementing a count in a counting + * semaphore. */ + ( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++; + + traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ); + + /* If the task is in the blocked state specifically to wait for a + * notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) 0U ) + { + listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + * this task pending until the scheduler is resumed. */ + listINSERT_END( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + * executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + * using the "xHigherPriorityTaskWoken" parameter in an ISR + * safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) + { + TCB_t * pxTCB; + BaseType_t xReturn; + + configASSERT( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + + /* If null is passed in here then it is the calling task that is having + * its notification state cleared. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + taskENTER_CRITICAL(); + { + if( pxTCB->ucNotifyState[ uxIndexToClear ] == taskNOTIFICATION_RECEIVED ) + { + pxTCB->ucNotifyState[ uxIndexToClear ] = taskNOT_WAITING_NOTIFICATION; + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) + { + TCB_t * pxTCB; + uint32_t ulReturn; + + configASSERT( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ); + + /* If null is passed in here then it is the calling task that is having + * its notification state cleared. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + taskENTER_CRITICAL(); + { + /* Return the notification as it was before the bits were cleared, + * then clear the bit mask. */ + ulReturn = pxTCB->ulNotifiedValue[ uxIndexToClear ]; + pxTCB->ulNotifiedValue[ uxIndexToClear ] &= ~ulBitsToClear; + } + taskEXIT_CRITICAL(); + + return ulReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) + { + return xTask->ulRunTimeCounter; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) + { + configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; + + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + + /* For percentage calculations. */ + ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) + { + ulReturn = xTask->ulRunTimeCounter / ulTotalTime; + } + else + { + ulReturn = 0; + } + + return ulReturn; + } + +#endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) + { + return ulTaskGetRunTimeCounter( xIdleTaskHandle ); + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimePercent( void ) + { + return ulTaskGetRunTimePercent( xIdleTaskHandle ); + } + +#endif +/*-----------------------------------------------------------*/ + +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, + const BaseType_t xCanBlockIndefinitely ) +{ + TickType_t xTimeToWake; + const TickType_t xConstTickCount = xTickCount; + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + { + /* About to enter a delayed list, so ensure the ucDelayAborted flag is + * reset to pdFALSE so it can be detected as having been set to pdTRUE + * when the task leaves the Blocked state. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Remove the task from the ready list before adding it to the blocked list + * as the same list item is used for both lists. */ + if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + * check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); /*lint !e931 pxCurrentTCB cannot change as it is the calling task. pxCurrentTCB->uxPriority and uxTopReadyPriority cannot change as called with scheduler suspended or in a critical section. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) ) + { + /* Add the task to the suspended task list instead of a delayed task + * list to ensure it is not woken by a timing event. It will block + * indefinitely. */ + listINSERT_END( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + * does not occur. This may overflow but this doesn't matter, the + * kernel will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow + * list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list + * is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the + * head of the list of blocked tasks then xNextTaskUnblockTime + * needs to be updated too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event + * does not occur. This may overflow but this doesn't matter, the kernel + * will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + * list of blocked tasks then xNextTaskUnblockTime needs to be updated + * too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */ + ( void ) xCanBlockIndefinitely; + } + #endif /* INCLUDE_vTaskSuspend */ +} +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + xMPU_SETTINGS * xTaskGetMPUSettings( TaskHandle_t xTask ) + { + TCB_t * pxTCB; + + pxTCB = prvGetTCBFromHandle( xTask ); + + return &( pxTCB->xMPUSettings ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +/* Code below here allows additional code to be inserted into this source file, + * especially where access to file scope functions and data is needed (for example + * when performing module tests). */ + +#ifdef FREERTOS_MODULE_TEST + #include "tasks_test_access_functions.h" +#endif + + +#if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) + + #include "freertos_tasks_c_additions.h" + + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + static void freertos_tasks_c_additions_init( void ) + { + FREERTOS_TASKS_C_ADDITIONS_INIT(); + } + #endif + +#endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */ diff --git a/Middlewares/Third_Party/FreeRTOS/Source/timers.c b/Middlewares/Third_Party/FreeRTOS/Source/timers.c new file mode 100644 index 0000000..d5012ad --- /dev/null +++ b/Middlewares/Third_Party/FreeRTOS/Source/timers.c @@ -0,0 +1,1146 @@ +/* + * FreeRTOS Kernel V10.6.2 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified + * because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined + * for the header files above, but not in this file, in order to generate the + * correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured + * to include software timer functionality. This #if is closed at the very bottom + * of this file. If you want to include software timer functionality then ensure + * configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ + #define tmrNO_DELAY ( ( TickType_t ) 0U ) + #define tmrMAX_TIME_BEFORE_OVERFLOW ( ( TickType_t ) -1 ) + +/* The name assigned to the timer service task. This can be overridden by + * defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ + #ifndef configTIMER_SERVICE_TASK_NAME + #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" + #endif + +/* Bit definitions used in the ucStatus member of a timer structure. */ + #define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) + #define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) + #define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) + +/* The definition of the timers themselves. */ + typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ + { + const char * pcTimerName; /**< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /**< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks; /**< How quickly and often the timer expires. */ + void * pvTimerID; /**< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /**< The function that will be called when the timer expires. */ + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /**< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif + uint8_t ucStatus; /**< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ + } xTIMER; + +/* The old xTIMER name is maintained above then typedefed to the new Timer_t + * name below to enable the use of older kernel aware debuggers. */ + typedef xTIMER Timer_t; + +/* The definition of messages that can be sent and received on the timer queue. + * Two types of message can be queued - messages that manipulate a software timer, + * and messages that request the execution of a non-timer related callback. The + * two message types are defined in two separate structures, xTimerParametersType + * and xCallbackParametersType respectively. */ + typedef struct tmrTimerParameters + { + TickType_t xMessageValue; /**< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /**< The timer to which the command will be applied. */ + } TimerParameter_t; + + + typedef struct tmrCallbackParameters + { + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void * pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ + } CallbackParameters_t; + +/* The structure that contains the two message types, along with an identifier + * that is used to determine which message type is valid. */ + typedef struct tmrTimerQueueMessage + { + BaseType_t xMessageID; /**< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + * it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; + } DaemonTaskMessage_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine + * which static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire + * time order, with the nearest expiry time at the front of the list. Only the + * timer service task is allowed to access these lists. + * xActiveTimerList1 and xActiveTimerList2 could be at function scope but that + * breaks some kernel aware debuggers, and debuggers that reply on removing the + * static qualifier. */ + PRIVILEGED_DATA static List_t xActiveTimerList1; + PRIVILEGED_DATA static List_t xActiveTimerList2; + PRIVILEGED_DATA static List_t * pxCurrentTimerList; + PRIVILEGED_DATA static List_t * pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ + PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; + PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ + static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ + static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ + static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ + static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, + const TickType_t xNextExpiryTime, + const TickType_t xTimeNow, + const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * Reload the specified auto-reload timer. If the reloading is backlogged, + * clear the backlog, calling the callback for each additional reload. When + * this function returns, the next expiry time is after xTimeNow. + */ + static void prvReloadTimer( Timer_t * const pxTimer, + TickType_t xExpiredTime, + const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto-reload timer, then call its callback. + */ + static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, + const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ + static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ + static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ + static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ + static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, + BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * Called after a Timer_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ + static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const BaseType_t xAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t * pxNewTimer ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + + BaseType_t xTimerCreateTimerTask( void ) + { + BaseType_t xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + * configUSE_TIMERS is set to 1. Check that the infrastructure used by the + * timer service task has been created/initialised. If timers have already + * been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t * pxTimerTaskTCBBuffer = NULL; + StackType_t * pxTimerTaskStackBuffer = NULL; + uint32_t ulTimerTaskStackSize; + + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + ulTimerTaskStackSize, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + pxTimerTaskStackBuffer, + pxTimerTaskTCBBuffer ); + + if( xTimerTaskHandle != NULL ) + { + xReturn = pdPASS; + } + } + #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + { + xReturn = xTaskCreate( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + configTIMER_TASK_STACK_DEPTH, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + &xTimerTaskHandle ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const BaseType_t xAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) + { + Timer_t * pxNewTimer; + + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */ + + if( pxNewTimer != NULL ) + { + /* Status is thus far zero as the timer is not created statically + * and has not been started. The auto-reload bit may get set in + * prvInitialiseNewTimer. */ + pxNewTimer->ucStatus = 0x00; + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const BaseType_t xAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t * pxTimerBuffer ) + { + Timer_t * pxNewTimer; + + #if ( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + * variable of type StaticTimer_t equals the size of the real timer + * structure. */ + volatile size_t xSize = sizeof( StaticTimer_t ); + configASSERT( xSize == sizeof( Timer_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ + configASSERT( pxTimerBuffer ); + pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */ + + if( pxNewTimer != NULL ) + { + /* Timers can be created statically or dynamically so note this + * timer was created statically in case it is later deleted. The + * auto-reload bit may get set in prvInitialiseNewTimer(). */ + pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; + + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const BaseType_t xAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t * pxNewTimer ) + { + /* 0 is not a valid value for xTimerPeriodInTicks. */ + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + /* Ensure the infrastructure used by the timer service task has been + * created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function + * parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + + if( xAutoReload != pdFALSE ) + { + pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } + + traceTIMER_CREATE( pxNewTimer ); + } +/*-----------------------------------------------------------*/ + + BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, + const BaseType_t xCommandID, + const TickType_t xOptionalValue, + BaseType_t * const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait ) + { + BaseType_t xReturn = pdFAIL; + DaemonTaskMessage_t xMessage; + + configASSERT( xTimer ); + + /* Send a message to the timer service task to perform a particular action + * on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; + xMessage.u.xTimerParameters.pxTimer = xTimer; + + if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } +/*-----------------------------------------------------------*/ + + TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) + { + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + * started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; + } +/*-----------------------------------------------------------*/ + + TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) + { + Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->xTimerPeriodInTicks; + } +/*-----------------------------------------------------------*/ + + void vTimerSetReloadMode( TimerHandle_t xTimer, + const BaseType_t xAutoReload ) + { + Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + taskENTER_CRITICAL(); + { + if( xAutoReload != pdFALSE ) + { + pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } + else + { + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_AUTORELOAD ); + } + } + taskEXIT_CRITICAL(); + } +/*-----------------------------------------------------------*/ + + BaseType_t xTimerGetReloadMode( TimerHandle_t xTimer ) + { + Timer_t * pxTimer = xTimer; + BaseType_t xReturn; + + configASSERT( xTimer ); + taskENTER_CRITICAL(); + { + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0 ) + { + /* Not an auto-reload timer. */ + xReturn = pdFALSE; + } + else + { + /* Is an auto-reload timer. */ + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + + UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer ) + { + return ( UBaseType_t ) xTimerGetReloadMode( xTimer ); + } +/*-----------------------------------------------------------*/ + + TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) + { + Timer_t * pxTimer = xTimer; + TickType_t xReturn; + + configASSERT( xTimer ); + xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); + return xReturn; + } +/*-----------------------------------------------------------*/ + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer, + StaticTimer_t ** ppxTimerBuffer ) + { + BaseType_t xReturn; + Timer_t * pxTimer = xTimer; + + configASSERT( ppxTimerBuffer != NULL ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) != 0 ) + { + *ppxTimerBuffer = ( StaticTimer_t * ) pxTimer; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->pcTimerName; + } +/*-----------------------------------------------------------*/ + + static void prvReloadTimer( Timer_t * const pxTimer, + TickType_t xExpiredTime, + const TickType_t xTimeNow ) + { + /* Insert the timer into the appropriate list for the next expiry time. + * If the next expiry time has already passed, advance the expiry time, + * call the callback function, and try again. */ + while( prvInsertTimerInActiveList( pxTimer, ( xExpiredTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xExpiredTime ) != pdFALSE ) + { + /* Advance the expiry time. */ + xExpiredTime += pxTimer->xTimerPeriodInTicks; + + /* Call the timer callback. */ + traceTIMER_EXPIRED( pxTimer ); + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + } + } +/*-----------------------------------------------------------*/ + + static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, + const TickType_t xTimeNow ) + { + Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Remove the timer from the list of active timers. A check has already + * been performed to ensure the list is not empty. */ + + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + + /* If the timer is an auto-reload timer then calculate the next + * expiry time and re-insert the timer in the list of active timers. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + prvReloadTimer( pxTimer, xNextExpireTime, xTimeNow ); + } + else + { + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + + /* Call the timer callback. */ + traceTIMER_EXPIRED( pxTimer ); + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + } +/*-----------------------------------------------------------*/ + + static portTASK_FUNCTION( prvTimerTask, pvParameters ) + { + TickType_t xNextExpireTime; + BaseType_t xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + #if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + { + /* Allow the application writer to execute some code in the context of + * this task at the point the task starts executing. This is useful if the + * application includes initialisation code that would benefit from + * executing after the scheduler has been started. */ + vApplicationDaemonTaskStartupHook(); + } + #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + for( ; ; ) + { + /* Query the timers list to see if it contains any timers, and if so, + * obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + * until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } + } +/*-----------------------------------------------------------*/ + + static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, + BaseType_t xListWasEmpty ) + { + TickType_t xTimeNow; + BaseType_t xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + * has expired or not. If obtaining the time causes the lists to switch + * then don't process this timer as any timers that remained in the list + * when the lists were switched will have been processed within the + * prvSampleTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + * time has not been reached yet. This task should therefore + * block to wait for the next expire time or a command to be + * received - whichever comes first. The following line cannot + * be reached unless xNextExpireTime > xTimeNow, except in the + * case when the current timer list is empty. */ + if( xListWasEmpty != pdFALSE ) + { + /* The current timer list is empty - is the overflow list + * also empty? */ + xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); + } + + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the + * block time to expire. If a command arrived between the + * critical section being exited and this yield then the yield + * will not cause the task to block. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } + } +/*-----------------------------------------------------------*/ + + static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) + { + TickType_t xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + * referencing the task that will expire first. Obtain the time at which + * the timer with the nearest expiry time will expire. If there are no + * active timers then just set the next expire time to 0. That will cause + * this task to unblock when the tick count overflows, at which point the + * timer lists will be switched and the next expiry time can be + * re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( TickType_t ) 0U; + } + + return xNextExpireTime; + } +/*-----------------------------------------------------------*/ + + static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) + { + TickType_t xTimeNow; + PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists(); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; + } +/*-----------------------------------------------------------*/ + + static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, + const TickType_t xNextExpiryTime, + const TickType_t xTimeNow, + const TickType_t xCommandTime ) + { + BaseType_t xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + * timer was issued, and the time the command was processed? */ + if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + { + /* The time between a command being issued and the command being + * processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + * but the expiry time has not, then the timer must have already passed + * its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; + } +/*-----------------------------------------------------------*/ + + static void prvProcessReceivedCommands( void ) + { + DaemonTaskMessage_t xMessage; + Timer_t * pxTimer; + BaseType_t xTimerListsWereSwitched; + TickType_t xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + { + /* Negative commands are pended function calls rather than timer + * commands. */ + if( xMessage.xMessageID < ( BaseType_t ) 0 ) + { + const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); + + /* The timer uses the xCallbackParameters member to request a + * callback be executed. Check the callback is not NULL. */ + configASSERT( pxCallback ); + + /* Call the function. */ + pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* INCLUDE_xTimerPendFunctionCall */ + + /* Commands that are positive are timer commands rather than pended + * function calls. */ + if( xMessage.xMessageID >= ( BaseType_t ) 0 ) + { + /* The messages uses the xTimerParameters member to work on a + * software timer. */ + pxTimer = xMessage.u.xTimerParameters.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + * it must be present in the function call. prvSampleTimeNow() must be + * called after the message is received from xTimerQueue so there is no + * possibility of a higher priority task adding a message to the message + * queue with a time that is ahead of the timer daemon task (because it + * pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START: + case tmrCOMMAND_START_FROM_ISR: + case tmrCOMMAND_RESET: + case tmrCOMMAND_RESET_FROM_ISR: + /* Start or restart a timer. */ + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) + { + /* The timer expired before it was added to the active + * timer list. Process it now. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + prvReloadTimer( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow ); + } + else + { + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + + /* Call the timer callback. */ + traceTIMER_EXPIRED( pxTimer ); + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + break; + + case tmrCOMMAND_STOP: + case tmrCOMMAND_STOP_FROM_ISR: + /* The timer has already been removed from the active list. */ + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + break; + + case tmrCOMMAND_CHANGE_PERIOD: + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can + * be longer or shorter than the old one. The command time is + * therefore set to the current time, and as the period cannot + * be zero the next expiry time can only be in the future, + * meaning (unlike for the xTimerStart() case above) there is + * no fail case that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE: + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* The timer has already been removed from the active list, + * just free up the memory if the memory was dynamically + * allocated. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) + { + vPortFree( pxTimer ); + } + else + { + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + } + #else /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */ + { + /* If dynamic allocation is not enabled, the memory + * could not have been dynamically allocated. So there is + * no need to free the memory - just mark the timer as + * "not active". */ + pxTimer->ucStatus &= ( ( uint8_t ) ~tmrSTATUS_IS_ACTIVE ); + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + break; + + default: + /* Don't expect to get here. */ + break; + } + } + } + } +/*-----------------------------------------------------------*/ + + static void prvSwitchTimerLists( void ) + { + TickType_t xNextExpireTime; + List_t * pxTemp; + + /* The tick count has overflowed. The timer lists must be switched. + * If there are any timers still referenced from the current timer list + * then they must have expired and should be processed before the lists + * are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Process the expired timer. For auto-reload timers, be careful to + * process only expirations that occur on the current list. Further + * expirations must wait until after the lists are switched. */ + prvProcessExpiredTimer( xNextExpireTime, tmrMAX_TIME_BEFORE_OVERFLOW ); + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; + } +/*-----------------------------------------------------------*/ + + static void prvCheckForValidListAndQueue( void ) + { + /* Check that the list from which active timers are referenced, and the + * queue used to communicate with the timer service, have been + * initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + + #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The timer queue is allocated statically in case + * configSUPPORT_DYNAMIC_ALLOCATION is 0. */ + PRIVILEGED_DATA static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + PRIVILEGED_DATA static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + + xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); + } + #else + { + xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); + } + #endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + if( xTimerQueue != NULL ) + { + vQueueAddToRegistry( xTimerQueue, "TmrQ" ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configQUEUE_REGISTRY_SIZE */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } +/*-----------------------------------------------------------*/ + + BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) + { + BaseType_t xReturn; + Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } /*lint !e818 Can't be pointer to const due to the typedef. */ +/*-----------------------------------------------------------*/ + + void * pvTimerGetTimerID( const TimerHandle_t xTimer ) + { + Timer_t * const pxTimer = xTimer; + void * pvReturn; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pvReturn = pxTimer->pvTimerID; + } + taskEXIT_CRITICAL(); + + return pvReturn; + } +/*-----------------------------------------------------------*/ + + void vTimerSetTimerID( TimerHandle_t xTimer, + void * pvNewID ) + { + Timer_t * const pxTimer = xTimer; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pxTimer->pvTimerID = pvNewID; + } + taskEXIT_CRITICAL(); + } +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + void * pvParameter1, + uint32_t ulParameter2, + BaseType_t * pxHigherPriorityTaskWoken ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + * daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + + #endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + void * pvParameter1, + uint32_t ulParameter2, + TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* This function can only be called after a timer has been created or + * after the scheduler has been started because, until then, the timer + * queue does not exist. */ + configASSERT( xTimerQueue ); + + /* Complete the message with the function parameters and post it to the + * daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + + #endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) + { + return ( ( Timer_t * ) xTimer )->uxTimerNumber; + } + + #endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + + #if ( configUSE_TRACE_FACILITY == 1 ) + + void vTimerSetTimerNumber( TimerHandle_t xTimer, + UBaseType_t uxTimerNumber ) + { + ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; + } + + #endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured + * to include software timer functionality. If you want to include software timer + * functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ diff --git a/STM32CubeIDE/.DS_Store b/STM32CubeIDE/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..34c020268abb663117771b8e3cf2da7b04f0ba4f GIT binary patch literal 8196 zcmeHMT}&KR6u#d8?W{~;sA6el+AXvO=#K~*wQ5+p3yOeHe&kOJyE`LH9cJjx?ozEk z#3vK2Mjy1Xz8L@Fi!oa3--|KEH2Pp-iH1J;_f+-8M6J<8&%Jk+mQtQH4T*Efz2}~D z?m73)neWWaSr}v3n=`Lvtco$FQs-1JrQsrt>v><+lt5BU6lBksZTe{^<#`UVVGAP= zMj(tp7=bVXVFXrV1cFOiUE$tejYkg86ho1s5vY5jhl*zxo6l;fosD@vqh9NW(}HlBu3R9v!Vts1$k zR9j~Z4UdeDY2*6(ylu_)%w%oP_3yGWKGAW#+@JDhJJO!po3XflDD649Y1bduE7D0P zopX{|tJQJ(?FTH9mHX+8=QzEdZ*w;z!&&Q4mg|$tOTzFeIVx)0S)6?&RRC zZDyy2^0sfM9BaT$PFs-*?2OEpS8d#MRkdNr1?LP3ONVnQ`(Vz_-mllHs@NlH)M$5` zbck-xZT2)WVg}b#zZQwrJH6yw&CC%FP z#-Ni-Sx!VZHR8s8zHL|1&-Tn%EjaBkndAf@p4Jdy|tNk)>~8# za;0v&c{@vQg5C|0oUhgvKv)~AlhfLdCMU#91iCiXD8&)F5)9VF60D0&unarQjVDGX|*%$0I`+=Qdzp&rgS@tLU3neH;B@A4RI@F^9&4{5DaU{@<5sYFCCTtvl zgK6Y(7!TrMJc7sYB%Z?4cm~Jt5?;oucnxpjeSClq@d-|09$(>We1kLi5kKKq{D!mm zLn&6)DP>BzvQ=qNb|^cQ7A2;1D1FM9GNIV=0hHjbV)sbCFe(RVwluqDWOgaXE}mW0 z?YG_DamOmou7xs@Pghi4xgol};hO6x%NB7bfm*=k`G^-VUy>XG<^l#6Ky+Rtp0;^Q zA=A#~p3KET$`9+1%F|R|8?3I~rc!?BB>`JkPi&{YMzYnrcB_<&x*}Mux~Vxr8K)No z?5c?YTKZnWq;A?B*6?nP94`;|X$dQdj>gSbxS&u?6-m`>J!v? + + STM32H7S78-DK + + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeProjectNature + com.st.stm32cube.ide.mcu.MCUAppliEnabledProjectNature + com.st.stm32cube.ide.mcu.MCUBootEnabledProjectNature + com.st.stm32cube.ide.mcu.MCURootBootProjectNature + com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature + + + + STM32H7S78-DK.ioc + 1 + PARENT-1-PROJECT_LOC/STM32H7S78-DK.ioc + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_cortex.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma_ex.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_exti.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_flash.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_flash_ex.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_gpio.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_i2s.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_mdf.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_pwr.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_pwr_ex.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_rcc.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_rcc_ex.c + 1 + PARENT-1-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_uart.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_uart.c + + + diff --git a/STM32CubeIDE/Appli/.DS_Store b/STM32CubeIDE/Appli/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0dbc01dee0302007465254e7d4bd186cd92bf642 GIT binary patch literal 6148 zcmeHKOKQVF43$zt1KoJpsj*UZAwjq7Vqwv}><&t{g2-A4?E6sQhBa{s^iKzZj{v|9X*aBW zmH-w@0BhnBhzv}F3Jj{|h@nA8zGPiZTmpkGn!|_Y$(j?2`ssLo@p91`$VdgKz@-8Y zvF)w@Z{dH;|Cc20r~noCR|;r1zKjE|l)bgNob}oQe}!Ak32uh9QxLoz1HBz%W9|6a ci=wXB8qaIu66kc~oet#BfayY`0{2$n3`m(3hX4Qo literal 0 HcmV?d00001 diff --git a/STM32CubeIDE/Appli/.cproject b/STM32CubeIDE/Appli/.cproject new file mode 100644 index 0000000..db4b5fa --- /dev/null +++ b/STM32CubeIDE/Appli/.cproject @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/STM32CubeIDE/Appli/.project b/STM32CubeIDE/Appli/.project new file mode 100644 index 0000000..41ca2ab --- /dev/null +++ b/STM32CubeIDE/Appli/.project @@ -0,0 +1,594 @@ + + + STM32H7S78-DK_Appli + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeProjectNature + com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature + com.st.stm32cube.ide.mcu.MCUAppliProjectNature + com.st.stm32cube.ide.mcu.MCUNonSecureProjectNature + com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.st.stm32cube.ide.mcu.MCUMultiLinkerEnabledProjectNature + com.st.stm32cube.ide.mcu.MCUBootModeEnabledProjectNature + + + + stm32h7rsxx_RAMxspi1_ROMxspi2.ld + 1 + PARENT-2-PROJECT_LOC/Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld + + + Drivers/audio.h + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/Components/Common/audio.h + + + Drivers/stm32h7s78_discovery.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.c + + + Drivers/stm32h7s78_discovery.h + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery.h + + + Drivers/stm32h7s78_discovery_audio.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.c + + + Drivers/stm32h7s78_discovery_audio.h + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_audio.h + + + Drivers/stm32h7s78_discovery_bus.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.c + + + Drivers/stm32h7s78_discovery_bus.h + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/STM32H7S78-DK/stm32h7s78_discovery_bus.h + + + Drivers/wm8904.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.c + + + Drivers/wm8904.h + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904.h + + + Drivers/wm8904_reg.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.c + + + Drivers/wm8904_reg.h + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_BSP/Components/wm8904/wm8904_reg.h + + + Drivers/CMSIS/system_stm32h7rsxx.c + 1 + PARENT-2-PROJECT_LOC/Appli/Core/Src/system_stm32h7rsxx.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_cortex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_crc.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_crc_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma2d.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_exti.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_flash.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_flash_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_gpio.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_gpu2d.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_i2c.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_i2c_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_i2s.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2s.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_icache.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_jpeg.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_ltdc.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_ltdc_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_mdf.c + 1 + /Users/thomas/Documents/Codes/STM32/CelloEffects/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_mdf.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_pwr.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_pwr_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_rcc.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_rcc_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_smbus.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_smbus_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_tim.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_tim_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c + + + Middlewares/FreeRTOS/cmsis_os2.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c + + + Middlewares/FreeRTOS/croutine.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/croutine.c + + + Middlewares/FreeRTOS/event_groups.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c + + + Middlewares/FreeRTOS/heap_4.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c + + + Middlewares/FreeRTOS/list.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/list.c + + + Middlewares/FreeRTOS/mpu_wrappers.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers.c + + + Middlewares/FreeRTOS/mpu_wrappers_v2.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/portable/Common/mpu_wrappers_v2.c + + + Middlewares/FreeRTOS/port.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c + + + Middlewares/FreeRTOS/queue.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/queue.c + + + Middlewares/FreeRTOS/stream_buffer.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/stream_buffer.c + + + Middlewares/FreeRTOS/tasks.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/tasks.c + + + Middlewares/FreeRTOS/timers.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/Third_Party/FreeRTOS/Source/timers.c + + + Application/User/Core/freertos.c + 1 + PARENT-2-PROJECT_LOC/Appli/Core/Src/freertos.c + + + Application/User/Core/main.c + 1 + PARENT-2-PROJECT_LOC/Appli/Core/Src/main.c + + + Application/User/Core/stm32h7rsxx_hal_msp.c + 1 + PARENT-2-PROJECT_LOC/Appli/Core/Src/stm32h7rsxx_hal_msp.c + + + Application/User/Core/stm32h7rsxx_hal_timebase_tim.c + 1 + PARENT-2-PROJECT_LOC/Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c + + + Application/User/Core/stm32h7rsxx_it.c + 1 + PARENT-2-PROJECT_LOC/Appli/Core/Src/stm32h7rsxx_it.c + + + Application/User/generated/ApplicationFontProvider.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/ApplicationFontProvider.cpp + + + Application/User/generated/BitmapDatabase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/BitmapDatabase.cpp + + + Application/User/generated/CachedFont.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/CachedFont.cpp + + + Application/User/generated/CompressedFontCache.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/CompressedFontCache.cpp + + + Application/User/generated/CompressedUnmappedFontCache.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/CompressedUnmappedFontCache.cpp + + + Application/User/generated/FontCache.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/FontCache.cpp + + + Application/User/generated/Font_arial_10_4bpp_0.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Font_arial_10_4bpp_0.cpp + + + Application/User/generated/Font_arial_20_4bpp_0.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Font_arial_20_4bpp_0.cpp + + + Application/User/generated/Font_arial_40_4bpp_0.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Font_arial_40_4bpp_0.cpp + + + Application/User/generated/FrontendApplicationBase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/gui_generated/src/common/FrontendApplicationBase.cpp + + + Application/User/generated/GeneratedFont.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/GeneratedFont.cpp + + + Application/User/generated/InitScreenViewBase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/gui_generated/src/initscreen_screen/InitScreenViewBase.cpp + + + Application/User/generated/Kerning_arial_10_4bpp.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Kerning_arial_10_4bpp.cpp + + + Application/User/generated/Kerning_arial_20_4bpp.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Kerning_arial_20_4bpp.cpp + + + Application/User/generated/Kerning_arial_40_4bpp.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Kerning_arial_40_4bpp.cpp + + + Application/User/generated/LanguageGb.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/texts/src/LanguageGb.cpp + + + Application/User/generated/SVGDatabase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/SVGDatabase.cpp + + + Application/User/generated/Screen1ViewBase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/gui_generated/src/screen1_screen/Screen1ViewBase.cpp + + + Application/User/generated/Table_arial_10_4bpp.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Table_arial_10_4bpp.cpp + + + Application/User/generated/Table_arial_20_4bpp.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Table_arial_20_4bpp.cpp + + + Application/User/generated/Table_arial_40_4bpp.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/Table_arial_40_4bpp.cpp + + + Application/User/generated/Texts.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/texts/src/Texts.cpp + + + Application/User/generated/TypedTextDatabase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/texts/src/TypedTextDatabase.cpp + + + Application/User/generated/UnmappedDataFont.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/UnmappedDataFont.cpp + + + Application/User/generated/VectorFontRendererBuffers.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/fonts/src/VectorFontRendererBuffers.cpp + + + Application/User/generated/image_alternate_theme_images_backgrounds_800x480_meteor_rain.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_backgrounds_800x480_meteor_rain.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_button_regular_height_50_medium_rounded_normal.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_button_regular_height_50_medium_rounded_normal.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_button_regular_height_50_medium_rounded_pressed.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_button_regular_height_50_medium_rounded_pressed.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_gauge_medium_backgrounds_active.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_gauge_medium_backgrounds_active.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_gauge_medium_needles_smooth.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_gauge_medium_needles_smooth.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_slider_horizontal_thick_filler_medium.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_slider_horizontal_thick_filler_medium.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_slider_horizontal_thick_rounded_dark.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_slider_horizontal_thick_rounded_dark.cpp + + + Application/User/generated/image_alternate_theme_images_widgets_slider_horizontal_thick_track_medium.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_alternate_theme_images_widgets_slider_horizontal_thick_track_medium.cpp + + + Application/User/generated/image_glass_theme_images_backgrounds_800x480_gradient_rainbow.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_glass_theme_images_backgrounds_800x480_gradient_rainbow.cpp + + + Application/User/generated/image_icon_theme_images_action_done_50_50_E8F6FB.svg.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_icon_theme_images_action_done_50_50_E8F6FB.svg.cpp + + + Application/User/generated/image_icon_theme_images_action_input_50_50_E8F6FB.svg.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/images/src/__generated/image_icon_theme_images_action_input_50_50_E8F6FB.svg.cpp + + + Application/User/gui/FrontendApplication.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/common/FrontendApplication.cpp + + + Application/User/gui/InitScreenPresenter.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenPresenter.cpp + + + Application/User/gui/InitScreenView.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/initscreen_screen/InitScreenView.cpp + + + Application/User/gui/Model.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/model/Model.cpp + + + Application/User/gui/Screen1Presenter.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/screen1_screen/Screen1Presenter.cpp + + + Application/User/gui/Screen1View.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/screen1_screen/Screen1View.cpp + + + Application/User/TouchGFX/App/app_touchgfx.c + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/App/app_touchgfx.c + + + Application/User/TouchGFX/target/CortexMMCUInstrumentation.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/CortexMMCUInstrumentation.cpp + + + Application/User/TouchGFX/target/STM32TouchController.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/STM32TouchController.cpp + + + Application/User/TouchGFX/target/TouchGFXGPIO.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/TouchGFXGPIO.cpp + + + Application/User/TouchGFX/target/TouchGFXHAL.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/TouchGFXHAL.cpp + + + Application/User/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/generated/HardwareMJPEGDecoder.cpp + + + Application/User/TouchGFX/target/generated/OSWrappers.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/generated/OSWrappers.cpp + + + Application/User/TouchGFX/target/generated/STM32DMA.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/generated/STM32DMA.cpp + + + Application/User/TouchGFX/target/generated/TouchGFXConfiguration.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/generated/TouchGFXConfiguration.cpp + + + Application/User/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/generated/TouchGFXGeneratedHAL.cpp + + + Application/User/TouchGFX/target/generated/nema_hal.c + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/target/generated/nema_hal.c + + + diff --git a/STM32CubeIDE/Appli/Application/User/Core/syscalls.c b/STM32CubeIDE/Appli/Application/User/Core/syscalls.c new file mode 100644 index 0000000..c6f50f2 --- /dev/null +++ b/STM32CubeIDE/Appli/Application/User/Core/syscalls.c @@ -0,0 +1,176 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 +#include +#include +#include +#include +#include +#include +#include + + +/* Variables */ +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + + +char *__env[1] = { 0 }; +char **environ = __env; + + +/* Functions */ +void initialise_monitor_handles() +{ +} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit (int status) +{ + _kill(status, -1); + while (1) {} /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + (void)file; + return -1; +} + + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/STM32CubeIDE/Appli/Application/User/Core/sysmem.c b/STM32CubeIDE/Appli/Application/User/Core/sysmem.c new file mode 100644 index 0000000..17a2c3a --- /dev/null +++ b/STM32CubeIDE/Appli/Application/User/Core/sysmem.c @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Generated by STM32CubeIDE + * @brief STM32CubeIDE System Memory calls file + * + * For more information about which C functions + * need which of these lowlevel functions + * please consult the newlib libc manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc + * and others from the C library + * + * @verbatim + * ############################################################################ + * # .data # .bss # newlib heap # MSP stack # + * # # # # Reserved by _Min_Stack_Size # + * ############################################################################ + * ^-- RAM start ^-- _end _estack, RAM end --^ + * @endverbatim + * + * This implementation starts allocating at the '_end' linker symbol + * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack + * The implementation considers '_estack' linker symbol to be RAM end + * NOTE: If the MSP stack, at any point during execution, grows larger than the + * reserved size, please increase the '_Min_Stack_Size'. + * + * @param incr Memory size + * @return Pointer to allocated memory + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + const uint8_t *max_heap = (uint8_t *)stack_limit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) + { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into the reserved MSP stack */ + if (__sbrk_heap_end + incr > max_heap) + { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/STM32CubeIDE/Appli/Application/User/Startup/startup_stm32h7s7l8hxh.s b/STM32CubeIDE/Appli/Application/User/Startup/startup_stm32h7s7l8hxh.s new file mode 100644 index 0000000..e6124df --- /dev/null +++ b/STM32CubeIDE/Appli/Application/User/Startup/startup_stm32h7s7l8hxh.s @@ -0,0 +1,780 @@ +/** + ****************************************************************************** + * @file startup_stm32h7s7xx.s + * @author MCD Application Team + * @brief STM32H7S7xx Devices vector table for 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 + * - 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-m7 + .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 STM32H7S7xx 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 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + /* External Interrupts */ + .word PVD_PVM_IRQHandler /* PVD/PVM through EXTI Line detection */ + .word 0 /* Reserved */ + .word DTS_IRQHandler /* Digital Temperature Sensor */ + .word IWDG_IRQHandler /* Internal Watchdog */ + .word WWDG_IRQHandler /* Window Watchdog */ + .word RCC_IRQHandler /* RCC global interrupts through EXTI Line detection */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FLASH_IRQHandler /* FLASH interrupts */ + .word RAMECC_IRQHandler /* RAMECC interrupts */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word TAMP_IRQHandler /* Tamper and TimeStamp interrupts */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word EXTI5_IRQHandler /* EXTI Line5 */ + .word EXTI6_IRQHandler /* EXTI Line6 */ + .word EXTI7_IRQHandler /* EXTI Line7 */ + .word EXTI8_IRQHandler /* EXTI Line8 */ + .word EXTI9_IRQHandler /* EXTI Line9 */ + .word EXTI10_IRQHandler /* EXTI Line10 */ + .word EXTI11_IRQHandler /* EXTI Line11 */ + .word EXTI12_IRQHandler /* EXTI Line12 */ + .word EXTI13_IRQHandler /* EXTI Line13 */ + .word EXTI14_IRQHandler /* EXTI Line14 */ + .word EXTI15_IRQHandler /* EXTI Line15 */ + .word RTC_IRQHandler /* RTC wakeup and alarm interrupts */ + .word SAES_IRQHandler /* SAES */ + .word CRYP_IRQHandler /* CRYP */ + .word PKA_IRQHandler /* PKA */ + .word HASH_IRQHandler /* HASH */ + .word RNG_IRQHandler /* RNG */ + .word ADC1_2_IRQHandler /* ADC1 & ADC2 */ + .word GPDMA1_Channel0_IRQHandler /* GPDMA1 Channel 0 */ + .word GPDMA1_Channel1_IRQHandler /* GPDMA1 Channel 1 */ + .word GPDMA1_Channel2_IRQHandler /* GPDMA1 Channel 2 */ + .word GPDMA1_Channel3_IRQHandler /* GPDMA1 Channel 3 */ + .word GPDMA1_Channel4_IRQHandler /* GPDMA1 Channel 4 */ + .word GPDMA1_Channel5_IRQHandler /* GPDMA1 Channel 5 */ + .word GPDMA1_Channel6_IRQHandler /* GPDMA1 Channel 6 */ + .word GPDMA1_Channel7_IRQHandler /* GPDMA1 Channel 7 */ + .word TIM1_BRK_IRQHandler /* TIM1 Break */ + .word TIM1_UP_IRQHandler /* TIM1 Update */ + .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word TIM5_IRQHandler /* TIM5 */ + .word TIM6_IRQHandler /* TIM6 */ + .word TIM7_IRQHandler /* TIM7 */ + .word TIM9_IRQHandler /* TIM9 */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word SPI3_IRQHandler /* SPI3 */ + .word SPI4_IRQHandler /* SPI4 */ + .word SPI5_IRQHandler /* SPI5 */ + .word SPI6_IRQHandler /* SPI6 */ + .word HPDMA1_Channel0_IRQHandler /* HPDMA1 Channel 0 */ + .word HPDMA1_Channel1_IRQHandler /* HPDMA1 Channel 1 */ + .word HPDMA1_Channel2_IRQHandler /* HPDMA1 Channel 2 */ + .word HPDMA1_Channel3_IRQHandler /* HPDMA1 Channel 3 */ + .word HPDMA1_Channel4_IRQHandler /* HPDMA1 Channel 4 */ + .word HPDMA1_Channel5_IRQHandler /* HPDMA1 Channel 5 */ + .word HPDMA1_Channel6_IRQHandler /* HPDMA1 Channel 6 */ + .word HPDMA1_Channel7_IRQHandler /* HPDMA1 Channel 7 */ + .word SAI1_A_IRQHandler /* Serial Audio Interface 1 block A */ + .word SAI1_B_IRQHandler /* Serial Audio Interface 1 block B */ + .word SAI2_A_IRQHandler /* Serial Audio Interface 2 block A */ + .word SAI2_B_IRQHandler /* Serial Audio Interface 2 block B */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word I2C3_EV_IRQHandler /* I2C3 Event */ + .word I2C3_ER_IRQHandler /* I2C3 Error */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word UART7_IRQHandler /* UART7 */ + .word UART8_IRQHandler /* UART8 */ + .word I3C1_EV_IRQHandler /* I3C1 Event */ + .word I3C1_ER_IRQHandler /* I3C1 Error */ + .word OTG_HS_IRQHandler /* USB OTG HS */ + .word ETH_IRQHandler /* Ethernet */ + .word CORDIC_IRQHandler /* CORDIC */ + .word GFXTIM_IRQHandler /* GFXTIM */ + .word DCMIPP_IRQHandler /* DCMIPP */ + .word LTDC_IRQHandler /* LTDC */ + .word LTDC_ER_IRQHandler /* LTDC error */ + .word DMA2D_IRQHandler /* DMA2D */ + .word JPEG_IRQHandler /* JPEG */ + .word GFXMMU_IRQHandler /* GFXMMU */ + .word I3C1_WKUP_IRQHandler /* I3C1 wakeup */ + .word MCE1_IRQHandler /* MCE1 */ + .word MCE2_IRQHandler /* MCE2 */ + .word MCE3_IRQHandler /* MCE3 */ + .word XSPI1_IRQHandler /* XSPI1 */ + .word XSPI2_IRQHandler /* XSPI2 */ + .word FMC_IRQHandler /* FMC */ + .word SDMMC1_IRQHandler /* SDMMC1 */ + .word SDMMC2_IRQHandler /* SDMMC2 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word TIM12_IRQHandler /* TIM12 */ + .word TIM13_IRQHandler /* TIM13 */ + .word TIM14_IRQHandler /* TIM14 */ + .word TIM15_IRQHandler /* TIM15 */ + .word TIM16_IRQHandler /* TIM16 */ + .word TIM17_IRQHandler /* TIM17 */ + .word LPTIM1_IRQHandler /* LP TIM1 */ + .word LPTIM2_IRQHandler /* LP TIM2 */ + .word LPTIM3_IRQHandler /* LP TIM3 */ + .word LPTIM4_IRQHandler /* LP TIM4 */ + .word LPTIM5_IRQHandler /* LP TIM5 */ + .word SPDIF_RX_IRQHandler /* SPDIF_RX */ + .word MDIOS_IRQHandler /* MDIOS */ + .word ADF1_FLT0_IRQHandler /* ADF1 Filter 0 */ + .word CRS_IRQHandler /* CRS */ + .word UCPD1_IRQHandler /* UCPD1 */ + .word CEC_IRQHandler /* HDMI_CEC */ + .word PSSI_IRQHandler /* PSSI */ + .word LPUART1_IRQHandler /* LP UART1 */ + .word WAKEUP_PIN_IRQHandler /* Wake-up pins interrupt */ + .word GPDMA1_Channel8_IRQHandler /* GPDMA1 Channel 8 */ + .word GPDMA1_Channel9_IRQHandler /* GPDMA1 Channel 9 */ + .word GPDMA1_Channel10_IRQHandler /* GPDMA1 Channel 10 */ + .word GPDMA1_Channel11_IRQHandler /* GPDMA1 Channel 11 */ + .word GPDMA1_Channel12_IRQHandler /* GPDMA1 Channel 12 */ + .word GPDMA1_Channel13_IRQHandler /* GPDMA1 Channel 13 */ + .word GPDMA1_Channel14_IRQHandler /* GPDMA1 Channel 14 */ + .word GPDMA1_Channel15_IRQHandler /* GPDMA1 Channel 15 */ + .word HPDMA1_Channel8_IRQHandler /* HPDMA1 Channel 8 */ + .word HPDMA1_Channel9_IRQHandler /* HPDMA1 Channel 9 */ + .word HPDMA1_Channel10_IRQHandler /* HPDMA1 Channel 10 */ + .word HPDMA1_Channel11_IRQHandler /* HPDMA1 Channel 11 */ + .word HPDMA1_Channel12_IRQHandler /* HPDMA1 Channel 12 */ + .word HPDMA1_Channel13_IRQHandler /* HPDMA1 Channel 13 */ + .word HPDMA1_Channel14_IRQHandler /* HPDMA1 Channel 14 */ + .word HPDMA1_Channel15_IRQHandler /* HPDMA1 Channel 15 */ + .word GPU2D_IRQHandler /* GPU2D */ + .word GPU2D_ER_IRQHandler /* GPU2D error */ + .word ICACHE_IRQHandler /* ICACHE */ + .word FDCAN1_IT0_IRQHandler /* FDCAN1 Interrupt 0 */ + .word FDCAN1_IT1_IRQHandler /* FDCAN1 Interrupt 1 */ + .word FDCAN2_IT0_IRQHandler /* FDCAN2 Interrupt 0 */ + .word FDCAN2_IT1_IRQHandler /* FDCAN2 Interrupt 1 */ + +/******************************************************************************* +* +* 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 PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RAMECC_IRQHandler + .thumb_set RAMECC_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_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 RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak SAES_IRQHandler + .thumb_set SAES_IRQHandler,Default_Handler + + .weak CRYP_IRQHandler + .thumb_set CRYP_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak ADC1_2_IRQHandler + .thumb_set ADC1_2_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 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 TIM9_IRQHandler + .thumb_set TIM9_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 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 HPDMA1_Channel0_IRQHandler + .thumb_set HPDMA1_Channel0_IRQHandler,Default_Handler + + .weak HPDMA1_Channel1_IRQHandler + .thumb_set HPDMA1_Channel1_IRQHandler,Default_Handler + + .weak HPDMA1_Channel2_IRQHandler + .thumb_set HPDMA1_Channel2_IRQHandler,Default_Handler + + .weak HPDMA1_Channel3_IRQHandler + .thumb_set HPDMA1_Channel3_IRQHandler,Default_Handler + + .weak HPDMA1_Channel4_IRQHandler + .thumb_set HPDMA1_Channel4_IRQHandler,Default_Handler + + .weak HPDMA1_Channel5_IRQHandler + .thumb_set HPDMA1_Channel5_IRQHandler,Default_Handler + + .weak HPDMA1_Channel6_IRQHandler + .thumb_set HPDMA1_Channel6_IRQHandler,Default_Handler + + .weak HPDMA1_Channel7_IRQHandler + .thumb_set HPDMA1_Channel7_IRQHandler,Default_Handler + + .weak SAI1_A_IRQHandler + .thumb_set SAI1_A_IRQHandler,Default_Handler + + .weak SAI1_B_IRQHandler + .thumb_set SAI1_B_IRQHandler,Default_Handler + + .weak SAI2_A_IRQHandler + .thumb_set SAI2_A_IRQHandler,Default_Handler + + .weak SAI2_B_IRQHandler + .thumb_set SAI2_B_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 I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_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 UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_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 OTG_HS_IRQHandler + .thumb_set OTG_HS_IRQHandler,Default_Handler + + .weak ETH_IRQHandler + .thumb_set ETH_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak GFXTIM_IRQHandler + .thumb_set GFXTIM_IRQHandler,Default_Handler + + .weak DCMIPP_IRQHandler + .thumb_set DCMIPP_IRQHandler,Default_Handler + + .weak LTDC_IRQHandler + .thumb_set LTDC_IRQHandler,Default_Handler + + .weak LTDC_ER_IRQHandler + .thumb_set LTDC_ER_IRQHandler,Default_Handler + + .weak DMA2D_IRQHandler + .thumb_set DMA2D_IRQHandler,Default_Handler + + .weak JPEG_IRQHandler + .thumb_set JPEG_IRQHandler,Default_Handler + + .weak GFXMMU_IRQHandler + .thumb_set GFXMMU_IRQHandler,Default_Handler + + .weak I3C1_WKUP_IRQHandler + .thumb_set I3C1_WKUP_IRQHandler,Default_Handler + + .weak MCE1_IRQHandler + .thumb_set MCE1_IRQHandler,Default_Handler + + .weak MCE2_IRQHandler + .thumb_set MCE2_IRQHandler,Default_Handler + + .weak MCE3_IRQHandler + .thumb_set MCE3_IRQHandler,Default_Handler + + .weak XSPI1_IRQHandler + .thumb_set XSPI1_IRQHandler,Default_Handler + + .weak XSPI2_IRQHandler + .thumb_set XSPI2_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_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 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 LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_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 SPDIF_RX_IRQHandler + .thumb_set SPDIF_RX_IRQHandler,Default_Handler + + .weak MDIOS_IRQHandler + .thumb_set MDIOS_IRQHandler,Default_Handler + + .weak ADF1_FLT0_IRQHandler + .thumb_set ADF1_FLT0_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak PSSI_IRQHandler + .thumb_set PSSI_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak WAKEUP_PIN_IRQHandler + .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler + + .weak GPDMA1_Channel8_IRQHandler + .thumb_set GPDMA1_Channel8_IRQHandler,Default_Handler + + .weak GPDMA1_Channel9_IRQHandler + .thumb_set GPDMA1_Channel9_IRQHandler,Default_Handler + + .weak GPDMA1_Channel10_IRQHandler + .thumb_set GPDMA1_Channel10_IRQHandler,Default_Handler + + .weak GPDMA1_Channel11_IRQHandler + .thumb_set GPDMA1_Channel11_IRQHandler,Default_Handler + + .weak GPDMA1_Channel12_IRQHandler + .thumb_set GPDMA1_Channel12_IRQHandler,Default_Handler + + .weak GPDMA1_Channel13_IRQHandler + .thumb_set GPDMA1_Channel13_IRQHandler,Default_Handler + + .weak GPDMA1_Channel14_IRQHandler + .thumb_set GPDMA1_Channel14_IRQHandler,Default_Handler + + .weak GPDMA1_Channel15_IRQHandler + .thumb_set GPDMA1_Channel15_IRQHandler,Default_Handler + + .weak HPDMA1_Channel8_IRQHandler + .thumb_set HPDMA1_Channel8_IRQHandler,Default_Handler + + .weak HPDMA1_Channel9_IRQHandler + .thumb_set HPDMA1_Channel9_IRQHandler,Default_Handler + + .weak HPDMA1_Channel10_IRQHandler + .thumb_set HPDMA1_Channel10_IRQHandler,Default_Handler + + .weak HPDMA1_Channel11_IRQHandler + .thumb_set HPDMA1_Channel11_IRQHandler,Default_Handler + + .weak HPDMA1_Channel12_IRQHandler + .thumb_set HPDMA1_Channel12_IRQHandler,Default_Handler + + .weak HPDMA1_Channel13_IRQHandler + .thumb_set HPDMA1_Channel13_IRQHandler,Default_Handler + + .weak HPDMA1_Channel14_IRQHandler + .thumb_set HPDMA1_Channel14_IRQHandler,Default_Handler + + .weak HPDMA1_Channel15_IRQHandler + .thumb_set HPDMA1_Channel15_IRQHandler,Default_Handler + + .weak GPU2D_IRQHandler + .thumb_set GPU2D_IRQHandler,Default_Handler + + .weak GPU2D_ER_IRQHandler + .thumb_set GPU2D_ER_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_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 FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak SystemInit \ No newline at end of file diff --git a/STM32CubeIDE/Appli/Drivers/.DS_Store b/STM32CubeIDE/Appli/Drivers/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ea52b7aacbf4ade900f363087d5b6b92374a6111 GIT binary patch literal 6148 zcmeHKu}VWh5S-N%0h?4}dB30*wr6;Pg*L`s(O3w9KtxITI)B^Qy%l^sEz($oS=gJq zy`4L5innh8*!+EY3d{gZ>5lmHVQjwdKC*+17?I91&Tx$j++l(3DEs$-bB~#Sk6WA% z_**>iv`gF&J8bZZ54>Qre0yF!t=B6j%A|l4kOERb3P^#S7041gJ=&Qmf)tPf`>ue0 z9}3;ECiV^E)4?HH0OEwv1c+iRZ5pZ2(Qs6%n_yW5L7jggq literal 0 HcmV?d00001 diff --git a/STM32CubeIDE/Appli/STM32H7S78-DK_Appli.launch b/STM32CubeIDE/Appli/STM32H7S78-DK_Appli.launch new file mode 100644 index 0000000..c7408a7 --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S78-DK_Appli.launch @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_OEMiROT_Appli.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_OEMiROT_Appli.ld new file mode 100644 index 0000000..8fde9cb --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_OEMiROT_Appli.ld @@ -0,0 +1,236 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32H7S78-DK Board embedding STM32H7S7L8HxH Device from stm32h7 series +** 64KBytes FLASH +** 456KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +CODE_OFFSET = 0x0; /* This define is updated automatically by OEMiROT_Boot postbuild */ +CODE_SIZE = 0x200000; /* This define is updated automatically by OEMiROT_Boot postbuild */ +PARTITION_START = 0x70000000; /* This define is updated automatically by OEMiROT_Boot postbuild */ +IMAGE_HEADER_SIZE = 0x400; /* mcuboot header size */ + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = PARTITION_START + CODE_OFFSET + IMAGE_HEADER_SIZE; +__FLASH_SIZE = CODE_SIZE - IMAGE_HEADER_SIZE; +__EXTRAM_BEGIN = 0x70000000; +__EXTRAM_SIZE = 0x00400000; + + +__RAM = 0x30004000; +__RAM_SIZE = 0x4000; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; +__RAM_CONF_FLAG_SIZE = 0x20; +__RAM_RAMECC_HANDLER_SIZE = 0x40; +__RAM_NONCACHEABLEBUFFER = __RAM + __RAM_SIZE - __RAM_NONCACHEABLEBUFFER_SIZE - __RAM_CONF_FLAG_SIZE - __RAM_RAMECC_HANDLER_SIZE; +__RAM_CONF_FLAG = __RAM_NONCACHEABLEBUFFER + __RAM_NONCACHEABLEBUFFER_SIZE; +__RAM_RAMECC_HANDLER = __RAM_NONCACHEABLEBUFFER + __RAM_CONF_FLAG_SIZE; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM, LENGTH = __RAM_SIZE -__RAM_NONCACHEABLEBUFFER_SIZE -__RAM_CONF_FLAG_SIZE -__RAM_RAMECC_HANDLER_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_NONCACHEABLEBUFFER, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + CONF_FLAG (rw) : ORIGIN = __RAM_CONF_FLAG, LENGTH = __RAM_CONF_FLAG_SIZE + RAMECC_HANDLER (rw) : ORIGIN = __RAM_RAMECC_HANDLER, LENGTH = __RAM_RAMECC_HANDLER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 4K + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 4K + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE + EXTRAM (rw) : ORIGIN = __EXTRAM_BEGIN,LENGTH = __EXTRAM_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + .flag (NOLOAD): + { + . = ALIGN(4); + KEEP(*(.flag)) + . = ALIGN(4); + } > CONF_FLAG + + .ramecchandlernoinit (NOLOAD): + { + . = ALIGN(4); + *(.ramecchandlernoinit) + . = ALIGN(4); + } > RAMECC_HANDLER + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_RAMxspi1_ROMxspi2.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_RAMxspi1_ROMxspi2.ld new file mode 100644 index 0000000..906281c --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_RAMxspi1_ROMxspi2.ld @@ -0,0 +1,212 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 128KBytes FLASH +** 456KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x70000000; +__FLASH_SIZE = 0x08000000; +__EXTRAM_BEGIN = 0x90000000; +__EXTRAM_SIZE = 0x02000000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x71C00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE + EXTRAM (rw) : ORIGIN = __EXTRAM_BEGIN, LENGTH = __EXTRAM_SIZE +} + + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" FLASH type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" FLASH type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" FLASH type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1.ld new file mode 100644 index 0000000..65a3fff --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1.ld @@ -0,0 +1,208 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 128KBytes FLASH +** 456KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x90000000; +__FLASH_SIZE = 0x08000000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x71C00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" FLASH type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" FLASH type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" FLASH type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1_RAMxspi2.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1_RAMxspi2.ld new file mode 100644 index 0000000..b476653 --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi1_RAMxspi2.ld @@ -0,0 +1,211 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 128KBytes FLASH +** 456KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x90000000; +__FLASH_SIZE = 0x08000000; +__EXTRAM_BEGIN = 0x70000000; +__EXTRAM_SIZE = 0x02000000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x71C00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE + EXTRAM (rw) : ORIGIN = __EXTRAM_BEGIN, LENGTH = __EXTRAM_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" FLASH type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" FLASH type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" FLASH type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi2.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi2.ld new file mode 100644 index 0000000..ae5326d --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_ROMxspi2.ld @@ -0,0 +1,208 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 128KBytes FLASH +** 456KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x70000000; +__FLASH_SIZE = 0x08000000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x71C00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" FLASH type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" FLASH type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" FLASH type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_STiROT_Appli.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_STiROT_Appli.ld new file mode 100644 index 0000000..a380c1f --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_STiROT_Appli.ld @@ -0,0 +1,214 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for STM32H7RS series +** 128KBytes FLASH +** 456KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +CODE_OFFSET = 0x24000000; /* Firmware execution area offset from STiROT_Config.xml */ +CODE_SIZE = 0x20000; /* Firmware execution area size from STiROT_Config.xml */ +IMAGE_HEADER_SIZE = 0x400; /* mcuboot header size */ + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x70000000; +__FLASH_SIZE = 0x08000000; +__EXTRAM_BEGIN = 0x90000000; +__EXTRAM_SIZE = 0x00400000; + + +__RAM = 0x30004000; +__RAM_SIZE = 0x4000; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM, LENGTH = __RAM_SIZE -__RAM_NONCACHEABLEBUFFER_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM + __RAM_SIZE - __RAM_NONCACHEABLEBUFFER_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + ROM (rx) : ORIGIN = CODE_OFFSET + IMAGE_HEADER_SIZE, LENGTH = CODE_SIZE - IMAGE_HEADER_SIZE + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 64K + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE + EXTRAM (rw) : ORIGIN = __EXTRAM_BEGIN,LENGTH = __EXTRAM_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >ROM + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >ROM + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >ROM + + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >ROM + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >ROM + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >ROM + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >DTCM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >DTCM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_default.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_default.ld new file mode 100644 index 0000000..44678b6 --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_default.ld @@ -0,0 +1,208 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 64Kbytes FLASH +** 456Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x08000000; +__FLASH_SIZE = 0x00010000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x71C00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Appli/STM32H7S7L8HXH_sram.ld b/STM32CubeIDE/Appli/STM32H7S7L8HXH_sram.ld new file mode 100644 index 0000000..d4e17c1 --- /dev/null +++ b/STM32CubeIDE/Appli/STM32H7S7L8HXH_sram.ld @@ -0,0 +1,209 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 128KBytes FLASH +** 456Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +******************************************************************************* +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + + +__ROM_BEGIN = 0x24050000; +__ROM_SIZE = 0x00022000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x0004FC00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + ROM (xrw) : ORIGIN = __ROM_BEGIN, LENGTH = __ROM_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >ROM + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >ROM + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >ROM + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >ROM + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >ROM + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >ROM + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >ROM + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >ROM + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> ROM + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough "DTCM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/Boot/.cproject b/STM32CubeIDE/Boot/.cproject new file mode 100644 index 0000000..4c82826 --- /dev/null +++ b/STM32CubeIDE/Boot/.cproject @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/STM32CubeIDE/Boot/.project b/STM32CubeIDE/Boot/.project new file mode 100644 index 0000000..a7819d7 --- /dev/null +++ b/STM32CubeIDE/Boot/.project @@ -0,0 +1,177 @@ + + + STM32H7S78-DK_Boot + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUNonUnderRootProjectNature + com.st.stm32cube.ide.mcu.MCUCubeProjectNature + com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature + com.st.stm32cube.ide.mcu.MCUBootProjectNature + com.st.stm32cube.ide.mcu.MCUNonSecureProjectNature + com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + stm32h7s7xx_flash.ld + 1 + PARENT-2-PROJECT_LOC/Boot/stm32h7s7xx_flash.ld + + + Drivers/CMSIS/system_stm32h7rsxx.c + 1 + PARENT-2-PROJECT_LOC/Boot/Core/Src/system_stm32h7rsxx.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_cortex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_dma_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_exti.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_flash.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_flash_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_gpio.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_pwr.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_pwr_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_rcc.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_rcc_ex.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c + + + Drivers/STM32H7RSxx_HAL_Driver/stm32h7rsxx_hal_xspi.c + 1 + PARENT-2-PROJECT_LOC/Drivers/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c + + + Middlewares/STM32_ExtMem_Manager/stm32_boot_xip.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/boot/stm32_boot_xip.c + + + Middlewares/STM32_ExtMem_Manager/stm32_extmem.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/stm32_extmem.c + + + Middlewares/STM32_ExtMem_Manager/stm32_psram_driver.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/psram/stm32_psram_driver.c + + + Middlewares/STM32_ExtMem_Manager/stm32_sal_sd.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_sd.c + + + Middlewares/STM32_ExtMem_Manager/stm32_sal_xspi.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/sal/stm32_sal_xspi.c + + + Middlewares/STM32_ExtMem_Manager/stm32_sdcard_driver.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c + + + Middlewares/STM32_ExtMem_Manager/stm32_sfdp_data.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c + + + Middlewares/STM32_ExtMem_Manager/stm32_sfdp_driver.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c + + + Middlewares/STM32_ExtMem_Manager/stm32_user_driver.c + 1 + PARENT-2-PROJECT_LOC/Middlewares/ST/STM32_ExtMem_Manager/user/stm32_user_driver.c + + + Application/User/Core/extmem_manager.c + 1 + PARENT-2-PROJECT_LOC/Boot/Core/Src/extmem_manager.c + + + Application/User/Core/main.c + 1 + PARENT-2-PROJECT_LOC/Boot/Core/Src/main.c + + + Application/User/Core/stm32h7rsxx_hal_msp.c + 1 + PARENT-2-PROJECT_LOC/Boot/Core/Src/stm32h7rsxx_hal_msp.c + + + Application/User/Core/stm32h7rsxx_it.c + 1 + PARENT-2-PROJECT_LOC/Boot/Core/Src/stm32h7rsxx_it.c + + + diff --git a/STM32CubeIDE/Boot/Application/User/Core/syscalls.c b/STM32CubeIDE/Boot/Application/User/Core/syscalls.c new file mode 100644 index 0000000..c6f50f2 --- /dev/null +++ b/STM32CubeIDE/Boot/Application/User/Core/syscalls.c @@ -0,0 +1,176 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 +#include +#include +#include +#include +#include +#include +#include + + +/* Variables */ +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + + +char *__env[1] = { 0 }; +char **environ = __env; + + +/* Functions */ +void initialise_monitor_handles() +{ +} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit (int status) +{ + _kill(status, -1); + while (1) {} /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + (void)file; + return -1; +} + + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/STM32CubeIDE/Boot/Application/User/Core/sysmem.c b/STM32CubeIDE/Boot/Application/User/Core/sysmem.c new file mode 100644 index 0000000..17a2c3a --- /dev/null +++ b/STM32CubeIDE/Boot/Application/User/Core/sysmem.c @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Generated by STM32CubeIDE + * @brief STM32CubeIDE System Memory calls file + * + * For more information about which C functions + * need which of these lowlevel functions + * please consult the newlib libc manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc + * and others from the C library + * + * @verbatim + * ############################################################################ + * # .data # .bss # newlib heap # MSP stack # + * # # # # Reserved by _Min_Stack_Size # + * ############################################################################ + * ^-- RAM start ^-- _end _estack, RAM end --^ + * @endverbatim + * + * This implementation starts allocating at the '_end' linker symbol + * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack + * The implementation considers '_estack' linker symbol to be RAM end + * NOTE: If the MSP stack, at any point during execution, grows larger than the + * reserved size, please increase the '_Min_Stack_Size'. + * + * @param incr Memory size + * @return Pointer to allocated memory + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + const uint8_t *max_heap = (uint8_t *)stack_limit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) + { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into the reserved MSP stack */ + if (__sbrk_heap_end + incr > max_heap) + { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/STM32CubeIDE/Boot/Application/User/Startup/startup_stm32h7s7l8hxh.s b/STM32CubeIDE/Boot/Application/User/Startup/startup_stm32h7s7l8hxh.s new file mode 100644 index 0000000..e6124df --- /dev/null +++ b/STM32CubeIDE/Boot/Application/User/Startup/startup_stm32h7s7l8hxh.s @@ -0,0 +1,780 @@ +/** + ****************************************************************************** + * @file startup_stm32h7s7xx.s + * @author MCD Application Team + * @brief STM32H7S7xx Devices vector table for 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 + * - 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-m7 + .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 STM32H7S7xx 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 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + /* External Interrupts */ + .word PVD_PVM_IRQHandler /* PVD/PVM through EXTI Line detection */ + .word 0 /* Reserved */ + .word DTS_IRQHandler /* Digital Temperature Sensor */ + .word IWDG_IRQHandler /* Internal Watchdog */ + .word WWDG_IRQHandler /* Window Watchdog */ + .word RCC_IRQHandler /* RCC global interrupts through EXTI Line detection */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FLASH_IRQHandler /* FLASH interrupts */ + .word RAMECC_IRQHandler /* RAMECC interrupts */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word TAMP_IRQHandler /* Tamper and TimeStamp interrupts */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word EXTI5_IRQHandler /* EXTI Line5 */ + .word EXTI6_IRQHandler /* EXTI Line6 */ + .word EXTI7_IRQHandler /* EXTI Line7 */ + .word EXTI8_IRQHandler /* EXTI Line8 */ + .word EXTI9_IRQHandler /* EXTI Line9 */ + .word EXTI10_IRQHandler /* EXTI Line10 */ + .word EXTI11_IRQHandler /* EXTI Line11 */ + .word EXTI12_IRQHandler /* EXTI Line12 */ + .word EXTI13_IRQHandler /* EXTI Line13 */ + .word EXTI14_IRQHandler /* EXTI Line14 */ + .word EXTI15_IRQHandler /* EXTI Line15 */ + .word RTC_IRQHandler /* RTC wakeup and alarm interrupts */ + .word SAES_IRQHandler /* SAES */ + .word CRYP_IRQHandler /* CRYP */ + .word PKA_IRQHandler /* PKA */ + .word HASH_IRQHandler /* HASH */ + .word RNG_IRQHandler /* RNG */ + .word ADC1_2_IRQHandler /* ADC1 & ADC2 */ + .word GPDMA1_Channel0_IRQHandler /* GPDMA1 Channel 0 */ + .word GPDMA1_Channel1_IRQHandler /* GPDMA1 Channel 1 */ + .word GPDMA1_Channel2_IRQHandler /* GPDMA1 Channel 2 */ + .word GPDMA1_Channel3_IRQHandler /* GPDMA1 Channel 3 */ + .word GPDMA1_Channel4_IRQHandler /* GPDMA1 Channel 4 */ + .word GPDMA1_Channel5_IRQHandler /* GPDMA1 Channel 5 */ + .word GPDMA1_Channel6_IRQHandler /* GPDMA1 Channel 6 */ + .word GPDMA1_Channel7_IRQHandler /* GPDMA1 Channel 7 */ + .word TIM1_BRK_IRQHandler /* TIM1 Break */ + .word TIM1_UP_IRQHandler /* TIM1 Update */ + .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word TIM5_IRQHandler /* TIM5 */ + .word TIM6_IRQHandler /* TIM6 */ + .word TIM7_IRQHandler /* TIM7 */ + .word TIM9_IRQHandler /* TIM9 */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word SPI3_IRQHandler /* SPI3 */ + .word SPI4_IRQHandler /* SPI4 */ + .word SPI5_IRQHandler /* SPI5 */ + .word SPI6_IRQHandler /* SPI6 */ + .word HPDMA1_Channel0_IRQHandler /* HPDMA1 Channel 0 */ + .word HPDMA1_Channel1_IRQHandler /* HPDMA1 Channel 1 */ + .word HPDMA1_Channel2_IRQHandler /* HPDMA1 Channel 2 */ + .word HPDMA1_Channel3_IRQHandler /* HPDMA1 Channel 3 */ + .word HPDMA1_Channel4_IRQHandler /* HPDMA1 Channel 4 */ + .word HPDMA1_Channel5_IRQHandler /* HPDMA1 Channel 5 */ + .word HPDMA1_Channel6_IRQHandler /* HPDMA1 Channel 6 */ + .word HPDMA1_Channel7_IRQHandler /* HPDMA1 Channel 7 */ + .word SAI1_A_IRQHandler /* Serial Audio Interface 1 block A */ + .word SAI1_B_IRQHandler /* Serial Audio Interface 1 block B */ + .word SAI2_A_IRQHandler /* Serial Audio Interface 2 block A */ + .word SAI2_B_IRQHandler /* Serial Audio Interface 2 block B */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word I2C3_EV_IRQHandler /* I2C3 Event */ + .word I2C3_ER_IRQHandler /* I2C3 Error */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word UART7_IRQHandler /* UART7 */ + .word UART8_IRQHandler /* UART8 */ + .word I3C1_EV_IRQHandler /* I3C1 Event */ + .word I3C1_ER_IRQHandler /* I3C1 Error */ + .word OTG_HS_IRQHandler /* USB OTG HS */ + .word ETH_IRQHandler /* Ethernet */ + .word CORDIC_IRQHandler /* CORDIC */ + .word GFXTIM_IRQHandler /* GFXTIM */ + .word DCMIPP_IRQHandler /* DCMIPP */ + .word LTDC_IRQHandler /* LTDC */ + .word LTDC_ER_IRQHandler /* LTDC error */ + .word DMA2D_IRQHandler /* DMA2D */ + .word JPEG_IRQHandler /* JPEG */ + .word GFXMMU_IRQHandler /* GFXMMU */ + .word I3C1_WKUP_IRQHandler /* I3C1 wakeup */ + .word MCE1_IRQHandler /* MCE1 */ + .word MCE2_IRQHandler /* MCE2 */ + .word MCE3_IRQHandler /* MCE3 */ + .word XSPI1_IRQHandler /* XSPI1 */ + .word XSPI2_IRQHandler /* XSPI2 */ + .word FMC_IRQHandler /* FMC */ + .word SDMMC1_IRQHandler /* SDMMC1 */ + .word SDMMC2_IRQHandler /* SDMMC2 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word TIM12_IRQHandler /* TIM12 */ + .word TIM13_IRQHandler /* TIM13 */ + .word TIM14_IRQHandler /* TIM14 */ + .word TIM15_IRQHandler /* TIM15 */ + .word TIM16_IRQHandler /* TIM16 */ + .word TIM17_IRQHandler /* TIM17 */ + .word LPTIM1_IRQHandler /* LP TIM1 */ + .word LPTIM2_IRQHandler /* LP TIM2 */ + .word LPTIM3_IRQHandler /* LP TIM3 */ + .word LPTIM4_IRQHandler /* LP TIM4 */ + .word LPTIM5_IRQHandler /* LP TIM5 */ + .word SPDIF_RX_IRQHandler /* SPDIF_RX */ + .word MDIOS_IRQHandler /* MDIOS */ + .word ADF1_FLT0_IRQHandler /* ADF1 Filter 0 */ + .word CRS_IRQHandler /* CRS */ + .word UCPD1_IRQHandler /* UCPD1 */ + .word CEC_IRQHandler /* HDMI_CEC */ + .word PSSI_IRQHandler /* PSSI */ + .word LPUART1_IRQHandler /* LP UART1 */ + .word WAKEUP_PIN_IRQHandler /* Wake-up pins interrupt */ + .word GPDMA1_Channel8_IRQHandler /* GPDMA1 Channel 8 */ + .word GPDMA1_Channel9_IRQHandler /* GPDMA1 Channel 9 */ + .word GPDMA1_Channel10_IRQHandler /* GPDMA1 Channel 10 */ + .word GPDMA1_Channel11_IRQHandler /* GPDMA1 Channel 11 */ + .word GPDMA1_Channel12_IRQHandler /* GPDMA1 Channel 12 */ + .word GPDMA1_Channel13_IRQHandler /* GPDMA1 Channel 13 */ + .word GPDMA1_Channel14_IRQHandler /* GPDMA1 Channel 14 */ + .word GPDMA1_Channel15_IRQHandler /* GPDMA1 Channel 15 */ + .word HPDMA1_Channel8_IRQHandler /* HPDMA1 Channel 8 */ + .word HPDMA1_Channel9_IRQHandler /* HPDMA1 Channel 9 */ + .word HPDMA1_Channel10_IRQHandler /* HPDMA1 Channel 10 */ + .word HPDMA1_Channel11_IRQHandler /* HPDMA1 Channel 11 */ + .word HPDMA1_Channel12_IRQHandler /* HPDMA1 Channel 12 */ + .word HPDMA1_Channel13_IRQHandler /* HPDMA1 Channel 13 */ + .word HPDMA1_Channel14_IRQHandler /* HPDMA1 Channel 14 */ + .word HPDMA1_Channel15_IRQHandler /* HPDMA1 Channel 15 */ + .word GPU2D_IRQHandler /* GPU2D */ + .word GPU2D_ER_IRQHandler /* GPU2D error */ + .word ICACHE_IRQHandler /* ICACHE */ + .word FDCAN1_IT0_IRQHandler /* FDCAN1 Interrupt 0 */ + .word FDCAN1_IT1_IRQHandler /* FDCAN1 Interrupt 1 */ + .word FDCAN2_IT0_IRQHandler /* FDCAN2 Interrupt 0 */ + .word FDCAN2_IT1_IRQHandler /* FDCAN2 Interrupt 1 */ + +/******************************************************************************* +* +* 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 PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RAMECC_IRQHandler + .thumb_set RAMECC_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_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 RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak SAES_IRQHandler + .thumb_set SAES_IRQHandler,Default_Handler + + .weak CRYP_IRQHandler + .thumb_set CRYP_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak ADC1_2_IRQHandler + .thumb_set ADC1_2_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 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 TIM9_IRQHandler + .thumb_set TIM9_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 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 HPDMA1_Channel0_IRQHandler + .thumb_set HPDMA1_Channel0_IRQHandler,Default_Handler + + .weak HPDMA1_Channel1_IRQHandler + .thumb_set HPDMA1_Channel1_IRQHandler,Default_Handler + + .weak HPDMA1_Channel2_IRQHandler + .thumb_set HPDMA1_Channel2_IRQHandler,Default_Handler + + .weak HPDMA1_Channel3_IRQHandler + .thumb_set HPDMA1_Channel3_IRQHandler,Default_Handler + + .weak HPDMA1_Channel4_IRQHandler + .thumb_set HPDMA1_Channel4_IRQHandler,Default_Handler + + .weak HPDMA1_Channel5_IRQHandler + .thumb_set HPDMA1_Channel5_IRQHandler,Default_Handler + + .weak HPDMA1_Channel6_IRQHandler + .thumb_set HPDMA1_Channel6_IRQHandler,Default_Handler + + .weak HPDMA1_Channel7_IRQHandler + .thumb_set HPDMA1_Channel7_IRQHandler,Default_Handler + + .weak SAI1_A_IRQHandler + .thumb_set SAI1_A_IRQHandler,Default_Handler + + .weak SAI1_B_IRQHandler + .thumb_set SAI1_B_IRQHandler,Default_Handler + + .weak SAI2_A_IRQHandler + .thumb_set SAI2_A_IRQHandler,Default_Handler + + .weak SAI2_B_IRQHandler + .thumb_set SAI2_B_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 I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_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 UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_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 OTG_HS_IRQHandler + .thumb_set OTG_HS_IRQHandler,Default_Handler + + .weak ETH_IRQHandler + .thumb_set ETH_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak GFXTIM_IRQHandler + .thumb_set GFXTIM_IRQHandler,Default_Handler + + .weak DCMIPP_IRQHandler + .thumb_set DCMIPP_IRQHandler,Default_Handler + + .weak LTDC_IRQHandler + .thumb_set LTDC_IRQHandler,Default_Handler + + .weak LTDC_ER_IRQHandler + .thumb_set LTDC_ER_IRQHandler,Default_Handler + + .weak DMA2D_IRQHandler + .thumb_set DMA2D_IRQHandler,Default_Handler + + .weak JPEG_IRQHandler + .thumb_set JPEG_IRQHandler,Default_Handler + + .weak GFXMMU_IRQHandler + .thumb_set GFXMMU_IRQHandler,Default_Handler + + .weak I3C1_WKUP_IRQHandler + .thumb_set I3C1_WKUP_IRQHandler,Default_Handler + + .weak MCE1_IRQHandler + .thumb_set MCE1_IRQHandler,Default_Handler + + .weak MCE2_IRQHandler + .thumb_set MCE2_IRQHandler,Default_Handler + + .weak MCE3_IRQHandler + .thumb_set MCE3_IRQHandler,Default_Handler + + .weak XSPI1_IRQHandler + .thumb_set XSPI1_IRQHandler,Default_Handler + + .weak XSPI2_IRQHandler + .thumb_set XSPI2_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_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 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 LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_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 SPDIF_RX_IRQHandler + .thumb_set SPDIF_RX_IRQHandler,Default_Handler + + .weak MDIOS_IRQHandler + .thumb_set MDIOS_IRQHandler,Default_Handler + + .weak ADF1_FLT0_IRQHandler + .thumb_set ADF1_FLT0_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak PSSI_IRQHandler + .thumb_set PSSI_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak WAKEUP_PIN_IRQHandler + .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler + + .weak GPDMA1_Channel8_IRQHandler + .thumb_set GPDMA1_Channel8_IRQHandler,Default_Handler + + .weak GPDMA1_Channel9_IRQHandler + .thumb_set GPDMA1_Channel9_IRQHandler,Default_Handler + + .weak GPDMA1_Channel10_IRQHandler + .thumb_set GPDMA1_Channel10_IRQHandler,Default_Handler + + .weak GPDMA1_Channel11_IRQHandler + .thumb_set GPDMA1_Channel11_IRQHandler,Default_Handler + + .weak GPDMA1_Channel12_IRQHandler + .thumb_set GPDMA1_Channel12_IRQHandler,Default_Handler + + .weak GPDMA1_Channel13_IRQHandler + .thumb_set GPDMA1_Channel13_IRQHandler,Default_Handler + + .weak GPDMA1_Channel14_IRQHandler + .thumb_set GPDMA1_Channel14_IRQHandler,Default_Handler + + .weak GPDMA1_Channel15_IRQHandler + .thumb_set GPDMA1_Channel15_IRQHandler,Default_Handler + + .weak HPDMA1_Channel8_IRQHandler + .thumb_set HPDMA1_Channel8_IRQHandler,Default_Handler + + .weak HPDMA1_Channel9_IRQHandler + .thumb_set HPDMA1_Channel9_IRQHandler,Default_Handler + + .weak HPDMA1_Channel10_IRQHandler + .thumb_set HPDMA1_Channel10_IRQHandler,Default_Handler + + .weak HPDMA1_Channel11_IRQHandler + .thumb_set HPDMA1_Channel11_IRQHandler,Default_Handler + + .weak HPDMA1_Channel12_IRQHandler + .thumb_set HPDMA1_Channel12_IRQHandler,Default_Handler + + .weak HPDMA1_Channel13_IRQHandler + .thumb_set HPDMA1_Channel13_IRQHandler,Default_Handler + + .weak HPDMA1_Channel14_IRQHandler + .thumb_set HPDMA1_Channel14_IRQHandler,Default_Handler + + .weak HPDMA1_Channel15_IRQHandler + .thumb_set HPDMA1_Channel15_IRQHandler,Default_Handler + + .weak GPU2D_IRQHandler + .thumb_set GPU2D_IRQHandler,Default_Handler + + .weak GPU2D_ER_IRQHandler + .thumb_set GPU2D_ER_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_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 FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak SystemInit \ No newline at end of file diff --git a/STM32CubeIDE/Boot/STM32H7S78-DK_Boot.launch b/STM32CubeIDE/Boot/STM32H7S78-DK_Boot.launch new file mode 100644 index 0000000..fe13967 --- /dev/null +++ b/STM32CubeIDE/Boot/STM32H7S78-DK_Boot.launch @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/STM32CubeIDE/Boot/STM32H7S7L8HXH_FLASH.ld b/STM32CubeIDE/Boot/STM32H7S7L8HXH_FLASH.ld new file mode 100644 index 0000000..44678b6 --- /dev/null +++ b/STM32CubeIDE/Boot/STM32H7S7L8HXH_FLASH.ld @@ -0,0 +1,208 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : STM32CubeIDE +** +** Abstract : Linker script for STM32H7Sxx Device +** 64Kbytes FLASH +** 456Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2026 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of Ram type memory */ + +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + +__FLASH_BEGIN = 0x08000000; +__FLASH_SIZE = 0x00010000; + + +__RAM_BEGIN = 0x24000000; +__RAM_SIZE = 0x71C00; +__RAM_NONCACHEABLEBUFFER_SIZE = 0x400; + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = __RAM_BEGIN, LENGTH = __RAM_SIZE + RAM_NONCACHEABLEBUFFER (xrw) : ORIGIN = __RAM_BEGIN + __RAM_SIZE, LENGTH = __RAM_NONCACHEABLEBUFFER_SIZE + + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 0x00010000 + DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 + SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000 + BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000 + + FLASH (xrw) : ORIGIN = __FLASH_BEGIN, LENGTH = __FLASH_SIZE +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + RW_NONCACHEABLE (NOLOAD): + { + __NONCACHEABLEBUFFER_BEGIN = .;/* create symbol for start of section */ + KEEP(*(noncacheable_buffer)) + __NONCACHEABLEBUFFER_END = .; /* create symbol for start of section */ + } > RAM_NONCACHEABLEBUFFER + + /* User_heap_stack section, used to check that there is enough Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >DTCM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/STM32CubeIDE/ExtMemLoader/postbuild.sh b/STM32CubeIDE/ExtMemLoader/postbuild.sh new file mode 100644 index 0000000..3882d73 --- /dev/null +++ b/STM32CubeIDE/ExtMemLoader/postbuild.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# set cubeprog variable check +cubeprog=1 +# Getting the project path +projectdir="$(dirname "$(readlink -f "$0")")" +# Check the operating system +if [[ "$OSTYPE" == "linux-gnu"* ]]; then + # Commands for Linux + export dest_dir=$STM32_PRG_PATH + # Commands for Ubuntu to extract STM32_PRG_PATH from /.bashrc + if [[ -z "${dest_dir}" ]]; then + dest_dir=$(grep "^export STM32_PRG_PATH=" ~/.bashrc | cut -d'=' -f2) + fi +elif [[ "$OSTYPE" == "darwin"* ]]; then + # Commands for macOS + export dest_dir=$STM32_PRG_PATH +elif [[ "$(echo "$OS" | grep -Ei 'win(dows)?(_nt)?')" ]]; then + # Commands for Windows + export dest_dir=$STM32_PRG_PATH +else + echo "Unknown operating system" +fi +# check if STM32Cubeprogrammer env variable exists or not +if [[ -z "${dest_dir}" ]]; then + echo "warning :: the env variable STM32_PRG_PATH is undefined" + cubeprog=0 +fi + +dest_dir=$dest_dir/ExternalLoader +cubeide_cubeprogrammer_path=$1 +new_ext=".stldr" +keyword="ExtMemLoader" +keyword_CUBEIDE="Debug" +extension=".ewp" + +# check used IDE EWARM or STM32CubeIDE +for j in $(find "$projectdir" -name "*$keyword*$extension" 2>/dev/null); do + EWARM=true +done +extension=".cproject" +for j in $(find "$projectdir" -name "$extension" 2>/dev/null); do + STM32CUBE=true +done + +if [ "$EWARM" = true ]; then + echo "EWARM IDE is found!" + extension=".out" + for j in $(find "$projectdir" -name "*$keyword*$extension" 2>/dev/null); do + projectCopy="$j" + done + if [ "$cubeprog" = 1 ]; then + for f in "$projectCopy"; do + cp "$f" "$dest_dir/$(basename "${f%.*}")$new_ext" + done + if [ $? -eq 0 ]; then + echo "File copied successfully" + else + echo "Error: File copy failed please check that the folder exists or you have the right permission to copy the ExtMemLoader" + fi + fi + exit 0 +fi +if [ "$STM32CUBE" = true ]; then + echo "STM32CUBE IDE is found!" + extension=".elf" + for j in $(find "$projectdir" -name "*$keyword*$extension" 2>/dev/null); do + projectCopy="$j" + done + + if [ "$cubeprog" = 1 ]; then + for f in "$projectCopy"; do + cp -a "$f" "$dest_dir/$(basename "${f%.*}")$new_ext" + done + if [ $? -eq 0 ]; then + echo "File copied successfully under STM32CubeProgrammer." + else + echo "warning :: File copy failed under STM32CubeProgrammer please check that the folder exists or you have the right permission to copy the ExtMemLoader." + fi + fi +if [ -d "$cubeide_cubeprogrammer_path" ]; then + for f in "$projectCopy"; do + cp -a "$f" "$cubeide_cubeprogrammer_path/$(basename "${f%.*}")$new_ext" + done + if [ $? -eq 0 ]; then + echo "File copied successfully under STM32CubeIDE" + else + echo "warning :: File copy failed under STM32CubeIDE please check that you have the right permission to copy the ExtMemLoader." + fi +else + echo "warning :: File copy failed under STM32CubeIDE please check that the folder exists." +fi + + exit 0 +fi diff --git a/STM32H7S78-DK.ioc b/STM32H7S78-DK.ioc new file mode 100644 index 0000000..82accac --- /dev/null +++ b/STM32H7S78-DK.ioc @@ -0,0 +1,988 @@ +#MicroXplorer Configuration settings - do not modify +ADF1.IPParameters=MDF_COMPARAM_ProcClockDivider,MDF_DFLT0_CIC_Mode,MDF_DFLT0_Decimation,MDF_DFLT0_ReshapeFilterActivation,MDF_DFLT0_FifoThreshold,MDF_SITF0_Mode_Display,MDF_COMPARAM_ActivationOutputClock,MDF_COMPARAM_Divider,MDF_SITF0_Threshold,MDF_DFLT0_HighPassFilterActivation,MDF_DFLT0_Gain +ADF1.MDF_COMPARAM_ActivationOutputClock=ENABLE +ADF1.MDF_COMPARAM_Divider=2 +ADF1.MDF_COMPARAM_ProcClockDivider=2 +ADF1.MDF_DFLT0_CIC_Mode=MDF_ONE_FILTER_SINC4 +ADF1.MDF_DFLT0_Decimation=32 +ADF1.MDF_DFLT0_FifoThreshold=MDF_FIFO_THRESHOLD_NOT_EMPTY +ADF1.MDF_DFLT0_Gain=2 +ADF1.MDF_DFLT0_HighPassFilterActivation=ENABLE +ADF1.MDF_DFLT0_ReshapeFilterActivation=ENABLE +ADF1.MDF_SITF0_Mode_Display=MDF_SITF_NORMAL_SPI_MODE +ADF1.MDF_SITF0_Threshold=31 +Appli.IPs=GPDMA1\:I,HPDMA1\:I,LINKEDLIST\:I,GPIO,NVIC2\:I,CRC,LTDC,DMA2D,FREERTOS\:I,SYS,STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App\:I,I2C1,JPEG,RCC,FLASH,GPU2D,ICACHE_GPU2D\:I,CORTEX_M7_APPLI\:I,TIM6,ADF1,I2S6 +Appli.Pins=PF3,PF2,PF4,PF1,PE15,PE3,PG15,PH1-OSC_OUT(PH1) +Boot.IPs=GPDMA1,HPDMA1,LINKEDLIST,RCC\:I,GPIO,NVIC1\:I,EXTMEM_MANAGER\:I,XSPI1,XSPI2,FLASH,SBS,CORTEX_M7_BOOT\:I,MEMORYMAP\:I +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_NO_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region6_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.AccessPermission-Cortex_Memory_Protection_Unit_Region7_Settings=MPU_REGION_FULL_ACCESS +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings=0x70000000 +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings=0x70000000 +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings=0x90000000 +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region4_Settings=0x20000000 +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region5_Settings=0x24000000 +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region6_Settings=0x24060000 +CORTEX_M7_APPLI.BaseAddress-Cortex_Memory_Protection_Unit_Region7_Settings=0x24070000 +CORTEX_M7_APPLI.CPU_DCache=Enabled +CORTEX_M7_APPLI.CPU_ICache=Enabled +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region6_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.DisableExec-Cortex_Memory_Protection_Unit_Region7_Settings=MPU_INSTRUCTION_ACCESS_DISABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region6_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region7_Settings=MPU_REGION_ENABLE +CORTEX_M7_APPLI.Enable-Cortex_Memory_Protection_Unit_Region8_Settings=__NULL +CORTEX_M7_APPLI.IPParameters=CPU_ICache,CPU_DCache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,SubRegionDisable-Cortex_Memory_Protection_Unit_Region0_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region0_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region0_Settings,Enable-Cortex_Memory_Protection_Unit_Region1_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region1_Settings,Size-Cortex_Memory_Protection_Unit_Region1_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region1_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region1_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region1_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings,Enable-Cortex_Memory_Protection_Unit_Region2_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region2_Settings,Size-Cortex_Memory_Protection_Unit_Region2_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region2_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region2_Settings,Enable-Cortex_Memory_Protection_Unit_Region3_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region3_Settings,Size-Cortex_Memory_Protection_Unit_Region3_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region3_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region3_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region3_Settings,Enable-Cortex_Memory_Protection_Unit_Region4_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region4_Settings,Size-Cortex_Memory_Protection_Unit_Region4_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region4_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region4_Settings,Enable-Cortex_Memory_Protection_Unit_Region5_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region5_Settings,Size-Cortex_Memory_Protection_Unit_Region5_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region5_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region5_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region5_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region5_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region5_Settings,Enable-Cortex_Memory_Protection_Unit_Region6_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region6_Settings,Size-Cortex_Memory_Protection_Unit_Region6_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region6_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region6_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region6_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region0_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region4_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region5_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region6_Settings,Enable-Cortex_Memory_Protection_Unit_Region8_Settings,Enable-Cortex_Memory_Protection_Unit_Region7_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region7_Settings,Size-Cortex_Memory_Protection_Unit_Region7_Settings,DisableExec-Cortex_Memory_Protection_Unit_Region7_Settings,IsShareable-Cortex_Memory_Protection_Unit_Region7_Settings,AccessPermission-Cortex_Memory_Protection_Unit_Region7_Settings +CORTEX_M7_APPLI.IsBufferable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_BUFFERABLE +CORTEX_M7_APPLI.IsBufferable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_BUFFERABLE +CORTEX_M7_APPLI.IsBufferable-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_ACCESS_BUFFERABLE +CORTEX_M7_APPLI.IsBufferable-Cortex_Memory_Protection_Unit_Region6_Settings=MPU_ACCESS_NOT_BUFFERABLE +CORTEX_M7_APPLI.IsCacheable-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_ACCESS_CACHEABLE +CORTEX_M7_APPLI.IsCacheable-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_ACCESS_CACHEABLE +CORTEX_M7_APPLI.IsCacheable-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_ACCESS_CACHEABLE +CORTEX_M7_APPLI.IsShareable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7_APPLI.IsShareable-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7_APPLI.IsShareable-Cortex_Memory_Protection_Unit_Region6_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7_APPLI.IsShareable-Cortex_Memory_Protection_Unit_Region7_Settings=MPU_ACCESS_SHAREABLE +CORTEX_M7_APPLI.MPU_Control=MPU_PRIVILEGED_DEFAULT +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_4GB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_REGION_SIZE_128MB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_REGION_SIZE_2MB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_REGION_SIZE_32MB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_REGION_SIZE_64KB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_REGION_SIZE_512KB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region6_Settings=MPU_REGION_SIZE_64KB +CORTEX_M7_APPLI.Size-Cortex_Memory_Protection_Unit_Region7_Settings=MPU_REGION_SIZE_16KB +CORTEX_M7_APPLI.SubRegionDisable-Cortex_Memory_Protection_Unit_Region0_Settings=0x87 +CORTEX_M7_APPLI.TypeExtField-Cortex_Memory_Protection_Unit_Region1_Settings=MPU_TEX_LEVEL1 +CORTEX_M7_APPLI.TypeExtField-Cortex_Memory_Protection_Unit_Region2_Settings=MPU_TEX_LEVEL1 +CORTEX_M7_APPLI.TypeExtField-Cortex_Memory_Protection_Unit_Region3_Settings=MPU_TEX_LEVEL1 +CORTEX_M7_APPLI.TypeExtField-Cortex_Memory_Protection_Unit_Region4_Settings=MPU_TEX_LEVEL1 +CORTEX_M7_APPLI.TypeExtField-Cortex_Memory_Protection_Unit_Region5_Settings=MPU_TEX_LEVEL1 +CORTEX_M7_BOOT.CPU_DCache=Enabled +CORTEX_M7_BOOT.CPU_ICache=Enabled +CORTEX_M7_BOOT.IPParameters=CPU_ICache,CPU_DCache +DMA2D.ColorMode=DMA2D_OUTPUT_RGB888 +DMA2D.IPParameters=Mode,ColorMode +DMA2D.Mode=DMA2D_R2M +EXTMEM_MANAGER.IPParameters=RefParam_MEMORY_1_ConfigType,RefParam_EXTMEM_SAL_XSPI,RefParam_EXTMEM_SFDP,RefParam_EXTMEM_PSRAM,RefParam_MEMORY_1_Instance,RefParam_MEMORY_1_Driver_Selection,RefParam_BOOT_enable,RefParam_EXTMEM_Number_of_Memory,RefParam_MEMORY_2_Driver_Selection,RefParam_MEMORY_2_ConfigType,RefParam_MEMORY_2_NumberOfConfig,RefParam_XIP_memory,RefParam_EXTMEM_USER,RefParam_BOOT_selection,RefParam_LRUN_DEST_memory +EXTMEM_MANAGER.RefParam_BOOT_enable=true +EXTMEM_MANAGER.RefParam_BOOT_selection=XIP +EXTMEM_MANAGER.RefParam_EXTMEM_Number_of_Memory=2 +EXTMEM_MANAGER.RefParam_EXTMEM_PSRAM=true +EXTMEM_MANAGER.RefParam_EXTMEM_SAL_XSPI=true +EXTMEM_MANAGER.RefParam_EXTMEM_SFDP=true +EXTMEM_MANAGER.RefParam_EXTMEM_USER=false +EXTMEM_MANAGER.RefParam_LRUN_DEST_memory=EXTMEM1 +EXTMEM_MANAGER.RefParam_MEMORY_1_ConfigType=EXTMEM_LINK_CONFIG_8LINES +EXTMEM_MANAGER.RefParam_MEMORY_1_Driver_Selection=EXTMEM_NOR_SFDP +EXTMEM_MANAGER.RefParam_MEMORY_1_Instance=XSPI2 +EXTMEM_MANAGER.RefParam_MEMORY_2_ConfigType=EXTMEM_LINK_CONFIG_16LINES +EXTMEM_MANAGER.RefParam_MEMORY_2_Driver_Selection=EXTMEM_PSRAM +EXTMEM_MANAGER.RefParam_MEMORY_2_NumberOfConfig=1 +EXTMEM_MANAGER.RefParam_XIP_memory=EXTMEM1 +ExtMemLoader.IPs=EXTMEM_LOADER\:I,EXTMEM_MANAGER,GPIO\:I,GPDMA1,HPDMA1,LINKEDLIST +FLASH.IPParameters=OB_User_Configuration1_active,OB_IWDG1_SW,OB_XSPI1_HSLV,OB_XSPI2_HSLV,OB_User_Configuration2_active,OB_IWDG1_SW_UI,OB_XSPI1_HSLV_UI,OB_XSPI2_HSLV_UI +FLASH.OB_IWDG1_SW=OB_IWDG_SW +FLASH.OB_IWDG1_SW_UI=OB_IWDG_SW +FLASH.OB_User_Configuration1_active=true +FLASH.OB_User_Configuration2_active=true +FLASH.OB_XSPI1_HSLV=OB_XSPI1_HSLV_ENABLE +FLASH.OB_XSPI1_HSLV_UI=OB_XSPI1_HSLV_ENABLE +FLASH.OB_XSPI2_HSLV=OB_XSPI2_HSLV_ENABLE +FLASH.OB_XSPI2_HSLV_UI=OB_XSPI2_HSLV_ENABLE +FREERTOS.FootprintOK=true +FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,FootprintOK,configUSE_APPLICATION_TASK_TAG,configUSE_IDLE_HOOK,configUSE_NEWLIB_REENTRANT +FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;TouchGFXTask,24,4096,TouchGFX_Task,As external,NULL,Dynamic,NULL,NULL +FREERTOS.configTOTAL_HEAP_SIZE=50000 +FREERTOS.configUSE_APPLICATION_TASK_TAG=1 +FREERTOS.configUSE_IDLE_HOOK=1 +FREERTOS.configUSE_NEWLIB_REENTRANT=1 +File.Version=6 +GPDMA1.CIRCULARMODE_GPDMACH0=ENABLE +GPDMA1.DATAHANDLING_GPDMACH0=ENABLE +GPDMA1.DESTDATAWIDTH_GPDMACH0=DMA_DEST_DATAWIDTH_WORD +GPDMA1.DESTINC_GPDMACH0=DMA_DINC_INCREMENTED +GPDMA1.IPHANDLE_GPDMACH0-SIMPLEREQUEST_GPDMACH0=__NULL +GPDMA1.IPParameters=CIRCULARMODE_GPDMACH0,REQUEST_GPDMACH0,SRCDATAWIDTH_GPDMACH0,DESTINC_GPDMACH0,DESTDATAWIDTH_GPDMACH0,TRANSFERALLOCATEDPORTDEST_GPDMACH0,LINKALLOCATEDPORT_CIRCULAR_GPDMACH0,PRIORITY_LL_CIRCULAR_GPDMACH0,DATAHANDLING_GPDMACH0,IPHANDLE_GPDMACH0-SIMPLEREQUEST_GPDMACH0 +GPDMA1.LINKALLOCATEDPORT_CIRCULAR_GPDMACH0=DMA_LINK_ALLOCATED_PORT1 +GPDMA1.PRIORITY_LL_CIRCULAR_GPDMACH0=DMA_LOW_PRIORITY_HIGH_WEIGHT +GPDMA1.REQUEST_GPDMACH0=GPDMA1_REQUEST_ADF1_FLT0 +GPDMA1.SRCDATAWIDTH_GPDMACH0=DMA_SRC_DATAWIDTH_WORD +GPDMA1.TRANSFERALLOCATEDPORTDEST_GPDMACH0=DMA_DEST_ALLOCATED_PORT1 +GPIO.groupedBy=Group By Peripherals +HPDMA1.DATAALIGNEMENT_HPDMACH0=DMA_DATA_PACK +HPDMA1.DATAHANDLING_HPDMACH0=ENABLE +HPDMA1.DESTBURSTLENGTH_HPDMACH0=8 +HPDMA1.DESTBURSTLENGTH_HPDMACH1=8 +HPDMA1.DESTDATAWIDTH_HPDMACH0=DMA_DEST_DATAWIDTH_WORD +HPDMA1.DESTDATAWIDTH_HPDMACH1=DMA_DEST_DATAWIDTH_WORD +HPDMA1.DESTINC_HPDMACH1=DMA_DINC_INCREMENTED +HPDMA1.DIRECTION_HPDMACH0=DMA_MEMORY_TO_PERIPH +HPDMA1.IPHANDLE_HPDMACH0-SIMPLEREQUEST_HPDMACH0=__NULL +HPDMA1.IPHANDLE_HPDMACH1-SIMPLEREQUEST_HPDMACH1=__NULL +HPDMA1.IPParameters=IPHANDLE_HPDMACH0-SIMPLEREQUEST_HPDMACH0,REQUEST_HPDMACH0,PRIORITY_HPDMACH0,DIRECTION_HPDMACH0,SRCINC_HPDMACH0,SRCBURSTLENGTH_HPDMACH0,TRANSFERALLOCATEDPORTSRC_HPDMACH0,DESTDATAWIDTH_HPDMACH0,DESTBURSTLENGTH_HPDMACH0,DATAHANDLING_HPDMACH0,DATAALIGNEMENT_HPDMACH0,IPHANDLE_HPDMACH1-SIMPLEREQUEST_HPDMACH1,REQUEST_HPDMACH1,PRIORITY_HPDMACH1,SRCDATAWIDTH_HPDMACH1,SRCBURSTLENGTH_HPDMACH1,DESTINC_HPDMACH1,DESTDATAWIDTH_HPDMACH1,DESTBURSTLENGTH_HPDMACH1,TRANSFERALLOCATEDPORTDEST_HPDMACH1,TRANSFERALLOCATEDPORTSRC_HPDMACH1,TRANSFERALLOCATEDPORTDEST_HPDMACH0 +HPDMA1.PRIORITY_HPDMACH0=DMA_HIGH_PRIORITY +HPDMA1.PRIORITY_HPDMACH1=DMA_HIGH_PRIORITY +HPDMA1.REQUEST_HPDMACH0=HPDMA1_REQUEST_JPEG_RX +HPDMA1.REQUEST_HPDMACH1=HPDMA1_REQUEST_JPEG_TX +HPDMA1.SRCBURSTLENGTH_HPDMACH0=8 +HPDMA1.SRCBURSTLENGTH_HPDMACH1=8 +HPDMA1.SRCDATAWIDTH_HPDMACH1=DMA_SRC_DATAWIDTH_WORD +HPDMA1.SRCINC_HPDMACH0=DMA_SINC_INCREMENTED +HPDMA1.TRANSFERALLOCATEDPORTDEST_HPDMACH0=DMA_DEST_ALLOCATED_PORT1 +HPDMA1.TRANSFERALLOCATEDPORTDEST_HPDMACH1=DMA_DEST_ALLOCATED_PORT0 +HPDMA1.TRANSFERALLOCATEDPORTSRC_HPDMACH0=DMA_SRC_ALLOCATED_PORT0 +HPDMA1.TRANSFERALLOCATEDPORTSRC_HPDMACH1=DMA_SRC_ALLOCATED_PORT1 +I2C1.I2C_Fall_Time=0 +I2C1.I2C_Rise_Time=0 +I2C1.I2C_Speed_Mode=I2C_Fast +I2C1.IPParameters=Timing,I2C_Speed_Mode,I2C_Rise_Time,I2C_Fall_Time +I2C1.Timing=0x00E063FF +I2S6.AudioFreq=I2S_AUDIOFREQ_48K +I2S6.ErrorAudioFreq=0.0 % +I2S6.IPParameters=Instance,RealAudioFreq,ErrorAudioFreq,AudioFreq +I2S6.Instance=SPI$Index +I2S6.RealAudioFreq=48.0 KHz +JPEG.IPParameters=JPEG_RGB_FORMAT,USE_JPEG_ENCODER +JPEG.JPEG_RGB_FORMAT=JPEG_ARGB8888 +JPEG.USE_JPEG_ENCODER=0 +KeepUserPlacement=false +LTDC.ActiveW=800 +LTDC.Alpha_L0=255 +LTDC.HBP=8 +LTDC.HFP=8 +LTDC.HSync=5 +LTDC.IPParameters=Layers,WindowX1_L0,WindowY1_L0,PixelFormat_L0,Alpha_L0,ImageWidth_L0,ImageHeight_L0,ActiveW,HSync,HBP,HFP,VSync,VBP,VFP +LTDC.ImageHeight_L0=480 +LTDC.ImageWidth_L0=800 +LTDC.Layers=0 +LTDC.PixelFormat_L0=LTDC_PIXEL_FORMAT_RGB565 +LTDC.VBP=8 +LTDC.VFP=14 +LTDC.VSync=5 +LTDC.WindowX1_L0=800 +LTDC.WindowY1_L0=480 +MMTAppReg1.MEMORYMAP.AppRegionName=DTCM +MMTAppReg1.MEMORYMAP.ContextName=Boot +MMTAppReg1.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg1.MEMORYMAP.DefaultDataRegion=true +MMTAppReg1.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name +MMTAppReg1.MEMORYMAP.Name=DTCM +MMTAppReg1.MEMORYMAP.Size=65536 +MMTAppReg1.MEMORYMAP.StartAddress=0x20000000 +MMTAppReg2.MEMORYMAP.AppRegionName=RAM +MMTAppReg2.MEMORYMAP.ContextName=Boot +MMTAppReg2.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg2.MEMORYMAP.DefaultDataRegion=true +MMTAppReg2.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name +MMTAppReg2.MEMORYMAP.Name=RAM +MMTAppReg2.MEMORYMAP.Size=465920 +MMTAppReg2.MEMORYMAP.StartAddress=0x24000000 +MMTAppReg3.MEMORYMAP.AppRegionName=ITCM +MMTAppReg3.MEMORYMAP.Cacheability=WTRA +MMTAppReg3.MEMORYMAP.ContextName=Boot +MMTAppReg3.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg3.MEMORYMAP.DefaultDataRegion=false +MMTAppReg3.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name,Cacheability +MMTAppReg3.MEMORYMAP.Name=ITCM +MMTAppReg3.MEMORYMAP.Size=65536 +MMTAppReg3.MEMORYMAP.StartAddress=0x00000000 +MMTAppReg4.MEMORYMAP.AP=RO_priv_only +MMTAppReg4.MEMORYMAP.AppRegionName=FLASH +MMTAppReg4.MEMORYMAP.Cacheability=WTRA +MMTAppReg4.MEMORYMAP.ContextName=Boot +MMTAppReg4.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg4.MEMORYMAP.DefaultCodeRegion=true +MMTAppReg4.MEMORYMAP.DefaultDataRegion=false +MMTAppReg4.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,MemType,ContextName,Name,AP,Cacheability,DefaultCodeRegion +MMTAppReg4.MEMORYMAP.MemType=ROM +MMTAppReg4.MEMORYMAP.Name=FLASH +MMTAppReg4.MEMORYMAP.Size=65536 +MMTAppReg4.MEMORYMAP.StartAddress=0x08000000 +MMTAppReg5.MEMORYMAP.AppRegionName=DTCM +MMTAppReg5.MEMORYMAP.ContextName=Appli +MMTAppReg5.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg5.MEMORYMAP.DefaultDataRegion=true +MMTAppReg5.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name +MMTAppReg5.MEMORYMAP.Name=DTCM +MMTAppReg5.MEMORYMAP.Size=65536 +MMTAppReg5.MEMORYMAP.StartAddress=0x20000000 +MMTAppReg6.MEMORYMAP.AppRegionName=RAM +MMTAppReg6.MEMORYMAP.ContextName=Appli +MMTAppReg6.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg6.MEMORYMAP.DefaultDataRegion=true +MMTAppReg6.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name +MMTAppReg6.MEMORYMAP.Name=RAM +MMTAppReg6.MEMORYMAP.Size=465920 +MMTAppReg6.MEMORYMAP.StartAddress=0x24000000 +MMTAppReg7.MEMORYMAP.AppRegionName=ITCM +MMTAppReg7.MEMORYMAP.Cacheability=WTRA +MMTAppReg7.MEMORYMAP.ContextName=Appli +MMTAppReg7.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg7.MEMORYMAP.DefaultDataRegion=false +MMTAppReg7.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name,Cacheability +MMTAppReg7.MEMORYMAP.Name=ITCM +MMTAppReg7.MEMORYMAP.Size=65536 +MMTAppReg7.MEMORYMAP.StartAddress=0x00000000 +MMTAppReg8.MEMORYMAP.AP=RO_priv_only +MMTAppReg8.MEMORYMAP.AppRegionName=FLASH +MMTAppReg8.MEMORYMAP.Cacheability=WTRA +MMTAppReg8.MEMORYMAP.ContextName=Appli +MMTAppReg8.MEMORYMAP.CoreName=ARM Cortex-M7 +MMTAppReg8.MEMORYMAP.DefaultCodeRegion=true +MMTAppReg8.MEMORYMAP.DefaultDataRegion=false +MMTAppReg8.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,MemType,ContextName,Name,AP,Cacheability,DefaultCodeRegion +MMTAppReg8.MEMORYMAP.MemType=ROM +MMTAppReg8.MEMORYMAP.Name=FLASH +MMTAppReg8.MEMORYMAP.Size=65536 +MMTAppReg8.MEMORYMAP.StartAddress=0x08000000 +MMTAppRegionsCount=8 +MMTConfigApplied=false +MMTSectionSuffix= +Mcu.CPN=STM32H7S7L8H6H +Mcu.Context0=Boot +Mcu.Context1=Appli +Mcu.Context2=ExtMemLoader +Mcu.ContextNb=3 +Mcu.Family=STM32H7 +Mcu.IP0=ADF1 +Mcu.IP1=CORTEX_M7_APPLI +Mcu.IP10=HPDMA1 +Mcu.IP11=I2C1 +Mcu.IP12=I2S6 +Mcu.IP13=ICACHE_GPU2D +Mcu.IP14=JPEG +Mcu.IP15=LTDC +Mcu.IP16=MEMORYMAP +Mcu.IP17=NVIC2 +Mcu.IP18=NVIC1 +Mcu.IP19=RCC +Mcu.IP2=CORTEX_M7_BOOT +Mcu.IP20=SBS +Mcu.IP21=SYS +Mcu.IP22=XSPI1 +Mcu.IP23=XSPI2 +Mcu.IP3=CRC +Mcu.IP4=DMA2D +Mcu.IP5=EXTMEM_MANAGER +Mcu.IP6=FLASH +Mcu.IP7=FREERTOS +Mcu.IP8=GPDMA1 +Mcu.IP9=GPU2D +Mcu.IPNb=24 +Mcu.Name=STM32H7S7L8HxH +Mcu.Package=TFBGA225 HEXA SMPS +Mcu.Pin0=PF3 +Mcu.Pin1=PF2 +Mcu.Pin10=PG2 +Mcu.Pin11=PE11 +Mcu.Pin12=PA12 +Mcu.Pin13=PA11 +Mcu.Pin14=PB4(NJTRST) +Mcu.Pin15=PE15 +Mcu.Pin16=PC12 +Mcu.Pin17=PA9 +Mcu.Pin18=PB6 +Mcu.Pin19=PD6 +Mcu.Pin2=PE2 +Mcu.Pin20=PG1 +Mcu.Pin21=PA10 +Mcu.Pin22=PG14 +Mcu.Pin23=PE3 +Mcu.Pin24=PA8 +Mcu.Pin25=PN1 +Mcu.Pin26=PG15 +Mcu.Pin27=PG13 +Mcu.Pin28=PA15(JTDI) +Mcu.Pin29=PN3 +Mcu.Pin3=PB5 +Mcu.Pin30=PN0 +Mcu.Pin31=PN11 +Mcu.Pin32=PF7 +Mcu.Pin33=PN10 +Mcu.Pin34=PN9 +Mcu.Pin35=PN2 +Mcu.Pin36=PF9 +Mcu.Pin37=PF10 +Mcu.Pin38=PN6 +Mcu.Pin39=PH0-OSC_IN(PH0) +Mcu.Pin4=PF4 +Mcu.Pin40=PH1-OSC_OUT(PH1) +Mcu.Pin41=PN8 +Mcu.Pin42=PN4 +Mcu.Pin43=PN5 +Mcu.Pin44=PB12 +Mcu.Pin45=PA0 +Mcu.Pin46=PA1 +Mcu.Pin47=PA4 +Mcu.Pin48=PF11 +Mcu.Pin49=PO3 +Mcu.Pin5=PF0 +Mcu.Pin50=PP10 +Mcu.Pin51=PB14 +Mcu.Pin52=PB15 +Mcu.Pin53=PF15 +Mcu.Pin54=PP12 +Mcu.Pin55=PP14 +Mcu.Pin56=PP2 +Mcu.Pin57=PP5 +Mcu.Pin58=PO2 +Mcu.Pin59=PP1 +Mcu.Pin6=PG0 +Mcu.Pin60=PB11 +Mcu.Pin61=PB13 +Mcu.Pin62=PA6 +Mcu.Pin63=PP11 +Mcu.Pin64=PP15 +Mcu.Pin65=PP3 +Mcu.Pin66=PP0 +Mcu.Pin67=PP7 +Mcu.Pin68=PP8 +Mcu.Pin69=PP13 +Mcu.Pin7=PB9 +Mcu.Pin70=PP4 +Mcu.Pin71=PO4 +Mcu.Pin72=PP6 +Mcu.Pin73=PO0 +Mcu.Pin74=PP9 +Mcu.Pin75=VP_CRC_VS_CRC +Mcu.Pin76=VP_DMA2D_VS_DMA2D +Mcu.Pin77=VP_EXTMEM_MANAGER_SIG_Activate_EXTMEM +Mcu.Pin78=VP_FLASH_SIG_Activate_FlashIP +Mcu.Pin79=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin8=PB3(JTDO/TRACESWO) +Mcu.Pin80=VP_GPDMA1_VS_GPDMACH0 +Mcu.Pin81=VP_GPU2D_VS_GPU2D +Mcu.Pin82=VP_HPDMA1_VS_HPDMACH0 +Mcu.Pin83=VP_HPDMA1_VS_HPDMACH1 +Mcu.Pin84=VP_ICACHE_GPU2D_VS_ICACHE +Mcu.Pin85=VP_JPEG_VS_JPEG +Mcu.Pin86=VP_SBS_VS-SBS +Mcu.Pin87=VP_SYS_VS_tim6 +Mcu.Pin88=VP_XSPI1_VS_hexa +Mcu.Pin89=VP_XSPI2_VS_octo +Mcu.Pin9=PF1 +Mcu.Pin90=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin91=VP_STMicroelectronics.X-CUBE-TOUCHGFX_App_VS_GraphicsJjApplication_4.26.1 +Mcu.PinsNb=92 +Mcu.ThirdParty0=STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1 +Mcu.ThirdParty0_ContextShortName=App +Mcu.ThirdParty0_Instance=STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App +Mcu.ThirdPartyNb=1 +Mcu.UserConstants= +Mcu.UserName=STM32H7S7L8HxH +MxCube.Version=6.18.1 +MxDb.Version=DB.6.0.181 +NVIC1.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.ForceEnableDMAVector=true +NVIC1.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC1.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC1.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC2.ADF1_FLT0_IRQn=true\:7\:0\:true\:false\:true\:true\:true\:true\:true +NVIC2.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC2.DMA2D_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:false +NVIC2.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC2.EXTI3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true +NVIC2.ForceEnableDMAVector=true +NVIC2.GPDMA1_Channel0_IRQn=true\:5\:0\:true\:false\:true\:true\:false\:true\:true +NVIC2.GPU2D_ER_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true +NVIC2.GPU2D_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true +NVIC2.HPDMA1_Channel0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true +NVIC2.HPDMA1_Channel1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true +NVIC2.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC2.JPEG_IRQn=true\:8\:0\:true\:false\:true\:true\:true\:true\:true +NVIC2.LTDC_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:false +NVIC2.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC2.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC2.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false +NVIC2.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC2.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false +NVIC2.SavedPendsvIrqHandlerGenerated=true +NVIC2.SavedSvcallIrqHandlerGenerated=true +NVIC2.SavedSystickIrqHandlerGenerated=true +NVIC2.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false +NVIC2.TIM6_IRQn=true\:4\:0\:true\:false\:true\:false\:false\:true\:true +NVIC2.TimeBase=TIM6_IRQn +NVIC2.TimeBaseIP=TIM6 +NVIC2.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +PA0.GPIOParameters=PinAttribute +PA0.Mode=RGB888 +PA0.PinAttribute=Appli +PA0.Signal=LTDC_G3 +PA1.GPIOParameters=PinAttribute +PA1.Mode=RGB888 +PA1.PinAttribute=Appli +PA1.Signal=LTDC_G2 +PA10.GPIOParameters=PinAttribute +PA10.Mode=RGB888 +PA10.PinAttribute=Appli +PA10.Signal=LTDC_B4 +PA11.GPIOParameters=PinAttribute +PA11.Mode=RGB888 +PA11.PinAttribute=Appli +PA11.Signal=LTDC_B3 +PA12.GPIOParameters=PinAttribute +PA12.Mode=RGB888 +PA12.PinAttribute=Appli +PA12.Signal=LTDC_B2 +PA15(JTDI).GPIOParameters=PinAttribute +PA15(JTDI).Mode=RGB888 +PA15(JTDI).PinAttribute=Appli +PA15(JTDI).Signal=LTDC_R5 +PA4.GPIOParameters=PinAttribute +PA4.Mode=Half_Duplex_Master_Tx +PA4.PinAttribute=Appli +PA4.Signal=I2S6_WS +PA6.GPIOParameters=PinAttribute +PA6.Locked=true +PA6.Mode=RGB888 +PA6.PinAttribute=Appli +PA6.Signal=LTDC_B7 +PA8.GPIOParameters=PinAttribute +PA8.Mode=RGB888 +PA8.PinAttribute=Appli +PA8.Signal=LTDC_B6 +PA9.GPIOParameters=PinAttribute +PA9.Mode=RGB888 +PA9.PinAttribute=Appli +PA9.Signal=LTDC_B5 +PB11.GPIOParameters=PinAttribute +PB11.Mode=RGB888 +PB11.PinAttribute=Appli +PB11.Signal=LTDC_G6 +PB12.GPIOParameters=PinAttribute +PB12.Mode=RGB888 +PB12.PinAttribute=Appli +PB12.Signal=LTDC_G5 +PB13.GPIOParameters=PinAttribute +PB13.Mode=RGB888 +PB13.PinAttribute=Appli +PB13.Signal=LTDC_G4 +PB14.GPIOParameters=PinAttribute +PB14.Locked=true +PB14.Mode=RGB888 +PB14.PinAttribute=Appli +PB14.Signal=LTDC_DE +PB15.GPIOParameters=PinAttribute +PB15.Mode=RGB888 +PB15.PinAttribute=Appli +PB15.Signal=LTDC_G7 +PB3(JTDO/TRACESWO).GPIOParameters=PinAttribute +PB3(JTDO/TRACESWO).Locked=true +PB3(JTDO/TRACESWO).Mode=RGB888 +PB3(JTDO/TRACESWO).PinAttribute=Appli +PB3(JTDO/TRACESWO).Signal=LTDC_R4 +PB4(NJTRST).GPIOParameters=PinAttribute +PB4(NJTRST).Locked=true +PB4(NJTRST).Mode=RGB888 +PB4(NJTRST).PinAttribute=Appli +PB4(NJTRST).Signal=LTDC_R3 +PB5.GPIOParameters=PinAttribute +PB5.Mode=Half_Duplex_Master_Tx +PB5.PinAttribute=Appli +PB5.Signal=I2S6_SDO +PB6.GPIOParameters=PinAttribute +PB6.Locked=true +PB6.Mode=I2C +PB6.PinAttribute=Appli +PB6.Signal=I2C1_SCL +PB9.GPIOParameters=PinAttribute +PB9.Mode=I2C +PB9.PinAttribute=Appli +PB9.Signal=I2C1_SDA +PC12.GPIOParameters=PinAttribute +PC12.Mode=Half_Duplex_Master_Tx +PC12.PinAttribute=Appli +PC12.Signal=I2S6_CK +PCC.Bar.Display=Horizontal Bar +PCC.Checker=false +PCC.Display=Plot\: All Steps +PCC.Line=STM32H7R7/7S7 +PCC.MCU=STM32H7S7L8HxH +PCC.PartNumber=STM32H7S7L8HxH +PCC.SequenceTime=1.0 ms +PCC.SequenceTime.Unit=ms +PCC.Series=STM32H7 +PCC.Temperature=25 +PCC.Vdd=3.0 +PD6.GPIOParameters=GPIO_Label,PinAttribute +PD6.GPIO_Label=ADF1_D +PD6.Locked=true +PD6.Mode=MOD_ADF_CCK +PD6.PinAttribute=Appli +PD6.Signal=ADF1_SDI0 +PE11.GPIOParameters=PinAttribute +PE11.Mode=RGB888 +PE11.PinAttribute=Appli +PE11.Signal=LTDC_VSYNC +PE15.ContextOwner=Appli +PE15.GPIOParameters=PinState,GPIO_Label,PinAttribute +PE15.GPIO_Label=LCD_EN +PE15.Locked=true +PE15.PinAttribute=Appli +PE15.PinState=GPIO_PIN_SET +PE15.Signal=GPIO_Output +PE2.GPIOParameters=GPIO_Label,PinAttribute +PE2.GPIO_Label=ADF1_CK +PE2.Locked=true +PE2.Mode=MOD_MDF_CCK0 +PE2.PinAttribute=Appli +PE2.Signal=ADF1_CCK0 +PE3.ContextOwner=Appli +PE3.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI,PinAttribute +PE3.GPIO_Label=TP_IRQ +PE3.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING +PE3.GPIO_PuPd=GPIO_PULLDOWN +PE3.Locked=true +PE3.PinAttribute=Appli +PE3.Signal=GPXTI3 +PF0.GPIOParameters=PinAttribute +PF0.Locked=true +PF0.Mode=RGB888 +PF0.PinAttribute=Appli +PF0.Signal=LTDC_R2 +PF1.ContextOwner=Appli +PF1.GPIOParameters=GPIO_Speed,GPIO_Label,PinAttribute +PF1.GPIO_Label=VSYNC_FREQ +PF1.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM +PF1.Locked=true +PF1.PinAttribute=Appli +PF1.Signal=GPIO_Output +PF10.GPIOParameters=PinAttribute +PF10.Mode=RGB888 +PF10.PinAttribute=Appli +PF10.Signal=LTDC_R1 +PF11.GPIOParameters=PinAttribute +PF11.Mode=RGB888 +PF11.PinAttribute=Appli +PF11.Signal=LTDC_B0 +PF15.GPIOParameters=PinAttribute +PF15.Locked=true +PF15.Mode=RGB888 +PF15.PinAttribute=Appli +PF15.Signal=LTDC_G1 +PF2.ContextOwner=Appli +PF2.GPIOParameters=GPIO_Speed,GPIO_Label,PinAttribute +PF2.GPIO_Label=RENDER_TIME +PF2.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM +PF2.Locked=true +PF2.PinAttribute=Appli +PF2.Signal=GPIO_Output +PF3.ContextOwner=Appli +PF3.GPIOParameters=GPIO_Speed,GPIO_Label,PinAttribute +PF3.GPIO_Label=FRAME_RATE +PF3.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM +PF3.Locked=true +PF3.PinAttribute=Appli +PF3.Signal=GPIO_Output +PF4.ContextOwner=Appli +PF4.GPIOParameters=GPIO_Label,PinAttribute +PF4.GPIO_Label=MCU_ACTIVE +PF4.Locked=true +PF4.PinAttribute=Appli +PF4.Signal=GPIO_Output +PF7.GPIOParameters=PinAttribute +PF7.Mode=RGB888 +PF7.PinAttribute=Appli +PF7.Signal=LTDC_G0 +PF9.GPIOParameters=PinAttribute +PF9.Mode=RGB888 +PF9.PinAttribute=Appli +PF9.Signal=LTDC_R0 +PG0.GPIOParameters=PinAttribute +PG0.Mode=RGB888 +PG0.PinAttribute=Appli +PG0.Signal=LTDC_R7 +PG1.GPIOParameters=PinAttribute +PG1.Mode=RGB888 +PG1.PinAttribute=Appli +PG1.Signal=LTDC_R6 +PG13.GPIOParameters=PinAttribute +PG13.Mode=RGB888 +PG13.PinAttribute=Appli +PG13.Signal=LTDC_CLK +PG14.GPIOParameters=PinAttribute +PG14.Locked=true +PG14.Mode=RGB888 +PG14.PinAttribute=Appli +PG14.Signal=LTDC_B1 +PG15.ContextOwner=Appli +PG15.GPIOParameters=PinState,GPIO_Label,PinAttribute +PG15.GPIO_Label=LCD_BL_CTRL +PG15.Locked=true +PG15.PinAttribute=Appli +PG15.PinState=GPIO_PIN_SET +PG15.Signal=GPIO_Output +PG2.GPIOParameters=PinAttribute +PG2.Mode=RGB888 +PG2.PinAttribute=Appli +PG2.Signal=LTDC_HSYNC +PH0-OSC_IN(PH0).GPIOParameters=PinAttribute +PH0-OSC_IN(PH0).Mode=HSE-External-Clock-Source +PH0-OSC_IN(PH0).PinAttribute=Free +PH0-OSC_IN(PH0).Signal=RCC_OSC_IN +PH1-OSC_OUT(PH1).ContextOwner=Appli +PH1-OSC_OUT(PH1).GPIOParameters=GPIO_PuPd,GPIO_Label,PinAttribute +PH1-OSC_OUT(PH1).GPIO_Label=MIC_DET +PH1-OSC_OUT(PH1).GPIO_PuPd=GPIO_PULLUP +PH1-OSC_OUT(PH1).Locked=true +PH1-OSC_OUT(PH1).PinAttribute=Appli +PH1-OSC_OUT(PH1).Signal=GPIO_Input +PN0.GPIOParameters=PinAttribute +PN0.Mode=XSPI2_Port2Octo +PN0.PinAttribute=Boot +PN0.Signal=XSPIM_P2_DQS0 +PN1.GPIOParameters=PinAttribute +PN1.Mode=XSPI2_NCS1_Port2 +PN1.PinAttribute=Boot +PN1.Signal=XSPIM_P2_NCS1 +PN10.GPIOParameters=PinAttribute +PN10.Mode=XSPI2_Port2Octo +PN10.PinAttribute=Boot +PN10.Signal=XSPIM_P2_IO6 +PN11.GPIOParameters=PinAttribute +PN11.Mode=XSPI2_Port2Octo +PN11.PinAttribute=Boot +PN11.Signal=XSPIM_P2_IO7 +PN2.GPIOParameters=PinAttribute +PN2.Mode=XSPI2_Port2Octo +PN2.PinAttribute=Boot +PN2.Signal=XSPIM_P2_IO0 +PN3.GPIOParameters=PinAttribute +PN3.Mode=XSPI2_Port2Octo +PN3.PinAttribute=Boot +PN3.Signal=XSPIM_P2_IO1 +PN4.GPIOParameters=PinAttribute +PN4.Mode=XSPI2_Port2Octo +PN4.PinAttribute=Boot +PN4.Signal=XSPIM_P2_IO2 +PN5.GPIOParameters=PinAttribute +PN5.Mode=XSPI2_Port2Octo +PN5.PinAttribute=Boot +PN5.Signal=XSPIM_P2_IO3 +PN6.GPIOParameters=PinAttribute +PN6.Mode=XSPI2_Port2Octo +PN6.PinAttribute=Boot +PN6.Signal=XSPIM_P2_CLK +PN8.GPIOParameters=PinAttribute +PN8.Mode=XSPI2_Port2Octo +PN8.PinAttribute=Boot +PN8.Signal=XSPIM_P2_IO4 +PN9.GPIOParameters=PinAttribute +PN9.Mode=XSPI2_Port2Octo +PN9.PinAttribute=Boot +PN9.Signal=XSPIM_P2_IO5 +PO0.GPIOParameters=PinAttribute +PO0.Mode=XSPI1_NCS1_Port1 +PO0.PinAttribute=Boot +PO0.Signal=XSPIM_P1_NCS1 +PO2.GPIOParameters=PinAttribute +PO2.Mode=XSPI1_Port1Hexa +PO2.PinAttribute=Boot +PO2.Signal=XSPIM_P1_DQS0 +PO3.GPIOParameters=PinAttribute +PO3.Mode=XSPI1_Port1Hexa +PO3.PinAttribute=Boot +PO3.Signal=XSPIM_P1_DQS1 +PO4.GPIOParameters=PinAttribute +PO4.Mode=XSPI1_Port1Hexa +PO4.PinAttribute=Boot +PO4.Signal=XSPIM_P1_CLK +PP0.GPIOParameters=PinAttribute +PP0.Mode=XSPI1_Port1Hexa +PP0.PinAttribute=Boot +PP0.Signal=XSPIM_P1_IO0 +PP1.GPIOParameters=PinAttribute +PP1.Mode=XSPI1_Port1Hexa +PP1.PinAttribute=Boot +PP1.Signal=XSPIM_P1_IO1 +PP10.GPIOParameters=PinAttribute +PP10.Mode=XSPI1_Port1Hexa +PP10.PinAttribute=Boot +PP10.Signal=XSPIM_P1_IO10 +PP11.GPIOParameters=PinAttribute +PP11.Mode=XSPI1_Port1Hexa +PP11.PinAttribute=Boot +PP11.Signal=XSPIM_P1_IO11 +PP12.GPIOParameters=PinAttribute +PP12.Mode=XSPI1_Port1Hexa +PP12.PinAttribute=Boot +PP12.Signal=XSPIM_P1_IO12 +PP13.GPIOParameters=PinAttribute +PP13.Mode=XSPI1_Port1Hexa +PP13.PinAttribute=Boot +PP13.Signal=XSPIM_P1_IO13 +PP14.GPIOParameters=PinAttribute +PP14.Mode=XSPI1_Port1Hexa +PP14.PinAttribute=Boot +PP14.Signal=XSPIM_P1_IO14 +PP15.GPIOParameters=PinAttribute +PP15.Mode=XSPI1_Port1Hexa +PP15.PinAttribute=Boot +PP15.Signal=XSPIM_P1_IO15 +PP2.GPIOParameters=PinAttribute +PP2.Mode=XSPI1_Port1Hexa +PP2.PinAttribute=Boot +PP2.Signal=XSPIM_P1_IO2 +PP3.GPIOParameters=PinAttribute +PP3.Mode=XSPI1_Port1Hexa +PP3.PinAttribute=Boot +PP3.Signal=XSPIM_P1_IO3 +PP4.GPIOParameters=PinAttribute +PP4.Mode=XSPI1_Port1Hexa +PP4.PinAttribute=Boot +PP4.Signal=XSPIM_P1_IO4 +PP5.GPIOParameters=PinAttribute +PP5.Mode=XSPI1_Port1Hexa +PP5.PinAttribute=Boot +PP5.Signal=XSPIM_P1_IO5 +PP6.GPIOParameters=PinAttribute +PP6.Mode=XSPI1_Port1Hexa +PP6.PinAttribute=Boot +PP6.Signal=XSPIM_P1_IO6 +PP7.GPIOParameters=PinAttribute +PP7.Mode=XSPI1_Port1Hexa +PP7.PinAttribute=Boot +PP7.Signal=XSPIM_P1_IO7 +PP8.GPIOParameters=PinAttribute +PP8.Mode=XSPI1_Port1Hexa +PP8.PinAttribute=Boot +PP8.Signal=XSPIM_P1_IO8 +PP9.GPIOParameters=PinAttribute +PP9.Mode=XSPI1_Port1Hexa +PP9.PinAttribute=Boot +PP9.Signal=XSPIM_P1_IO9 +PinOutPanel.CurrentBGAView=Top +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32H7S7L8HxH +ProjectManager.FirmwarePackage=STM32Cube FW_H7RS V1.3.0 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext=Boot +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=App-0x1000,Boot-0x1000,ExtMemLoader-0x1000 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=STM32H7S78-DK.ioc +ProjectManager.ProjectName=STM32H7S78-DK +ProjectManager.ProjectStructure=Boot\:Boot Project\:true;App\:Appli Project\:true;ExtMemLoader\:ExtMemLoader Project\:false; +ProjectManager.RegisterCallBack=ADC,MDF,SAI,SPI,I2S,XSPI,I2C +ProjectManager.StackSize=App-0x1000,Boot-0x1000,ExtMemLoader-0x1000 +ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false-Boot,2-MX_GPIO_Init-GPIO-false-HAL-true-Boot,3-MX_HPDMA1_Init-HPDMA1-false-HAL-true-Boot,4-MX_GPDMA1_Init-GPDMA1-false-HAL-true-Boot,5-MX_XSPI1_Init-XSPI1-false-HAL-true-Boot,6-MX_XSPI2_Init-XSPI2-false-HAL-true-Boot,7-MX_FLASH_Init-FLASH-false-HAL-true-Boot,8-MX_SBS_Init-SBS-false-HAL-true-Boot,9-MX_EXTMEM_MANAGER_Init-EXTMEM_MANAGER-false-HAL-false-Boot,1-SystemClock_Config-RCC-false-HAL-false-Appli,2-MX_GPIO_Init-GPIO-false-HAL-true-Appli,3-MX_HPDMA1_Init-HPDMA1-false-HAL-true-Appli,4-MX_GPDMA1_Init-GPDMA1-false-HAL-true-Appli,5-MX_LTDC_Init-LTDC-false-HAL-true-Appli,6-MX_CRC_Init-CRC-false-HAL-true-Appli,7-MX_DMA2D_Init-DMA2D-false-HAL-true-Appli,8-MX_JPEG_Init-JPEG-false-HAL-true-Appli,9-MX_FLASH_Init-FLASH-false-HAL-true-Appli,10-MX_I2C1_Init-I2C1-false-HAL-true-Appli,11-MX_GPU2D_Init-GPU2D-false-HAL-true-Appli,12-MX_ICACHE_GPU2D_Init-ICACHE_GPU2D-false-HAL-true-Appli,13-MX_ADF1_Init-ADF1-false-HAL-true-Appli,15-MX_TouchGFX_Init-STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App-false-HAL-false-Appli,0-MX_CORTEX_M7_BOOT_Init-CORTEX_M7_BOOT-false-HAL-true-Boot,0-MX_CORTEX_M7_APPLI_Init-CORTEX_M7_APPLI-false-HAL-true-Appli,16-MX_TouchGFX_Process-STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App-false-HAL-false-Appli,1-SystemClock_Config-RCC-false-HAL-false-ExtMemLoader,2-MX_HPDMA1_Init-HPDMA1-false-HAL-true-ExtMemLoader,3-MX_GPDMA1_Init-GPDMA1-false-HAL-true-ExtMemLoader,4-MX_EXTMEM_MANAGER_Init-EXTMEM_MANAGER-false-HAL-false-ExtMemLoader +RCC.ADCFreq_Value=24576000 +RCC.ADFFreq_Value=24576000 +RCC.AHB1234Freq_Value=300000000 +RCC.AHB5ClockFreq_Value=300000000 +RCC.APB1Freq_Value=150000000 +RCC.APB2Freq_Value=150000000 +RCC.APB4Freq_Value=150000000 +RCC.APB5Freq_Value=150000000 +RCC.AXIClockFreq_Value=300000000 +RCC.Adf1ClockSelection=RCC_ADF1CLKSOURCE_PLL2P +RCC.BMPRE=RCC_HCLK_DIV2 +RCC.CECFreq_Value=32768 +RCC.CKPERFreq_Value=64000000 +RCC.CPREFreq_Value=600000000 +RCC.CortexFreq_Value=600000000 +RCC.CpuClockFreq_Value=600000000 +RCC.DIVM1=4 +RCC.DIVM2=5 +RCC.DIVM3=2 +RCC.DIVN1=200 +RCC.DIVN3=50 +RCC.DIVP1Freq_Value=600000000 +RCC.DIVP2=25 +RCC.DIVP2Freq_Value=24576000 +RCC.DIVP3Freq_Value=300000000 +RCC.DIVQ1Freq_Value=600000000 +RCC.DIVQ2=10 +RCC.DIVQ2Freq_Value=61440000 +RCC.DIVQ3Freq_Value=300000000 +RCC.DIVR1Freq_Value=600000000 +RCC.DIVR2Freq_Value=307200000 +RCC.DIVR3=24 +RCC.DIVR3Freq_Value=25000000 +RCC.DIVS1Freq_Value=600000000 +RCC.DIVS2Freq_Value=307200000 +RCC.DIVS3Freq_Value=300000000 +RCC.DIVT1Freq_Value=600000000 +RCC.DIVT2Freq_Value=307200000 +RCC.DIVT3Freq_Value=300000000 +RCC.DTSFreq_Value=32768 +RCC.ETH1Freq_Value=12288000 +RCC.ETHPHYFreq_Value=24000000 +RCC.FDCANFreq_Value=24000000 +RCC.FMCFreq_Value=300000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=300000000 +RCC.HSE_VALUE=24000000 +RCC.I2C1Freq_Value=150000000 +RCC.I2C23Freq_Value=150000000 +RCC.I2CI3C1Freq_Value=150000000 +RCC.IPParameters=ADCFreq_Value,ADFFreq_Value,AHB1234Freq_Value,AHB5ClockFreq_Value,APB1Freq_Value,APB2Freq_Value,APB4Freq_Value,APB5Freq_Value,AXIClockFreq_Value,Adf1ClockSelection,BMPRE,CECFreq_Value,CKPERFreq_Value,CPREFreq_Value,CortexFreq_Value,CpuClockFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN3,DIVP1Freq_Value,DIVP2,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1Freq_Value,DIVQ2,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3,DIVR3Freq_Value,DIVS1Freq_Value,DIVS2Freq_Value,DIVS3Freq_Value,DIVT1Freq_Value,DIVT2Freq_Value,DIVT3Freq_Value,DTSFreq_Value,ETH1Freq_Value,ETHPHYFreq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,I2C1Freq_Value,I2C23Freq_Value,I2CI3C1Freq_Value,LPTIM1Freq_Value,LPTIM23Freq_Value,LPTIM45Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,OSPI1Freq_Value,OSPI2Freq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSource,PPRE1,PPRE2,PPRE4,PPRE5,PSSIFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI1Freq_Value,SPI23Freq_Value,SPI45Freq_Value,SPI6CLockSelection,SPI6Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,SupplySource,TPIUFreq_Value,Tim1OutputFreq_Value,Tim2OutputFreq_Value,UCPDFreq_Value,USART1Freq_Value,USART234578Freq_Value,USBOFSFreq_Value,USBPHYFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,Xspi1ClockSelection,Xspi2ClockSelection +RCC.LPTIM1Freq_Value=150000000 +RCC.LPTIM23Freq_Value=150000000 +RCC.LPTIM45Freq_Value=150000000 +RCC.LPUART1Freq_Value=150000000 +RCC.LTDCFreq_Value=25000000 +RCC.MCO1PinFreq_Value=64000000 +RCC.MCO2PinFreq_Value=600000000 +RCC.OSPI1Freq_Value=307200000 +RCC.OSPI2Freq_Value=307200000 +RCC.PLL2FRACN=0 +RCC.PLL3FRACN=0 +RCC.PLLFRACN=0 +RCC.PLLSource=RCC_PLLSOURCE_HSE +RCC.PPRE1=RCC_APB1_DIV2 +RCC.PPRE2=RCC_APB2_DIV2 +RCC.PPRE4=RCC_APB4_DIV2 +RCC.PPRE5=RCC_APB5_DIV2 +RCC.PSSIFreq_Value=25000000 +RCC.RTCFreq_Value=32000 +RCC.SAI1Freq_Value=600000000 +RCC.SAI2Freq_Value=600000000 +RCC.SDMMCFreq_Value=307200000 +RCC.SPDIFRXFreq_Value=600000000 +RCC.SPI1Freq_Value=600000000 +RCC.SPI23Freq_Value=600000000 +RCC.SPI45Freq_Value=150000000 +RCC.SPI6CLockSelection=RCC_SPI6CLKSOURCE_PLL2Q +RCC.SPI6Freq_Value=61440000 +RCC.SYSCLKFreq_VALUE=600000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.SupplySource=PWR_DIRECT_SMPS_SUPPLY +RCC.TPIUFreq_Value=200000000 +RCC.Tim1OutputFreq_Value=300000000 +RCC.Tim2OutputFreq_Value=300000000 +RCC.UCPDFreq_Value=16000000 +RCC.USART1Freq_Value=150000000 +RCC.USART234578Freq_Value=150000000 +RCC.USBOFSFreq_Value=48000000 +RCC.USBPHYFreq_Value=24000000 +RCC.VCO1OutputFreq_Value=1200000000 +RCC.VCO2OutputFreq_Value=614400000 +RCC.VCO3OutputFreq_Value=600000000 +RCC.VCOInput1Freq_Value=6000000 +RCC.VCOInput2Freq_Value=4800000 +RCC.VCOInput3Freq_Value=12000000 +RCC.Xspi1ClockSelection=RCC_XSPI1CLKSOURCE_PLL2S +RCC.Xspi2ClockSelection=RCC_XSPI2CLKSOURCE_PLL2S +SBS.IPParameters=XSPIM1,XSPIM2 +SBS.XSPIM1=Disable +SBS.XSPIM2=Disable +SH.GPXTI3.0=GPIO_EXTI3 +SH.GPXTI3.ConfNb=1 +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.ApplicationCcGraphicsJjApplication=TouchGFXOoGenerator +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.GraphicsJjApplication_Checked=true +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.IPParameters=ApplicationCcGraphicsJjApplication,tgfx_display_interface,tgfx_hardware_accelerator,tgfx_oswrapper,tgfx_vsync,tgfx_video,tgfx_video_width,tgfx_video_height,tgfx_buffering_strategy,tgfx_vector_rendering,tgfx_nemap_accelerator,tgfx_video_strategy,tgfx_vector_fonts +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_buffering_strategy=Double +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_display_interface=disp_ltdc +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_hardware_accelerator=dma_2d +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_nemap_accelerator=gpu2d_enabled +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_oswrapper=CMSIS V2 +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_vector_fonts=Enabled +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_vector_rendering=Hardware +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_video=Hardware +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_video_height=480 +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_video_strategy=0 +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_video_width=800 +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App.tgfx_vsync=vsync_ltdc +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_App_SwParameter=ApplicationCcGraphicsJjApplication\:TouchGFXOoGenerator; +STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1_IsPackSelfContextualization=true +VP_CRC_VS_CRC.Mode=CRC_Activate +VP_CRC_VS_CRC.Signal=CRC_VS_CRC +VP_DMA2D_VS_DMA2D.Mode=DMA2D_Activate +VP_DMA2D_VS_DMA2D.Signal=DMA2D_VS_DMA2D +VP_EXTMEM_MANAGER_SIG_Activate_EXTMEM.Mode=Activate_EXTMEM +VP_EXTMEM_MANAGER_SIG_Activate_EXTMEM.Signal=EXTMEM_MANAGER_SIG_Activate_EXTMEM +VP_FLASH_SIG_Activate_FlashIP.Mode=Activate_FlashIP +VP_FLASH_SIG_Activate_FlashIP.Signal=FLASH_SIG_Activate_FlashIP +VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2 +VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2 +VP_GPDMA1_VS_GPDMACH0.Mode=SIMPLEREQUEST_GPDMACH0 +VP_GPDMA1_VS_GPDMACH0.Signal=GPDMA1_VS_GPDMACH0 +VP_GPU2D_VS_GPU2D.Mode=GPU2D_Activate +VP_GPU2D_VS_GPU2D.Signal=GPU2D_VS_GPU2D +VP_HPDMA1_VS_HPDMACH0.Mode=SIMPLEREQUEST_HPDMACH0 +VP_HPDMA1_VS_HPDMACH0.Signal=HPDMA1_VS_HPDMACH0 +VP_HPDMA1_VS_HPDMACH1.Mode=SIMPLEREQUEST_HPDMACH1 +VP_HPDMA1_VS_HPDMACH1.Signal=HPDMA1_VS_HPDMACH1 +VP_ICACHE_GPU2D_VS_ICACHE.Mode=DefaultMode +VP_ICACHE_GPU2D_VS_ICACHE.Signal=ICACHE_GPU2D_VS_ICACHE +VP_JPEG_VS_JPEG.Mode=JPEG_Activate +VP_JPEG_VS_JPEG.Signal=JPEG_VS_JPEG +VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg +VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP +VP_SBS_VS-SBS.Mode=SBS +VP_SBS_VS-SBS.Signal=SBS_VS-SBS +VP_STMicroelectronics.X-CUBE-TOUCHGFX_App_VS_GraphicsJjApplication_4.26.1.Mode=GraphicsJjApplication +VP_STMicroelectronics.X-CUBE-TOUCHGFX_App_VS_GraphicsJjApplication_4.26.1.Signal=STMicroelectronics.X-CUBE-TOUCHGFX_App_VS_GraphicsJjApplication_4.26.1 +VP_SYS_VS_tim6.Mode=TIM6 +VP_SYS_VS_tim6.Signal=SYS_VS_tim6 +VP_XSPI1_VS_hexa.Mode=hexa_mode +VP_XSPI1_VS_hexa.Signal=XSPI1_VS_hexa +VP_XSPI2_VS_octo.Mode=octo_mode +VP_XSPI2_VS_octo.Signal=XSPI2_VS_octo +XSPI1.ChipSelectBoundary=HAL_XSPI_BONDARYOF_16KB +XSPI1.DelayHoldQuarterCycle=HAL_XSPI_DHQC_ENABLE +XSPI1.FifoThresholdByte=2 +XSPI1.FreeRunningClock=HAL_XSPI_FREERUNCLK_DISABLE +XSPI1.IPParameters=FifoThresholdByte,MemoryMode,MemoryType,MemorySize,FreeRunningClock,WrapSize,DelayHoldQuarterCycle,ChipSelectBoundary,Refresh +XSPI1.MemoryMode=HAL_XSPI_SINGLE_MEM +XSPI1.MemorySize=HAL_XSPI_SIZE_256MB +XSPI1.MemoryType=HAL_XSPI_MEMTYPE_APMEM_16BITS +XSPI1.Refresh=400 +XSPI1.WrapSize=HAL_XSPI_WRAP_32_BYTES +XSPI2.ChipSelectHighTimeCycle=2 +XSPI2.ClockPrescaler=0 +XSPI2.DelayHoldQuarterCycle=HAL_XSPI_DHQC_ENABLE +XSPI2.FifoThresholdByte=4 +XSPI2.IPParameters=FifoThresholdByte,MemoryType,ChipSelectHighTimeCycle,DelayHoldQuarterCycle,MemorySize,MemorySelect,ClockPrescaler +XSPI2.MemorySelect=HAL_XSPI_CSSEL_NCS1 +XSPI2.MemorySize=HAL_XSPI_SIZE_1GB +XSPI2.MemoryType=HAL_XSPI_MEMTYPE_MACRONIX +board=custom +rtos.0.ip=FREERTOS diff --git a/Utilities/JPEG/jpeg_utils.c b/Utilities/JPEG/jpeg_utils.c new file mode 100644 index 0000000..e83f6f1 --- /dev/null +++ b/Utilities/JPEG/jpeg_utils.c @@ -0,0 +1,1984 @@ +/** + ****************************************************************************** + * @file jpeg_utils.c + * @author MCD Application Team + * @brief This driver provides JPEG MCU (Minimum Coded Unit) blocks to RGB and RGB to JPEG MCU conversion functions. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 + [..] + The STM32 HW JPEG decoder/encoder peripheral allows to decode/encode jpeg images. + In decoding, the STM32 HW JPEG data output are organized in blocks called MCU (Minimum Coded Unit) + as specified in the jpeg standard. + In encoding, the STM32 HW JPEG data input must be organized in MCU blocks. + Depending of the image color space and chrominance sampling, an MCU is generally organized in : + N luminance (Y) blocks + a Blue chrominance (Cb) block + a Red chrominance (Cr) block. + Each block size is 8x8 samples. + + The STM32 HW JPEG supports 3 possible color space : + - YCbCr : an MCU is composed of 3 color components : Y , Cb and Cr + - GrayScale : an MCU is composed of 1 single color component : Y + - CMYK : an MCU is composed of 4 color components : Cyan, Magenta, Yellow, and Key (blacK) + + This utility file should be used on top of the STM32 HAL JPEG driver. + In decoding, it allows to convert MCU blocks to RGB888 or ARGB8888 pixels stored to a destination + frame buffer that can be displayed. + In encoding, it allows to convert RGB888 or ARGB8888 pixels to MCU blocks. + + This utility supports following MCU Chroma sampling format and color space : + - YCbCr 4:2:0 : Each MCU is composed of 4 Y 8x8 blocks + 1 Cb 8x8 block + Cr 8x8 block + - YCbCr 4:2:2 : Each MCU is composed of 2 Y 8x8 blocks + 1 Cb 8x8 block + Cr 8x8 block + - YCbCr 4:4:4 : Each MCU is composed of 1 Y 8x8 block + 1 Cb 8x8 block + Cr 8x8 block + - GrayScale : Each MCU is composed of 1 Y 8x8 block + - CMYK : Each MCU is composed of 1 Cyan 8x8 block + 1 Magenta 8x8 block + 1 Yellow 8x8 block + 1 Key 8x8 block. + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + - The configuration file "jpeg_utils_conf_template.h" is used to configure this utility + providing some useful flexibilities. + This file should be copied to the application folder and modified as follows: + - Rename it to "jpeg_utils_conf.h". + - Update the name of the JPEG driver's header file, depending on the EVAL board you are using. + + Example if using the STM32F769I-EVAL board : + - Copy the file "jpeg_utils_conf_template.h" to the application folder and rename it to "jpeg_utils_conf.h" + - Edit the "jpeg_utils_conf.h" and change lines 51 and 52 as follow : + #include "stm32f7xx_hal.h" + #include "stm32f7xx_hal_jpeg.h" + + Using this configuration file, user can change the following settings: + - Use RGB888 or ARGB8888 or RGB565 by setting the constant JPEG_RGB_FORMAT respectively to JPEG_RGB888, JPEG_ARGB8888 JPEG_RGB565. + - Swap RED, and Blue offsets if user needs to change the color order to BGR (instead of RGB) by setting: + #define JPEG_SWAP_RB 1 + - Enable or disable the decoding post-processing functions (YCbCr to RGB conversion functions) by setting the define USE_JPEG_DECODER + respectively to 0 or 1. + - Enable or disable the encoding pre-processing functions (RGB to YCbCr conversion functions) by setting the define USE_JPEG_ENCODER + respectively to 0 or 1. + + [..]For Decoding: + - First, function "JPEG_InitColorTables" should be called to initialize the YCbCr to RGB color + conversion tables. This function needs to be called only one time at the beginning of the + program whatever the number of jpeg files to be decoded. + + - As soon as the JPEG HW peripheral finished parsing the header of the JPEG input file, + the HAL JPEG callback "HAL_JPEG_InfoReadyCallback" is launched providing the jpeg file + characteristics found in its header. + User can then call the utility function "JPEG_GetDecodeColorConvertFunc" with these + information and retrieve the corresponding color conversion function and number of MCUs. + + Then each time an integer number of MCUs are available (from the HW JPEG output), user + can call the retrieved function to convert these HW JPEG output data to RGB888 or + ARGB8888 pixel stored to the specified destination buffer. + + [..]For Encoding: + - First, function "JPEG_InitColorTables" should be called to initialize the YCbCr/RGB color + conversion tables. This function needs to be called only one time at the beginning of the + program whatever the number of jpeg files to be encoded or decoded. + + - First Use the utility function "JPEG_GetEncodeColorConvertFunc" with the input image information + to retrieve the corresponding color conversion function and number of MCUs. + + Then each time an RGB input buffer is available, user can call the retrieved function to convert + RGB data to MCU blocks stored to the specified destination buffer. + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "jpeg_utils.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @defgroup JPEG JPEG +* @brief JPEG YCbCr blocks <-> RGB conversion utilities +* @{ +*/ + +/** @defgroup JPEG_Private_Types JPEG Private Types +* @{ +*/ +/* Private typedef -----------------------------------------------------------*/ +typedef struct __JPEG_MCU_RGB_ConvertorTypeDef +{ + uint32_t ColorSpace; + uint32_t ChromaSubsampling; + + uint32_t ImageWidth; + uint32_t ImageHeight; + uint32_t ImageSize_Bytes; + + uint32_t LineOffset; + uint32_t BlockSize; + + uint32_t H_factor; + uint32_t V_factor; + + uint32_t WidthExtend; + uint32_t ScaledWidth; + + uint32_t MCU_Total_Nb; + + uint16_t *Y_MCU_LUT; + uint16_t *Cb_MCU_LUT; + uint16_t *Cr_MCU_LUT; + uint16_t *K_MCU_LUT; + +}JPEG_MCU_RGB_ConvertorTypeDef; +/** +* @} +*/ + +/** @defgroup JPEG_Private_Defines JPEG Private Defines +* @{ +*/ +/* Private define ------------------------------------------------------------*/ +#define YCBCR_420_BLOCK_SIZE 384 /* YCbCr 4:2:0 MCU : 4 8x8 blocks of Y + 1 8x8 block of Cb + 1 8x8 block of Cr */ +#define YCBCR_422_BLOCK_SIZE 256 /* YCbCr 4:2:2 MCU : 2 8x8 blocks of Y + 1 8x8 block of Cb + 1 8x8 block of Cr */ +#define YCBCR_444_BLOCK_SIZE 192 /* YCbCr 4:4:4 MCU : 1 8x8 block of Y + 1 8x8 block of Cb + 1 8x8 block of Cr */ + +#define GRAY_444_BLOCK_SIZE 64 /* GrayScale MCU : 1 8x8 block of Y */ + +#define CMYK_444_BLOCK_SIZE 256 /* CMYK MCU : 1 8x8 blocks of Cyan + 1 8x8 block Magenta + 1 8x8 block of Yellow and 1 8x8 block of BlacK */ + +#if (JPEG_RGB_FORMAT == JPEG_ARGB8888) + #define JPEG_GREEN_OFFSET 8 /* Offset of the GREEN color in a pixel */ + #define JPEG_ALPHA_OFFSET 24 /* Offset of the Transparency Alpha in a pixel */ + #define JPEG_BYTES_PER_PIXEL 4 /* Number of bytes in a pixel */ + #if (JPEG_SWAP_RB == 0) + #define JPEG_RED_OFFSET 16 /* Offset of the RED color in a pixel */ + #define JPEG_BLUE_OFFSET 0 /* Offset of the BLUE color in a pixel */ + #else + #define JPEG_RED_OFFSET 0 /* Offset of the RED color in a pixel */ + #define JPEG_BLUE_OFFSET 16 /* Offset of the BLUE color in a pixel */ + #endif /* JPEG_SWAP_RB */ + +#elif(JPEG_RGB_FORMAT == JPEG_RGB888) + #define JPEG_GREEN_OFFSET 8 /* Offset of the GREEN color in a pixel */ + #define JPEG_BYTES_PER_PIXEL 3 /* Number of bytes in a pixel */ + + #if (JPEG_SWAP_RB == 0) + #define JPEG_RED_OFFSET 16 /* Offset of the RED color in a pixel */ + #define JPEG_BLUE_OFFSET 0 /* Offset of the BLUE color in a pixel */ + #else + #define JPEG_RED_OFFSET 0 /* Offset of the RED color in a pixel */ + #define JPEG_BLUE_OFFSET 16 /* Offset of the BLUE color in a pixel */ + #endif /* JPEG_SWAP_RB */ + +#elif (JPEG_RGB_FORMAT == JPEG_RGB565) + #define JPEG_GREEN_OFFSET 5 /* Offset of the GREEN color in a pixel */ + #define JPEG_BYTES_PER_PIXEL 2 /* Number of bytes in a pixel */ + #define JPEG_RGB565_GREEN_MASK 0x07E0 /* Mask of Green component in RGB565 Format */ + + #if (JPEG_SWAP_RB == 0) + #define JPEG_RED_OFFSET 11 /* Offset of the RED color in a pixel */ + #define JPEG_BLUE_OFFSET 0 /* Offset of the BLUE color in a pixel */ + #define JPEG_RGB565_RED_MASK 0xF800 /* Mask of Red component in RGB565 Format */ + #define JPEG_RGB565_BLUE_MASK 0x001F /* Mask of Blue component in RGB565 Format */ + #else + #define JPEG_RED_OFFSET 0 /* Offset of the RED color in a pixel */ + #define JPEG_BLUE_OFFSET 11 /* Offset of the BLUE color in a pixel */ + #define JPEG_RGB565_RED_MASK 0x001F /* Mask of Red component in RGB565 Format */ + #define JPEG_RGB565_BLUE_MASK 0xF800 /* Mask of Blue component in RGB565 Format */ + #endif /* JPEG_SWAP_RB */ + +#else + + #error "unknown JPEG_RGB_FORMAT " + +#endif /* JPEG_RGB_FORMAT */ + +/** +* @} +*/ + +/** @defgroup JPEG_Private_Macros JPEG Private Macros +* @{ +*/ +/* Private macro -------------------------------------------------------------*/ +#if (USE_JPEG_DECODER == 1) +#define CLAMP(value) CLAMP_LUT[(value) + 0x100] /* Range limiting macro */ +#endif +#if (USE_JPEG_ENCODER == 1) +#define MAX(val1,val2) ((val1 > val2) ? val1 : val2) +#define CLAMP_8BITS(comp) ((comp) > 255 ? 255 : (comp)) /* Saturate component to 8-bit representation */ +#endif +/** +* @} +*/ + +/** @defgroup JPEG_Private_Variables JPEG Private Variables +* @{ +*/ +/* Private variables ---------------------------------------------------------*/ + +static JPEG_MCU_RGB_ConvertorTypeDef JPEG_ConvertorParams; + +#if (USE_JPEG_DECODER == 1) +static int32_t CR_RED_LUT[256]; /* Cr to Red color conversion Look Up Table */ +static int32_t CB_BLUE_LUT[256]; /* Cb to Blue color conversion Look Up Table */ +static int32_t CR_GREEN_LUT[256]; /* Cr to Green color conversion Look Up Table*/ +static int32_t CB_GREEN_LUT[256]; /* Cb to Green color conversion Look Up Table*/ +#endif /* USE_JPEG_DECODER == 1 */ + +#if (USE_JPEG_ENCODER == 1) +static int32_t RED_Y_LUT[256]; /* Red to Y color conversion Look Up Table */ +static int32_t RED_CB_LUT[256]; /* Red to Cb color conversion Look Up Table */ +static int32_t BLUE_CB_RED_CR_LUT[256]; /* Red to Cr and Blue to Cb color conversion Look Up Table */ +static int32_t GREEN_Y_LUT[256]; /* Green to Y color conversion Look Up Table*/ +static int32_t GREEN_CR_LUT[256]; /* Green to Cr color conversion Look Up Table*/ +static int32_t GREEN_CB_LUT[256]; /* Green to Cb color conversion Look Up Table*/ +static int32_t BLUE_Y_LUT[256]; /* Blue to Y color conversion Look Up Table */ +static int32_t BLUE_CR_LUT[256]; /* Blue to Cr color conversion Look Up Table */ + +/* Different MCU Look Up Table */ +static uint16_t JPEG_Y_MCU_LUT[256]; +static uint16_t JPEG_Y_MCU_444_LUT[64]; + +static uint16_t JPEG_Cb_MCU_420_LUT[256]; +static uint16_t JPEG_Cb_MCU_422_LUT[256]; +static uint16_t JPEG_Cb_MCU_444_LUT[64]; + +static uint16_t JPEG_Cr_MCU_420_LUT[256]; +static uint16_t JPEG_Cr_MCU_422_LUT[256]; +static uint16_t JPEG_Cr_MCU_444_LUT[64]; + +static uint16_t JPEG_K_MCU_420_LUT[256]; +static uint16_t JPEG_K_MCU_422_LUT[256]; +static uint16_t JPEG_K_MCU_444_LUT[64]; + +/* YCCK format blocks */ +uint8_t kBlocks[16][16]; +#endif /* USE_JPEG_ENCODER == 1 */ + +#if (USE_JPEG_DECODER == 1) +/* color clamp table : used for range limiting */ +static const uint8_t CLAMP_LUT[] = { +/* clamp range 0xffffffff to 0xffffff00 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* clamp range 0x00 to 0xff */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, +0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, +0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, +0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, +0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, +0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, +0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, +0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, +0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, +0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, +0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +/* clamp range 0x100 to 0x1ff */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +#endif /* USE_JPEG_DECODER == 1 */ +/** +* @} +*/ + +/** @defgroup JPEG_Private_FunctionPrototypes JPEG Private FunctionPrototypes +* @{ +*/ +/* Private function prototypes -----------------------------------------------*/ +#if (USE_JPEG_ENCODER == 1) +static uint32_t JPEG_ARGB_MCU_YCbCr420_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static uint32_t JPEG_ARGB_MCU_YCbCr422_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static uint32_t JPEG_ARGB_MCU_YCbCr444_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + + +static uint32_t JPEG_ARGB_MCU_Gray_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static uint32_t JPEG_ARGB_MCU_YCCK_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static void JPEG_Init_MCU_LUT(void); +static void JPEG_InitPreProcColorTables(void); +static uint8_t *JPEG_Set_K_Blocks(uint8_t *pMCUBuffer, uint8_t pKBlocks[16][16], uint32_t ChromaSampling); + +#endif /* USE_JPEG_ENCODER == 1 */ + +#if (USE_JPEG_DECODER == 1) +static uint32_t JPEG_MCU_YCbCr420_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static uint32_t JPEG_MCU_YCbCr422_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static uint32_t JPEG_MCU_YCbCr444_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + + +static uint32_t JPEG_MCU_Gray_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); + +static uint32_t JPEG_MCU_YCCK_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount); +static void JPEG_InitPostProcColorTables(void); +#endif /* USE_JPEG_DECODER == 1 */ + +/** +* @} +*/ + +/** @defgroup JPEG_Private_Functions JPEG Private Functions +* @{ +*/ + +#if (USE_JPEG_ENCODER == 1) +/** + * @brief Convert RGB to YCbCr 4:2:0 blocks pixels + * @param pInBuffer : pointer to input RGB888/ARGB8888 frame buffer. + * @param pOutBuffer : pointer to output YCbCr blocks buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from RGB to YCbCr + */ +static uint32_t JPEG_ARGB_MCU_YCbCr420_ConvertBlocks (uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef, colones; + + uint32_t refline; + int32_t ycomp, crcomp, cbcomp, offset; + + uint32_t red, green, blue; + + uint8_t *pOutAddr; + uint8_t *pInAddr; + + + numberMCU = ((3 * DataCount) / ( 2 * JPEG_BYTES_PER_PIXEL * YCBCR_420_BLOCK_SIZE)); + + currentMCU = BlockIndex; + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + pOutAddr = &pOutBuffer[0]; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *JPEG_ConvertorParams.H_factor) / JPEG_ConvertorParams.WidthExtend)*JPEG_ConvertorParams.V_factor; + + yRef = ((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend); + + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + if(((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend) == 0) + { + colones = JPEG_ConvertorParams.H_factor - JPEG_ConvertorParams.LineOffset; + } + else + { + colones = JPEG_ConvertorParams.H_factor; + } + offset = 0; + + for(i= 0; i < JPEG_ConvertorParams.V_factor; i+=2) + { + + pInAddr = &pInBuffer[0] ; + + for(j=0; j < colones; j+=2) + { + /* First Pixel */ +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + cbcomp = (int32_t)(*(RED_CB_LUT + red)) + (int32_t)(*(GREEN_CB_LUT + green)) + (int32_t)(*(BLUE_CB_RED_CR_LUT + blue)) + 128; + cbcomp = CLAMP_8BITS(cbcomp); + crcomp = (int32_t)(*(BLUE_CB_RED_CR_LUT + red)) + (int32_t)(*(GREEN_CR_LUT + green)) + (int32_t)(*(BLUE_CR_LUT + blue)) + 128; + crcomp = CLAMP_8BITS(crcomp); + + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset])) = (ycomp); + (*(pOutAddr + JPEG_ConvertorParams.Cb_MCU_LUT[offset])) = (cbcomp); + (*(pOutAddr + JPEG_ConvertorParams.Cr_MCU_LUT[offset])) = (crcomp); + + /* Second Pixel */ +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + JPEG_BYTES_PER_PIXEL + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + JPEG_BYTES_PER_PIXEL + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + JPEG_BYTES_PER_PIXEL + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_BYTES_PER_PIXEL + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_BYTES_PER_PIXEL + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_BYTES_PER_PIXEL + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset + 1])) = (ycomp); + + /* Third Pixel */ +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + JPEG_ConvertorParams.ScaledWidth + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + JPEG_ConvertorParams.ScaledWidth + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + JPEG_ConvertorParams.ScaledWidth + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset + JPEG_ConvertorParams.H_factor])) = (ycomp); + + /* Fourth Pixel */ +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BYTES_PER_PIXEL)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BYTES_PER_PIXEL)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BYTES_PER_PIXEL)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BYTES_PER_PIXEL + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BYTES_PER_PIXEL + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_ConvertorParams.ScaledWidth + JPEG_BYTES_PER_PIXEL + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset + JPEG_ConvertorParams.H_factor + 1])) = (ycomp); + + /****************/ + + pInAddr += JPEG_BYTES_PER_PIXEL * 2; + offset+=2; + } + offset += JPEG_ConvertorParams.H_factor + (JPEG_ConvertorParams.H_factor - colones); + refline += JPEG_ConvertorParams.ScaledWidth * 2 ; + } + pOutAddr += JPEG_ConvertorParams.BlockSize ; + } + return numberMCU; +} + +/** + * @brief Convert RGB to YCbCr 4:2:2 blocks pixels + * @param pInBuffer : pointer to input RGB888/ARGB8888 frame buffer. + * @param pOutBuffer : pointer to output YCbCr blocks buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from RGB to YCbCr + */ +static uint32_t JPEG_ARGB_MCU_YCbCr422_ConvertBlocks (uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef, colones; + + uint32_t refline; + int32_t ycomp, crcomp, cbcomp, offset; + + uint32_t red, green, blue; + + uint8_t *pOutAddr; + uint8_t *pInAddr; + + numberMCU = ((2 * DataCount) / (JPEG_BYTES_PER_PIXEL * YCBCR_422_BLOCK_SIZE)); + + currentMCU = BlockIndex; + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + pOutAddr = &pOutBuffer[0]; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *JPEG_ConvertorParams.H_factor) / JPEG_ConvertorParams.WidthExtend)*JPEG_ConvertorParams.V_factor; + + yRef = ((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend); + + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + if(((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend) == 0) + { + colones = JPEG_ConvertorParams.H_factor - JPEG_ConvertorParams.LineOffset; + } + else + { + colones = JPEG_ConvertorParams.H_factor; + } + offset = 0; + + for(i= 0; i < JPEG_ConvertorParams.V_factor; i+=1) + { + + pInAddr = &pInBuffer[0] ; + + for(j=0; j < colones; j+=2) + { + /* First Pixel */ +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + cbcomp = (int32_t)(*(RED_CB_LUT + red)) + (int32_t)(*(GREEN_CB_LUT + green)) + (int32_t)(*(BLUE_CB_RED_CR_LUT + blue)) + 128; + cbcomp = CLAMP_8BITS(cbcomp); + crcomp = (int32_t)(*(BLUE_CB_RED_CR_LUT + red)) + (int32_t)(*(GREEN_CR_LUT + green)) + (int32_t)(*(BLUE_CR_LUT + blue)) + 128; + crcomp = CLAMP_8BITS(crcomp); + + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset])) = ycomp; + (*(pOutAddr + JPEG_ConvertorParams.Cb_MCU_LUT[offset])) = cbcomp; + (*(pOutAddr + JPEG_ConvertorParams.Cr_MCU_LUT[offset])) = crcomp; + + /* Second Pixel */ +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline + JPEG_BYTES_PER_PIXEL)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline + JPEG_BYTES_PER_PIXEL)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline + JPEG_BYTES_PER_PIXEL)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_BYTES_PER_PIXEL + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_BYTES_PER_PIXEL + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_BYTES_PER_PIXEL + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset + 1])) = ycomp; + + /****************/ + + pInAddr += JPEG_BYTES_PER_PIXEL * 2; + offset+=2; + } + offset += (JPEG_ConvertorParams.H_factor - colones); + refline += JPEG_ConvertorParams.ScaledWidth ; + + } + pOutAddr += JPEG_ConvertorParams.BlockSize; + } + + return numberMCU; +} + +/** + * @brief Convert RGB to YCbCr 4:4:4 blocks pixels + * @param pInBuffer : pointer to input RGB888/ARGB8888 frame buffer. + * @param pOutBuffer : pointer to output YCbCr blocks buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from RGB to YCbCr + */ +static uint32_t JPEG_ARGB_MCU_YCbCr444_ConvertBlocks (uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef, colones; + + uint32_t refline; + int32_t ycomp, crcomp, cbcomp, offset; + + uint32_t red, green, blue; + + uint8_t *pOutAddr; + uint8_t *pInAddr; + + numberMCU = ((3 * DataCount) / (JPEG_BYTES_PER_PIXEL * YCBCR_444_BLOCK_SIZE)); + + currentMCU = BlockIndex; + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + pOutAddr = &pOutBuffer[0]; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *JPEG_ConvertorParams.H_factor) / JPEG_ConvertorParams.WidthExtend)*JPEG_ConvertorParams.V_factor; + + yRef = ((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + if(((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend) == 0) + { + colones = JPEG_ConvertorParams.H_factor - JPEG_ConvertorParams.LineOffset; + } + else + { + colones = JPEG_ConvertorParams.H_factor; + } + offset = 0; + + for(i= 0; i < JPEG_ConvertorParams.V_factor; i++) + { + pInAddr = &pInBuffer[0] ; + + for(j=0; j < colones; j++) + { +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue)); + cbcomp = (int32_t)(*(RED_CB_LUT + red)) + (int32_t)(*(GREEN_CB_LUT + green)) + (int32_t)(*(BLUE_CB_RED_CR_LUT + blue)) + 128; + cbcomp = CLAMP_8BITS(cbcomp); + crcomp = (int32_t)(*(BLUE_CB_RED_CR_LUT + red)) + (int32_t)(*(GREEN_CR_LUT + green)) + (int32_t)(*(BLUE_CR_LUT + blue)) + 128; + crcomp = CLAMP_8BITS(crcomp); + + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset])) = (ycomp); + (*(pOutAddr + JPEG_ConvertorParams.Cb_MCU_LUT[offset])) = (cbcomp); + (*(pOutAddr + JPEG_ConvertorParams.Cr_MCU_LUT[offset])) = (crcomp); + + pInAddr += JPEG_BYTES_PER_PIXEL; + offset++; + } + offset += (JPEG_ConvertorParams.H_factor - colones); + refline += JPEG_ConvertorParams.ScaledWidth; + } + pOutAddr += JPEG_ConvertorParams.BlockSize; + } + + return numberMCU; +} + +/** + * @brief Convert RGB to Gray blocks pixels + * @param pInBuffer : pointer to input RGB888/ARGB8888 blocks. + * @param pOutBuffer : pointer to output Gray blocks buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from RGB to Gray + */ +static uint32_t JPEG_ARGB_MCU_Gray_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef, colones; + + uint32_t refline; + int32_t offset; + + uint32_t red, green, blue; + + uint8_t *pOutAddr; + uint8_t *pInAddr; + uint8_t ycomp; + + numberMCU = (DataCount / (JPEG_BYTES_PER_PIXEL * GRAY_444_BLOCK_SIZE)); + + currentMCU = BlockIndex; + *ConvertedDataCount = numberMCU * GRAY_444_BLOCK_SIZE; + + pOutAddr = &pOutBuffer[0]; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *JPEG_ConvertorParams.H_factor) / JPEG_ConvertorParams.WidthExtend)*JPEG_ConvertorParams.V_factor; + + yRef = ((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + if(((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend) == 0) + { + colones = JPEG_ConvertorParams.H_factor - JPEG_ConvertorParams.LineOffset; + } + else + { + colones = JPEG_ConvertorParams.H_factor; + } + offset = 0; + + for(i= 0; i < JPEG_ConvertorParams.V_factor; i++) + { + pInAddr = &pInBuffer[0] ; + + for(j=0; j < colones; j++) + { +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + refline + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + refline + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + refline + JPEG_BLUE_OFFSET/8)) ; +#endif + ycomp = (uint8_t)((int32_t)(*(RED_Y_LUT + red)) + (int32_t)(*(GREEN_Y_LUT + green)) + (int32_t)(*(BLUE_Y_LUT + blue))); + + (*(pOutAddr + offset)) = (ycomp); + + pInAddr += JPEG_BYTES_PER_PIXEL; + offset++; + } + offset += (JPEG_ConvertorParams.H_factor - colones); + refline += JPEG_ConvertorParams.ScaledWidth; + } + pOutAddr += JPEG_ConvertorParams.BlockSize; + } + + return numberMCU; +} + +/** + * @brief Convert RGB to YCCK blocks pixels + * @param pInBuffer : pointer to input RGB888/ARGB8888 blocks. + * @param pOutBuffer : pointer to output YCCK blocks buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from RGB to YCCK + */ +static uint32_t JPEG_ARGB_MCU_YCCK_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef, colones; + + uint32_t refline; + uint32_t offset; + + int32_t red, green, blue, color_k ; + + uint8_t *pOutAddr; + uint8_t *pInAddr; + + numberMCU = ((3 * DataCount) / (JPEG_BYTES_PER_PIXEL * CMYK_444_BLOCK_SIZE)); + *ConvertedDataCount = numberMCU * CMYK_444_BLOCK_SIZE; + + currentMCU = BlockIndex; + + pOutAddr = &pOutBuffer[0]; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *JPEG_ConvertorParams.H_factor) / JPEG_ConvertorParams.WidthExtend)*JPEG_ConvertorParams.V_factor; + + yRef = ((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + if(((currentMCU *JPEG_ConvertorParams.H_factor) % JPEG_ConvertorParams.WidthExtend) == 0) + { + colones = JPEG_ConvertorParams.H_factor - JPEG_ConvertorParams.LineOffset; + } + else + { + colones = JPEG_ConvertorParams.H_factor; + } + offset = 0; + for(i= 0; i < JPEG_ConvertorParams.V_factor; i++) + { + pInAddr = &pInBuffer[refline]; + + for(j=0; j < colones; j++) + { +#if (JPEG_RGB_FORMAT == JPEG_RGB565) + red = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_RED_MASK) >> JPEG_RED_OFFSET) ; + green = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_GREEN_MASK) >> JPEG_GREEN_OFFSET) ; + blue = (((*(__IO uint16_t *)(pInAddr + refline)) & JPEG_RGB565_BLUE_MASK) >> JPEG_BLUE_OFFSET) ; + red = (red << 3) | (red >> 2); + green = (green << 2) | (green >> 4); + blue = (blue << 3) | (blue >> 2); +#else + red = (*(pInAddr + JPEG_RED_OFFSET/8)) ; + green = (*(pInAddr + JPEG_GREEN_OFFSET/8)) ; + blue = (*(pInAddr + JPEG_BLUE_OFFSET/8)) ; +#endif + color_k = MAX(MAX(red,green),blue); + kBlocks[i][j]=color_k; + + (*(pOutAddr + JPEG_ConvertorParams.Y_MCU_LUT[offset])) = red * 255 / color_k; + (*(pOutAddr + JPEG_ConvertorParams.Cb_MCU_LUT[offset])) = green * 255 / color_k; + (*(pOutAddr + JPEG_ConvertorParams.Cr_MCU_LUT[offset])) = blue * 255 / color_k; + + pInAddr += JPEG_BYTES_PER_PIXEL; + offset++; + } + offset += (JPEG_ConvertorParams.H_factor - colones); + refline += JPEG_ConvertorParams.ScaledWidth; + } + JPEG_Set_K_Blocks(pOutAddr, kBlocks, JPEG_ConvertorParams.ChromaSubsampling); + pOutAddr += JPEG_ConvertorParams.BlockSize; + } + + return numberMCU; +} + +/** + * @brief Retrieve Encoding RGB to YCbCr color conversion function and block number + * @param pJpegInfo : JPEG_ConfTypeDef that contains the JPEG image information. + * These info are available in the HAL callback "HAL_JPEG_InfoReadyCallback". + * @param pFunction : pointer to JPEG_RGBToYCbCr_Convert_Function , used to Retrieve the color conversion function + * depending of the jpeg image color space and chroma sampling info. + * @param ImageNbMCUs : pointer to uint32_t, used to Retrieve the total number of MCU blocks in the jpeg image. + * @retval HAL status : HAL_OK or HAL_ERROR. + */ +HAL_StatusTypeDef JPEG_GetEncodeColorConvertFunc(JPEG_ConfTypeDef *pJpegInfo, JPEG_RGBToYCbCr_Convert_Function *pFunction, uint32_t *ImageNbMCUs) +{ + uint32_t hMCU, vMCU; + + JPEG_ConvertorParams.ColorSpace = pJpegInfo->ColorSpace; + JPEG_ConvertorParams.ChromaSubsampling = pJpegInfo->ChromaSubsampling; + + if(JPEG_ConvertorParams.ColorSpace == JPEG_YCBCR_COLORSPACE) + { + if(JPEG_ConvertorParams.ChromaSubsampling == JPEG_420_SUBSAMPLING) + { + *pFunction = JPEG_ARGB_MCU_YCbCr420_ConvertBlocks; + } + else if (JPEG_ConvertorParams.ChromaSubsampling == JPEG_422_SUBSAMPLING) + { + *pFunction = JPEG_ARGB_MCU_YCbCr422_ConvertBlocks; + } + else if (JPEG_ConvertorParams.ChromaSubsampling == JPEG_444_SUBSAMPLING) + { + *pFunction = JPEG_ARGB_MCU_YCbCr444_ConvertBlocks; + } + else + { + return HAL_ERROR; /* Chroma SubSampling Not supported*/ + } + } + else if(JPEG_ConvertorParams.ColorSpace == JPEG_GRAYSCALE_COLORSPACE) + { + *pFunction = JPEG_ARGB_MCU_Gray_ConvertBlocks; + } + else if(JPEG_ConvertorParams.ColorSpace == JPEG_CMYK_COLORSPACE) + { + *pFunction = JPEG_ARGB_MCU_YCCK_ConvertBlocks; + } + else + { + return HAL_ERROR; /* Color space Not supported*/ + } + + JPEG_ConvertorParams.ImageWidth = pJpegInfo->ImageWidth; + JPEG_ConvertorParams.ImageHeight = pJpegInfo->ImageHeight; + JPEG_ConvertorParams.ImageSize_Bytes = pJpegInfo->ImageWidth * pJpegInfo->ImageHeight * JPEG_BYTES_PER_PIXEL; + + if((JPEG_ConvertorParams.ChromaSubsampling == JPEG_420_SUBSAMPLING) || (JPEG_ConvertorParams.ChromaSubsampling == JPEG_422_SUBSAMPLING)) + { + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 16; + + JPEG_ConvertorParams.Y_MCU_LUT = JPEG_Y_MCU_LUT; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 16 - JPEG_ConvertorParams.LineOffset; + } + + JPEG_ConvertorParams.H_factor = 16; + + if(JPEG_ConvertorParams.ChromaSubsampling == JPEG_420_SUBSAMPLING) + { + JPEG_ConvertorParams.V_factor = 16; + + if(JPEG_ConvertorParams.ColorSpace == JPEG_YCBCR_COLORSPACE) + { + JPEG_ConvertorParams.BlockSize = YCBCR_420_BLOCK_SIZE; + } + + JPEG_ConvertorParams.Cb_MCU_LUT = JPEG_Cb_MCU_420_LUT; + JPEG_ConvertorParams.Cr_MCU_LUT = JPEG_Cr_MCU_420_LUT; + + JPEG_ConvertorParams.K_MCU_LUT = JPEG_K_MCU_420_LUT; + } + else /* 4:2:2*/ + { + JPEG_ConvertorParams.V_factor = 8; + + if(JPEG_ConvertorParams.ColorSpace == JPEG_YCBCR_COLORSPACE) + { + JPEG_ConvertorParams.BlockSize = YCBCR_422_BLOCK_SIZE; + } + + JPEG_ConvertorParams.Cb_MCU_LUT = JPEG_Cb_MCU_422_LUT; + JPEG_ConvertorParams.Cr_MCU_LUT = JPEG_Cr_MCU_422_LUT; + + JPEG_ConvertorParams.K_MCU_LUT = JPEG_K_MCU_422_LUT; + } + } + else if(JPEG_ConvertorParams.ChromaSubsampling == JPEG_444_SUBSAMPLING) + { + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 8; + + JPEG_ConvertorParams.Y_MCU_LUT = JPEG_Y_MCU_444_LUT; + + JPEG_ConvertorParams.Cb_MCU_LUT = JPEG_Cb_MCU_444_LUT; + JPEG_ConvertorParams.Cr_MCU_LUT = JPEG_Cr_MCU_444_LUT; + + JPEG_ConvertorParams.K_MCU_LUT = JPEG_K_MCU_444_LUT; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 8 - JPEG_ConvertorParams.LineOffset; + } + JPEG_ConvertorParams.H_factor = 8; + JPEG_ConvertorParams.V_factor = 8; + + if(JPEG_ConvertorParams.ColorSpace == JPEG_YCBCR_COLORSPACE) + { + JPEG_ConvertorParams.BlockSize = YCBCR_444_BLOCK_SIZE; + } + if(JPEG_ConvertorParams.ColorSpace == JPEG_CMYK_COLORSPACE) + { + JPEG_ConvertorParams.BlockSize = CMYK_444_BLOCK_SIZE; + } + else if(JPEG_ConvertorParams.ColorSpace == JPEG_GRAYSCALE_COLORSPACE) + { + JPEG_ConvertorParams.BlockSize = GRAY_444_BLOCK_SIZE; + } + + } + else + { + return HAL_ERROR; /* Not supported*/ + } + + + JPEG_ConvertorParams.WidthExtend = JPEG_ConvertorParams.ImageWidth + JPEG_ConvertorParams.LineOffset; + JPEG_ConvertorParams.ScaledWidth = JPEG_BYTES_PER_PIXEL * JPEG_ConvertorParams.ImageWidth; + + hMCU = (JPEG_ConvertorParams.ImageWidth / JPEG_ConvertorParams.H_factor); + if((JPEG_ConvertorParams.ImageWidth % JPEG_ConvertorParams.H_factor) != 0) + { + hMCU++; /*+1 for horizenatl incomplete MCU */ + } + + vMCU = (JPEG_ConvertorParams.ImageHeight / JPEG_ConvertorParams.V_factor); + if((JPEG_ConvertorParams.ImageHeight % JPEG_ConvertorParams.V_factor) != 0) + { + vMCU++; /*+1 for vertical incomplete MCU */ + } + JPEG_ConvertorParams.MCU_Total_Nb = (hMCU * vMCU); + *ImageNbMCUs = JPEG_ConvertorParams.MCU_Total_Nb; + + return HAL_OK; +} +#endif /* USE_JPEG_ENCODER == 1 */ + +#if (USE_JPEG_DECODER == 1) +/** + * @brief Convert YCbCr 4:2:0 blocks to RGB pixels + * @param pInBuffer : pointer to input YCbCr blocks buffer. + * @param pOutBuffer : pointer to output RGB888/ARGB8888 frame buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from YCbCr to RGB + */ + +static uint32_t JPEG_MCU_YCbCr420_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j,k, currentMCU, xRef,yRef; + + uint32_t refline; + int32_t ycomp, crcomp, cbcomp; + + int32_t c_red, c_blue, c_green; + + uint8_t *pOutAddr, *pOutAddr2; + uint8_t *pChrom, *pLum; + + numberMCU = DataCount / YCBCR_420_BLOCK_SIZE; + currentMCU = BlockIndex; + + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *16) / JPEG_ConvertorParams.WidthExtend)*16; + + yRef = ((currentMCU *16) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + pChrom = pInBuffer + 256; /* pChroma = pInBuffer + 4*64 */ + + pLum = pInBuffer; + + for(i= 0; i < 16; i+=2) + { + if(i == 8) + { + pLum = pInBuffer + 128; + } + + if(refline < JPEG_ConvertorParams.ImageSize_Bytes) + { + pOutAddr = pOutBuffer + refline; + pOutAddr2 = pOutAddr + JPEG_ConvertorParams.ScaledWidth; + + for(k= 0; k<2; k++) + { + for(j=0; j < 8; j+=2) + { + cbcomp = (int32_t)(*(pChrom)); + c_blue = (int32_t)(*(CB_BLUE_LUT + cbcomp)); + + crcomp = (int32_t)(*(pChrom + 64)); + c_red = (int32_t)(*(CR_RED_LUT + crcomp)); + + c_green = ((int32_t)(*(CR_GREEN_LUT + crcomp)) + (int32_t)(*(CB_GREEN_LUT + cbcomp))) >> 16; + + + +#if (JPEG_RGB_FORMAT == JPEG_ARGB8888) + + ycomp = (int32_t)(*(pLum +j)); + + *(__IO uint32_t *)pOutAddr = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + /**********/ + ycomp = (int32_t)(*(pLum +j +1)); + + *((__IO uint32_t *)(pOutAddr + 4)) = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + + /**********/ + ycomp = (int32_t)(*(pLum +j +8)); + + *(__IO uint32_t *)pOutAddr2 = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + + /**********/ + ycomp = (int32_t)(*(pLum +j +8 +1)); + + *((__IO uint32_t *)(pOutAddr2 +4)) = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + + +#elif (JPEG_RGB_FORMAT == JPEG_RGB888) + + ycomp = (int32_t)(*(pLum +j)); + + pOutAddr[JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr[JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr[JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + + /**********/ + ycomp = (int32_t)(*(pLum +j +1)); + + pOutAddr[3 + JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr[3 + JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr[3 + JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + + /**********/ + ycomp = (int32_t)(*(pLum +j +8)); + + pOutAddr2[JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr2[JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr2[JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + + /**********/ + ycomp = (int32_t)(*(pLum +j +8 +1)); + + pOutAddr2[3+ JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr2[3 + JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr2[3 + JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB565) + + ycomp = (int32_t)(*(pLum +j)); + + *(__IO uint16_t *)pOutAddr = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); + /**********/ + ycomp = (int32_t)(*(pLum +j +1)); + + *((__IO uint16_t *)(pOutAddr + 2)) = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); + + /**********/ + ycomp = (int32_t)(*(pLum +j +8)); + + *(__IO uint16_t *)pOutAddr2 = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); + + /**********/ + ycomp = (int32_t)(*(pLum +j +8 +1)); + + *((__IO uint16_t *)(pOutAddr2 +2)) = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); +#endif /* JPEG_RGB_FORMAT */ + + pOutAddr += JPEG_BYTES_PER_PIXEL * 2; + pOutAddr2 += JPEG_BYTES_PER_PIXEL * 2; + + pChrom++; + } + pLum += 64; + } + + pLum = pLum - 128 + 16; + + refline += 2*JPEG_ConvertorParams.ScaledWidth; + } + } + + pInBuffer += YCBCR_420_BLOCK_SIZE; + } + return numberMCU; +} + +/** + * @brief Convert YCbCr 4:2:2 blocks to RGB pixels + * @param pInBuffer : pointer to input YCbCr blocks buffer. + * @param pOutBuffer : pointer to output RGB888/ARGB8888 frame buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from YCbCr to RGB + */ +static uint32_t JPEG_MCU_YCbCr422_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j,k, currentMCU, xRef,yRef; + + uint32_t refline; + int32_t ycomp, crcomp, cbcomp; + + int32_t c_red, c_blue, c_green; + + uint8_t *pOutAddr; + uint8_t *pChrom, *pLum; + + numberMCU = DataCount / YCBCR_422_BLOCK_SIZE; + currentMCU = BlockIndex; + + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *16) / JPEG_ConvertorParams.WidthExtend)*8; + + yRef = ((currentMCU *16) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + pChrom = pInBuffer + 128; /* pChroma = pInBuffer + 2*64 */ + + pLum = pInBuffer; + + for(i= 0; i < 8; i++) + { + if(refline < JPEG_ConvertorParams.ImageSize_Bytes) + { + pOutAddr = pOutBuffer + refline; + + for(k= 0; k<2; k++) + { + for(j=0; j < 8; j+=2) + { + cbcomp = (int32_t)(*(pChrom)); + c_blue = (int32_t)(*(CB_BLUE_LUT + cbcomp)); + + crcomp = (int32_t)(*(pChrom + 64)); + c_red = (int32_t)(*(CR_RED_LUT + crcomp)); + + c_green = ((int32_t)(*(CR_GREEN_LUT + crcomp)) + (int32_t)(*(CB_GREEN_LUT + cbcomp))) >> 16; + + + +#if (JPEG_RGB_FORMAT == JPEG_ARGB8888) + + ycomp = (int32_t)(*(pLum +j)); + + *(__IO uint32_t *)pOutAddr = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + /**********/ + ycomp = (int32_t)(*(pLum +j +1)); + + *((__IO uint32_t *)(pOutAddr + 4)) = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB888) + + ycomp = (int32_t)(*(pLum +j)); + + pOutAddr[JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr[JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr[JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + + /**********/ + ycomp = (int32_t)(*(pLum +j +1)); + + pOutAddr[3 + JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr[3 + JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr[3 + JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB565) + + ycomp = (int32_t)(*(pLum +j)); + + *(__IO uint16_t *)pOutAddr = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); + /**********/ + ycomp = (int32_t)(*(pLum +j +1)); + + *((__IO uint16_t *)(pOutAddr + 2)) = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); + +#endif /* JPEG_RGB_FORMAT*/ + + pOutAddr += JPEG_BYTES_PER_PIXEL * 2; + + pChrom++; + } + pLum += 64; + } + + pLum = pLum - 128 + 8; + + refline += JPEG_ConvertorParams.ScaledWidth; + } + } + + pInBuffer += YCBCR_422_BLOCK_SIZE; + } + return numberMCU; +} + +/** + * @brief Convert YCbCr 4:4:4 blocks to RGB pixels + * @param pInBuffer : pointer to input YCbCr blocks buffer. + * @param pOutBuffer : pointer to output RGB888/ARGB8888 frame buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from YCbCr to RGB + */ +static uint32_t JPEG_MCU_YCbCr444_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef; + + uint32_t refline; + int32_t ycomp, crcomp, cbcomp; + + int32_t c_red, c_blue, c_green; + + uint8_t *pOutAddr; + uint8_t *pChrom, *pLum; + + numberMCU = DataCount / YCBCR_444_BLOCK_SIZE; + currentMCU = BlockIndex; + + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + while(currentMCU < (numberMCU + BlockIndex)) + { + + xRef = ((currentMCU *8) / JPEG_ConvertorParams.WidthExtend)*8; + + yRef = ((currentMCU *8) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + pChrom = pInBuffer + 64; /* pChroma = pInBuffer + 4*64 */ + + pLum = pInBuffer; + + for(i= 0; i < 8; i++) + { + if(refline < JPEG_ConvertorParams.ImageSize_Bytes) + { + pOutAddr = pOutBuffer+ refline; + + + for(j=0; j < 8; j++) + { + cbcomp = (int32_t)(*pChrom); + c_blue = (int32_t)(*(CB_BLUE_LUT + cbcomp)); + + crcomp = (int32_t)(*(pChrom + 64)); + c_red = (int32_t)(*(CR_RED_LUT + crcomp)); + + c_green = ((int32_t)(*(CR_GREEN_LUT + crcomp)) + (int32_t)(*(CB_GREEN_LUT + cbcomp))) >> 16; + +#if (JPEG_RGB_FORMAT == JPEG_ARGB8888) + + ycomp = (int32_t)(*(pLum +j)); + + *(__IO uint32_t *)pOutAddr = + (CLAMP(ycomp + c_red) << JPEG_RED_OFFSET) | \ + (CLAMP( ycomp + c_green) << JPEG_GREEN_OFFSET) | \ + (CLAMP(ycomp + c_blue) << JPEG_BLUE_OFFSET); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB888) + + ycomp = (int32_t)(*(pLum +j)); + + pOutAddr[JPEG_RED_OFFSET/8] = CLAMP(ycomp + c_red); + pOutAddr[JPEG_GREEN_OFFSET/8] = CLAMP(ycomp + c_green); + pOutAddr[JPEG_BLUE_OFFSET/8] = CLAMP(ycomp + c_blue); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB565) + + ycomp = (int32_t)(*(pLum +j)); + + *(__IO uint16_t *)pOutAddr = + ((CLAMP(ycomp + c_red) >> 3) << JPEG_RED_OFFSET) | \ + ((CLAMP( ycomp + c_green) >> 2) << JPEG_GREEN_OFFSET) | \ + ((CLAMP(ycomp + c_blue) >> 3) << JPEG_BLUE_OFFSET); + +#endif /* JPEG_RGB_FORMAT */ + + pOutAddr += JPEG_BYTES_PER_PIXEL; + + pChrom++; + } + pLum += 8; + + refline += JPEG_ConvertorParams.ScaledWidth; + } + } + + pInBuffer += YCBCR_444_BLOCK_SIZE; + } + return numberMCU; +} + +/** + * @brief Convert Y Gray blocks to RGB pixels + * @param pInBuffer : pointer to input Luminance Y blocks buffer. + * @param pOutBuffer : pointer to output RGB888/ARGB8888 frame buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from YCbCr to RGB + */ +static uint32_t JPEG_MCU_Gray_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t currentMCU, xRef,yRef; + uint32_t refline; + + + uint32_t i,j, ySample; + uint8_t *pOutAddr, *pLum; + + + numberMCU = DataCount / GRAY_444_BLOCK_SIZE; + currentMCU = BlockIndex; + + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + while(currentMCU < (numberMCU + BlockIndex)) + { + xRef = ((currentMCU *8) / JPEG_ConvertorParams.WidthExtend)*8; + + yRef = ((currentMCU *8) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + pLum = pInBuffer; + + for(i= 0; i < 8; i++) + { + pOutAddr = pOutBuffer + refline; + if(refline < JPEG_ConvertorParams.ImageSize_Bytes) + { + for(j=0; j < 8; j++) + { + ySample = (uint32_t)(*pLum); + +#if (JPEG_RGB_FORMAT == JPEG_ARGB8888) + + *(__IO uint32_t *)pOutAddr = ySample | (ySample << 8) | (ySample << 16); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB888) + + pOutAddr[0] = ySample; + pOutAddr[1] = ySample; + pOutAddr[2] = ySample; + +#elif (JPEG_RGB_FORMAT == JPEG_RGB565) + + *(__IO uint16_t *)pOutAddr = ((ySample >> 3) << 11) | ((ySample >> 2) << 5) | (ySample >> 3); + +#endif /* JPEG_RGB_FORMAT */ + + pOutAddr += JPEG_BYTES_PER_PIXEL; + pLum++; + } + + refline += JPEG_ConvertorParams.ScaledWidth; + } + } + + pInBuffer += GRAY_444_BLOCK_SIZE; + } + return numberMCU; +} + +/** + * @brief Convert CMYK blocks to RGB pixels + * @param pInBuffer : pointer to input CMYK blocks buffer. + * @param pOutBuffer : pointer to output RGB888/ARGB8888 frame buffer. + * @param BlockIndex : index of the input buffer first block in the final image. + * @param DataCount : number of bytes in the input buffer . + * @param ConvertedDataCount : number of converted bytes from input buffer. + * @retval Number of blocks converted from CMYK to RGB + */ +static uint32_t JPEG_MCU_YCCK_ARGB_ConvertBlocks(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount) +{ + uint32_t numberMCU; + uint32_t i,j, currentMCU, xRef,yRef; + + uint32_t refline; + int32_t color_k; + + int32_t c_red, c_blue, c_green; + + uint8_t *pOutAddr, *pChrom; + + numberMCU = DataCount / CMYK_444_BLOCK_SIZE; + currentMCU = BlockIndex; + + *ConvertedDataCount = numberMCU * JPEG_ConvertorParams.BlockSize; + + while(currentMCU < (numberMCU + BlockIndex)) + { + + xRef = ((currentMCU *8) / JPEG_ConvertorParams.WidthExtend)*8; + + yRef = ((currentMCU *8) % JPEG_ConvertorParams.WidthExtend); + + refline = JPEG_ConvertorParams.ScaledWidth * xRef + (JPEG_BYTES_PER_PIXEL*yRef); + + currentMCU++; + + pChrom = pInBuffer; + + for(i= 0; i < 8; i++) + { + if(refline < JPEG_ConvertorParams.ImageSize_Bytes) + { + pOutAddr = pOutBuffer+ refline; + + for(j=0; j < 8; j++) + { + color_k = (int32_t)(*(pChrom + 192)); + c_red = (color_k * ((int32_t)(*pChrom)))/255; + + c_green = (color_k * (int32_t)(*(pChrom + 64)))/255; + + c_blue = (color_k * (int32_t)(*(pChrom + 128)))/255; + +#if (JPEG_RGB_FORMAT == JPEG_ARGB8888) + + *(__IO uint32_t *)pOutAddr = + (c_red << JPEG_RED_OFFSET) | \ + (c_green << JPEG_GREEN_OFFSET) | \ + (c_blue << JPEG_BLUE_OFFSET); + +#elif (JPEG_RGB_FORMAT == JPEG_RGB888) + + pOutAddr[JPEG_RED_OFFSET/8] = c_red; + pOutAddr[JPEG_GREEN_OFFSET/8] = c_green; + pOutAddr[JPEG_BLUE_OFFSET/8] = c_blue; + +#elif (JPEG_RGB_FORMAT == JPEG_RGB565) + + *(__IO uint16_t *)pOutAddr = + ((c_red >> 3) << JPEG_RED_OFFSET) | \ + ((c_green >> 2) << JPEG_GREEN_OFFSET) | \ + ((c_blue >> 3) << JPEG_BLUE_OFFSET); + +#endif /* JPEG_RGB_FORMAT */ + + pOutAddr += JPEG_BYTES_PER_PIXEL; + + pChrom++; + } + + refline += JPEG_ConvertorParams.ScaledWidth; + } + } + + pInBuffer += CMYK_444_BLOCK_SIZE; + } + return numberMCU; +} + +/** + * @brief Retrieve Decoding YCbCr to RGB color conversion function and block number + * @param pJpegInfo : JPEG_ConfTypeDef that contains the JPEG image information. + * These info are available in the HAL callback "HAL_JPEG_InfoReadyCallback". + * @param pFunction : pointer to JPEG_YCbCrToRGB_Convert_Function , used to Retrieve the color conversion function + * depending of the jpeg image color space and chroma sampling info. + * @param ImageNbMCUs : pointer to uint32_t, used to Retrieve the total number of MCU blocks in the jpeg image. + * @retval HAL status : HAL_OK or HAL_ERROR. + */ +HAL_StatusTypeDef JPEG_GetDecodeColorConvertFunc(JPEG_ConfTypeDef *pJpegInfo, JPEG_YCbCrToRGB_Convert_Function *pFunction, uint32_t *ImageNbMCUs) +{ + uint32_t hMCU, vMCU; + + JPEG_ConvertorParams.ColorSpace = pJpegInfo->ColorSpace; + JPEG_ConvertorParams.ImageWidth = pJpegInfo->ImageWidth; + JPEG_ConvertorParams.ImageHeight = pJpegInfo->ImageHeight; + JPEG_ConvertorParams.ImageSize_Bytes = pJpegInfo->ImageWidth * pJpegInfo->ImageHeight * JPEG_BYTES_PER_PIXEL; + + JPEG_ConvertorParams.ChromaSubsampling = pJpegInfo->ChromaSubsampling; + if(JPEG_ConvertorParams.ColorSpace == JPEG_YCBCR_COLORSPACE) + { + if(JPEG_ConvertorParams.ChromaSubsampling == JPEG_420_SUBSAMPLING) + { + *pFunction = JPEG_MCU_YCbCr420_ARGB_ConvertBlocks; + + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 16; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 16 - JPEG_ConvertorParams.LineOffset; + } + JPEG_ConvertorParams.H_factor = 16; + JPEG_ConvertorParams.V_factor = 16; + } + else if(JPEG_ConvertorParams.ChromaSubsampling == JPEG_422_SUBSAMPLING) + { + *pFunction = JPEG_MCU_YCbCr422_ARGB_ConvertBlocks; + + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 16; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 16 - JPEG_ConvertorParams.LineOffset; + } + JPEG_ConvertorParams.H_factor = 16; + JPEG_ConvertorParams.V_factor = 8; + } + else /*4:4:4*/ + { + *pFunction = JPEG_MCU_YCbCr444_ARGB_ConvertBlocks; + + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 8; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 8 - JPEG_ConvertorParams.LineOffset; + } + JPEG_ConvertorParams.H_factor = 8; + JPEG_ConvertorParams.V_factor = 8; + } + } + else if(JPEG_ConvertorParams.ColorSpace == JPEG_GRAYSCALE_COLORSPACE) + { + *pFunction = JPEG_MCU_Gray_ARGB_ConvertBlocks; + + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 8; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 8 - JPEG_ConvertorParams.LineOffset; + } + JPEG_ConvertorParams.H_factor = 8; + JPEG_ConvertorParams.V_factor = 8; + } + else if(JPEG_ConvertorParams.ColorSpace == JPEG_CMYK_COLORSPACE) + { + *pFunction = JPEG_MCU_YCCK_ARGB_ConvertBlocks; + + JPEG_ConvertorParams.LineOffset = JPEG_ConvertorParams.ImageWidth % 8; + + if(JPEG_ConvertorParams.LineOffset != 0) + { + JPEG_ConvertorParams.LineOffset = 8 - JPEG_ConvertorParams.LineOffset; + } + JPEG_ConvertorParams.H_factor = 8; + JPEG_ConvertorParams.V_factor = 8; + } + else + { + return HAL_ERROR; /* Color space Not supported*/ + } + + JPEG_ConvertorParams.WidthExtend = JPEG_ConvertorParams.ImageWidth + JPEG_ConvertorParams.LineOffset; + JPEG_ConvertorParams.ScaledWidth = JPEG_BYTES_PER_PIXEL * JPEG_ConvertorParams.ImageWidth; + + hMCU = (JPEG_ConvertorParams.ImageWidth / JPEG_ConvertorParams.H_factor); + if((JPEG_ConvertorParams.ImageWidth % JPEG_ConvertorParams.H_factor) != 0) + { + hMCU++; /*+1 for horizenatl incomplete MCU */ + } + + vMCU = (JPEG_ConvertorParams.ImageHeight / JPEG_ConvertorParams.V_factor); + if((JPEG_ConvertorParams.ImageHeight % JPEG_ConvertorParams.V_factor) != 0) + { + vMCU++; /*+1 for vertical incomplete MCU */ + } + JPEG_ConvertorParams.MCU_Total_Nb = (hMCU * vMCU); + *ImageNbMCUs = JPEG_ConvertorParams.MCU_Total_Nb; + + return HAL_OK; +} + +/** + * @brief Initializes the YCbCr -> RGB colors conversion Look Up Tables + * @param None + * @retval None + */ +void JPEG_InitPostProcColorTables(void) +{ + int32_t index, i; + + for (i = 0; i <= 255; i++) + { + index = (i * 2) - 256; + CR_RED_LUT[i] = ( (((int32_t) ((1.40200 / 2) * (1L << 16))) * index) + ((int32_t) 1 << (16 - 1))) >> 16; + + CB_BLUE_LUT[i] = ( (((int32_t) ((1.77200 / 2) * (1L << 16))) * index) + ((int32_t) 1 << (16 - 1))) >> 16; + + CR_GREEN_LUT[i] = (-((int32_t) ((0.71414 / 2) * (1L << 16)))) * index; + CB_GREEN_LUT[i] = (-((int32_t) ((0.34414 / 2) * (1L << 16)))) * index; + } +} +#endif /* USE_JPEG_DECODER == 1 */ + +/** + * @brief Initializes the colors conversion Look Up Tables + * @param None + * @retval None + */ +void JPEG_InitColorTables(void) +{ + +#if (USE_JPEG_ENCODER == 1) + JPEG_InitPreProcColorTables(); + JPEG_Init_MCU_LUT(); +#endif + +#if (USE_JPEG_DECODER == 1) + JPEG_InitPostProcColorTables(); +#endif + +} + +#if (USE_JPEG_ENCODER == 1) +/** + * @brief Initializes the RGB -> YCbCr colors conversion Look Up Tables + * @param None + * @retval None + */ +void JPEG_InitPreProcColorTables(void) +{ + int32_t i; + + for (i = 0; i <= 255; i++) + { + RED_Y_LUT[i] = (( ((int32_t) ((0.299 ) * (1L << 16))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + GREEN_Y_LUT[i] = (( ((int32_t) ((0.587 ) * (1L << 16))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + BLUE_Y_LUT[i] = (( ((int32_t) ((0.114 ) * (1L << 16))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + + RED_CB_LUT[i] = (((-((int32_t) ((0.1687 ) * (1L << 16)))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + GREEN_CB_LUT[i] = (((-((int32_t) ((0.3313 ) * (1L << 16)))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + + /* BLUE_CB_LUT and RED_CR_LUT are identical */ + BLUE_CB_RED_CR_LUT[i] = (( ((int32_t) ((0.5 ) * (1L << 16))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + + GREEN_CR_LUT[i] = (((-((int32_t) ((0.4187 ) * (1L << 16)))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + BLUE_CR_LUT[i] = (((-((int32_t) ((0.0813 ) * (1L << 16)))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ; + } +} + +/** + * @brief Initializes the MCU Look Up Tables + * @param None + * @retval None + */ +void JPEG_Init_MCU_LUT(void) +{ + uint32_t i, j, offset; + + /*Y LUT */ + for(i = 0; i < 16; i++) + { + for(j = 0; j < 16; j++) + { + offset = j + (i*8); + if((j>=8) && (i>=8)) offset+= 120; + else if((j>=8) && (i<8)) offset+= 56; + else if((j<8) && (i>=8)) offset+= 64; + + JPEG_Y_MCU_LUT[i*16 + j] = offset; + } + } + + /*Cb Cr K LUT*/ + for(i = 0; i < 16; i++) + { + for(j = 0; j < 16; j++) + { + offset = i*16 + j; + + JPEG_Cb_MCU_420_LUT[offset] = (j/2) + ((i/2)*8) + 256; + JPEG_Cb_MCU_422_LUT[offset] = (j/2) + (i*8) + 128; + + JPEG_Cr_MCU_420_LUT[offset] = (j/2) + ((i/2)*8) + 320; + JPEG_Cr_MCU_422_LUT[offset] = (j/2) + (i*8) + 192; + + JPEG_K_MCU_420_LUT[offset] = (j/2) + ((i/2)*8) + 384; + JPEG_K_MCU_422_LUT[offset] = (j/2) + ((i/2)*8) + 256; + } + } + + for(i = 0; i < 8; i++) + { + for(j = 0; j < 8; j++) + { + offset = i*8 + j; + + JPEG_Y_MCU_444_LUT[offset] = offset; + JPEG_Cb_MCU_444_LUT[offset] = offset + 64 ; + JPEG_Cr_MCU_444_LUT[offset] = offset + 128 ; + JPEG_K_MCU_444_LUT[offset] = offset + 192 ; + } + } +} + +/** + * @brief Initializes the YCCK format K Blocks + * @param ChromaSampling + * @retval pMCUBuffer + */ +static uint8_t *JPEG_Set_K_Blocks(uint8_t *pMCUBuffer, uint8_t pKBlocks[16][16], uint32_t ChromaSampling) +{ + uint32_t i,j; + + if(ChromaSampling == JPEG_420_SUBSAMPLING) + { + /* 4:2:0 4Y + Cb + Cr + K*/ + + pMCUBuffer = pMCUBuffer + 384; + /* K block */ + for(i=0;i<16;i+=2) + { + for(j=0;j<16;j+=2) + { + *pMCUBuffer = pKBlocks[i][j]; + pMCUBuffer++; + } + } + } + else if(ChromaSampling == JPEG_422_SUBSAMPLING) + { + /* 4:2:2 2Y horizental + Cb + Cr + K*/ + pMCUBuffer = pMCUBuffer + 256; + + /* K block */ + for(i=0;i<8;i++) + { + for(j=0;j<16;j+=2) + { + *pMCUBuffer = pKBlocks[i][j]; + pMCUBuffer++; + } + } + } + else if(ChromaSampling == JPEG_444_SUBSAMPLING) + { + /* 4:4:4 Y + Cb + Cr + K*/ + + /* K block */ + pMCUBuffer = pMCUBuffer + 192; + for(i=0;i<8;i++) + { + for(j=0;j<8;j++) + { + *pMCUBuffer = pKBlocks[i][j]; + pMCUBuffer++; + } + } + } + return pMCUBuffer; +} +#endif /* USE_JPEG_ENCODER == 1 */ diff --git a/Utilities/JPEG/jpeg_utils.h b/Utilities/JPEG/jpeg_utils.h new file mode 100644 index 0000000..4ef42fb --- /dev/null +++ b/Utilities/JPEG/jpeg_utils.h @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * @file jpeg_utils.h + * @author MCD Application Team + * @brief Header for jpeg_utils.c module + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 __JPEG_UTILS_H +#define __JPEG_UTILS_H + +/* Includes ------------------------------------------------------------------*/ +#include "jpeg_utils_conf.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup JPEG + * @{ + */ + +/** @defgroup JPEG_Exported_Defines JPEG Exported Defines + * @{ + */ +/** +* @} +*/ + +/** @defgroup JPEG_Exported_Types JPEG Exported Types + * @{ + */ +#if (USE_JPEG_DECODER == 1) +typedef uint32_t (* JPEG_YCbCrToRGB_Convert_Function)(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount ); +#endif + +#if (USE_JPEG_ENCODER == 1) +typedef uint32_t (* JPEG_RGBToYCbCr_Convert_Function)(uint8_t *pInBuffer, + uint8_t *pOutBuffer, + uint32_t BlockIndex, + uint32_t DataCount, + uint32_t *ConvertedDataCount ); +#endif +/** +* @} +*/ + +/** @defgroup JPEG_Exported_Macros JPEG Exported Macros + * @{ + */ +/** +* @} +*/ + +/** @defgroup JPEG_Exported_Variables JPEG Exported Variables + * @{ + */ +/** +* @} +*/ + +/** @defgroup JPEG_Exported_FunctionsPrototype JPEG Exported FunctionsPrototype + * @{ + */ +void JPEG_InitColorTables(void); + +#if (USE_JPEG_DECODER == 1) +HAL_StatusTypeDef JPEG_GetDecodeColorConvertFunc(JPEG_ConfTypeDef *pJpegInfo, JPEG_YCbCrToRGB_Convert_Function *pFunction, uint32_t *ImageNbMCUs); +#endif + +#if (USE_JPEG_ENCODER == 1) +HAL_StatusTypeDef JPEG_GetEncodeColorConvertFunc(JPEG_ConfTypeDef *pJpegInfo, JPEG_RGBToYCbCr_Convert_Function *pFunction, uint32_t *ImageNbMCUs); +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* __JPEG_UTILS_H */ + diff --git a/Utilities/JPEG/jpeg_utils_conf_template.h b/Utilities/JPEG/jpeg_utils_conf_template.h new file mode 100644 index 0000000..a28a724 --- /dev/null +++ b/Utilities/JPEG/jpeg_utils_conf_template.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file jpeg_utils_conf_template.h + * @author MCD Application Team + * @brief jpeg_utils configuration template file. + * This file should be copied to the application folder and modified + * as follows: + * - Rename it to 'jpeg_utils_conf.h'. + * - Update the name of the JPEG driver's header file, depending on + * the EVAL board you are using, see lines 51 and 52 below (by default this + * file will generate compile error unless you do this modification). + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 __JPEG_UTILS_CONF_H__ +#define __JPEG_UTILS_CONF_H__ + + +/* Includes ------------------------------------------------------------------*/ +/*#include "stm32fXxx_hal.h" */ +/* #include "stm32fXxx_hal_jpeg.h" */ + +/* Private define ------------------------------------------------------------*/ +/** @addtogroup JPEG_Private_Defines + * @{ + */ +/* RGB Color format definition for JPEG encoding/Decoding : Should not be modified*/ +#define JPEG_ARGB8888 0 /* ARGB8888 Color Format */ +#define JPEG_RGB888 1 /* RGB888 Color Format */ +#define JPEG_RGB565 2 /* RGB565 Color Format */ + +/** +* @} +*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @addtogroup JPEG_Exported_Defines + * @{ + */ +#define USE_JPEG_DECODER 1 /* Enable Decoding Post-Processing functions (YCbCr to RGB conversion) */ +#define USE_JPEG_ENCODER 1 /* Enable Encoding Pre-Processing functions (RGB to YCbCr conversion)*/ + +#define JPEG_RGB_FORMAT JPEG_ARGB8888 /* Select RGB format: ARGB8888, RGB888, RBG_565 */ +#define JPEG_SWAP_RB 0 /* Change color order to BGR */ + +/** +* @} +*/ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#endif /* __JPEG_UTILS_CONF_H__ */ diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..d6c065a --- /dev/null +++ b/changelog.txt @@ -0,0 +1,48 @@ +3.0.9 +- Updated to STM32CubeMX 6.17.0 +- Priority of SYSCLK increased + +3.0.8 +- Updated to STM32CubeMX 6.16.0 +- Updated to Firmware Package FW_H7RS V1.3.0 +- Added new linker scripts to match ST Arm Clang requirements. These linker scripts are now also used for both Run Target and CubeIDE builds, and the old linker scripts have been removed. + +3.0.7 +- Updated to TouchGFX 4.26.0 + +3.0.6 +- Updated to STM32CubeMX 6.15.0 +- Added print of memory usage to TouchGFX Designer "Run target" build script log + +3.0.5 +- Correct PSRAM configuration +- Add TouchGFX animation buffer to enable "Slide" screen transition +- Update to TouchGFX 4.25.0 +- Update to STM32CubeMX 6.14.0 +- Updated to Firmware Package FW_H7RS V1.2.0 + +3.0.4 +- Disable SBS Compensation cell to improve stability on OSPI external flash + +3.0.3 +- Updated to STM32CubeMX 6.13.0 + +3.0.2 +- Updated to STM32CubeMX 6.12.0 +- Updated to Firmware Package FW_H7RS V1.1.0 + +3.0.1 +- Update to TouchGFX 4.24.0 +- Update MPU settings, allowing instruction from fewer regions to reduce speculative execution misses +- Reduce region of uncached SRAM for GPU2D commandlist, to make more available for general purpose SRAM +- Moved FreeRTOS heap to DTCM memory to improve performance + +3.0.0 +First released version +- TouchGFX 4.23.2 +- STM32CubeMX 6.11.0 +- Firmware FW_H7RS V1.0.0 +- X-CUBE-FREERTOS 1.1.0 +- Support for STM32CubeIDE +- Support for EWARM +- Support for "Run target" in TouchGFX Designer diff --git a/gcc/MX66UW1G45G_STM32H7S78-DK.stldr b/gcc/MX66UW1G45G_STM32H7S78-DK.stldr new file mode 100644 index 0000000000000000000000000000000000000000..20ff78a2ed29cd012a7f8f9c834a954b268c5a6d GIT binary patch literal 239516 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
    `ey8rlm3%L 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 literal 0 HcmV?d00001 diff --git a/gcc/Makefile b/gcc/Makefile new file mode 100644 index 0000000..c4b80d2 --- /dev/null +++ b/gcc/Makefile @@ -0,0 +1,9 @@ +makefile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +makefile_dir := $(dir $(makefile_path)) + + +.PHONY: all clean assets flash intflash + +all clean assets flash intflash: + $(MAKE) -C $(makefile_dir) --no-print-directory -f makefile_boot $(MAKEFLAGS) $@ + $(MAKE) -C $(makefile_dir) --no-print-directory -f makefile_appli $(MAKEFLAGS) $@ \ No newline at end of file diff --git a/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c new file mode 100644 index 0000000..9e1d1a8 --- /dev/null +++ b/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c @@ -0,0 +1,775 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __VFP_FP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 +r0p1 port. */ +#define portCPUID ( * ( ( volatile uint32_t * ) 0xE000ed00 ) ) +#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) +#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0xFFUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXC_RETURN ( 0xfffffffd ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case it messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__ (( naked )); + +/* + * Function to enable the VFP. + */ +static void vPortEnableVFP( void ) __attribute__ (( naked )); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * The number of SysTick increments that make up one tick period. + */ +#if( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if( configUSE_TICKLESS_IDLE == 1 ) + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ +volatile uint32_t ulDummy = 0; + + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + while( ulDummy == 0 ) + { + /* This file calls prvTaskExitError() after the scheduler has been + started to remove a compiler warning about the function being defined + but never called. ulDummy is used purely to quieten other warnings + about code appearing after this function is called - making ulDummy + volatile makes the compiler think the function could return and + therefore not output an 'unreachable code' warning for code that appears + after it. */ + } +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + /* Start the first task. This also clears the bit that indicates the FPU is + in use in case the FPU was used before the scheduler was started - which + would otherwise result in the unnecessary leaving of space in the SVC stack + for lazy saving of FPU registers. */ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. */ + " msr control, r0 \n" + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + /* This port can be used on all revisions of the Cortex-M7 core other than + the r0p1 parts. r0p1 parts should use the port from the + /source/portable/GCC/ARM_CM7/r0p1 directory. */ + configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); + configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + #ifdef __NVIC_PRIO_BITS + { + /* Check the CMSIS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS ); + } + #endif + + #ifdef configPRIO_BITS + { + /* Check the FreeRTOS configuration that defines the number of + priority bits matches the number of priority bits actually queried + from the hardware. */ + configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS ); + } + #endif + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + exit error function to prevent compiler warnings about a static function + not being called in the case that the application writer overrides this + functionality by defining configTASK_RETURN_ADDRESS. Call + vTaskSwitchContext() so link time optimisation does not remove the + symbol. */ + vTaskSwitchContext(); + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + " \n" + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r0, r3} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r0, r3} \n" + " \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" + " \n" + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" + " \n" + " msr psp, r0 \n" + " isb \n" + " \n" + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ + #if WORKAROUND_PMU_CM001 == 1 + " push { r14 } \n" + " pop { pc } \n" + #endif + #endif + " \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portENABLE_INTERRUPTS(); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TICKLESS_IDLE == 1 ) + + __attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __asm volatile( "cpsid i" ::: "memory" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ::: "memory" ); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ::: "memory" ); + __asm volatile( "wfi" ); + __asm volatile( "isb" ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Re-enable interrupts to allow the interrupt that brought the MCU + out of sleep mode to execute immediately. see comments above + __disable_interrupt() call above. */ + __asm volatile( "cpsie i" ::: "memory" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* Disable interrupts again because the clock is about to be stopped + and interrupts that execute while the clock is stopped will increase + any slippage between the time maintained by the RTOS and calendar + time. */ + __asm volatile( "cpsid i" ::: "memory" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* Disable the SysTick clock without reading the + portNVIC_SYSTICK_CTRL_REG register to ensure the + portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again, + the time the SysTick is stopped for is accounted for as best it can + be, but using the tickless mode will inevitably result in some tiny + drift of the time maintained by the kernel with respect to calendar + time*/ + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); + + /* Determine if the SysTick clock has already counted to zero and + been set back to the current reload value (the reload back being + correct for the entire expected idle time) or if the SysTick is yet + to count to zero (in which case an interrupt other than the SysTick + must have brought the system out of sleep mode). */ + if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt is already pending, and the SysTick count + reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* As the pending tick will be processed as soon as this + function exits, the tick value maintained by the tick is stepped + forward by one less than the time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Exit with interrupts enabled. */ + __asm volatile( "cpsie i" ::: "memory" ); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if( configUSE_TICKLESS_IDLE == 1 ) + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Stop and clear the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vPortEnableVFP( void ) +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredictable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h b/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..e1e7fad --- /dev/null +++ b/gcc/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h @@ -0,0 +1,243 @@ +/* + * FreeRTOS Kernel V10.3.1 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +#define portYIELD() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ::: "memory" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ +uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory" + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory" + ); +} +/*-----------------------------------------------------------*/ + +#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/gcc/include/cube_programmer.mk b/gcc/include/cube_programmer.mk new file mode 100644 index 0000000..cda936f --- /dev/null +++ b/gcc/include/cube_programmer.mk @@ -0,0 +1,38 @@ +stm32cube_programmer_path := STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin +stm32cube_programmer_filename := STM32_Programmer_CLI.exe +stm32cube_programmer_filepath := $(stm32cube_programmer_path)/$(stm32cube_programmer_filename) +stm32cube_loader_relative_path := ExternalLoader/$(stldr) +stm32cube_loader := $(stm32cube_programmer_path)/$(stm32cube_loader_relative_path) + +program_files_win32 = /c/Program Files (x86) +program_files_win64 = /c/Program Files +program_files_CLT = /c/ST/STM32CubeCLT/STM32CubeCLT/ + +# Check which tools are installed +ifneq ("$(shell find "$(program_files_win64)/$(stm32cube_programmer_filepath)" 2> nul )","") +program_files_path := $(program_files_win64) +else ifneq ("$(shell find "$(program_files_win32)/$(stm32cube_programmer_filepath)" 2> nul )","") +program_files_path := $(program_files_win32) +else ifneq ("$(shell find "$(program_files_CLT)/$(stm32cube_programmer_filepath)" 2> nul )","") +program_files_path := $(program_files_CLT) +endif + +st_stm32cube_programmer_path := $(program_files_path)/$(stm32cube_programmer_path) +st_stm32cube_programmer_filepath := $(program_files_path)/$(stm32cube_programmer_filepath) +st_stm32cube_external_loader := $(program_files_path)/$(stm32cube_loader) + +# define variable n as some line breaks for the error message +define error_msg + + + +**************************************************************************************************************************** +* * +* STM32CubeProgrammer is not found. Make sure the STM32CubeProgrammer is installed in its default directory. * +* You can download it at https://www.st.com/en/development-tools/stm32cubeprog.html * +* * +**************************************************************************************************************************** + + + +endef \ No newline at end of file diff --git a/gcc/include/flash_sections_int_ext.mk b/gcc/include/flash_sections_int_ext.mk new file mode 100644 index 0000000..80ba0aa --- /dev/null +++ b/gcc/include/flash_sections_int_ext.mk @@ -0,0 +1,10 @@ +_extflash_: +ifeq ($(program_files_path),) + $(error $(error_msg)) +endif + @cd "$(st_stm32cube_programmer_path)" && ./$(stm32cube_programmer_filename) -c port=SWD ap=1 -d $(application_path)/$(binary_output_path)/target.hex -el $(stm32cube_loader_relative_path) -hardRst +_intflash_: +ifeq ($(program_files_path),) + $(error $(error_msg)) +endif + @cd "$(st_stm32cube_programmer_path)" && ./$(stm32cube_programmer_filename) -c port=SWD ap=1 -d $(application_path)/$(binary_output_path)/intflash.hex -el $(stm32cube_loader_relative_path) -hardRst diff --git a/gcc/makefile_appli b/gcc/makefile_appli new file mode 100644 index 0000000..b58e5bb --- /dev/null +++ b/gcc/makefile_appli @@ -0,0 +1,469 @@ +# Helper macros to convert spaces into question marks and back again +e := +sp := $(e) $(e) +qs = $(subst ?,$(sp),$1) +sq = $(subst $(sp),?,$1) + +# Get name of this Makefile (avoid getting word 0 and a starting space) +makefile_name := $(wordlist 1,1000,$(MAKEFILE_LIST)) + +# Get path of this Makefile +makefile_path := $(call qs,$(dir $(call sq,$(abspath $(call sq,$(makefile_name)))))) + +# Get path where the Application is +application_path := $(call qs,$(abspath $(call sq,$(makefile_path)..))) + +# Change makefile_name to a relative path +makefile_name := $(subst $(call sq,$(application_path))/,,$(call sq,$(abspath $(call sq,$(makefile_name))))) + +# Get relative path to makefile from application_path +makefile_path_relative := $(subst $(call sq,$(application_path))/,,$(call sq,$(abspath $(call sq,$(makefile_path))))) + +# Get path to Middlewares +touchgfx_middlewares_path := gcc/Middlewares +cubemx_middlewares_path := Middlewares + +# Get path to Drivers +Drivers_path := Drivers + +# Get path to GPU2D +gpu2d_path := Appli/Middlewares/ST/touchgfx_components/gpu2d + +# Get OS path +touchgfx_os_path := $(touchgfx_middlewares_path)/Third_Party/FreeRTOS +cubemx_os_path := $(cubemx_middlewares_path)/Third_Party/FreeRTOS + +# Get identification of this system +ifeq ($(OS),Windows_NT) +UNAME := MINGW32_NT-6.2 +else +UNAME := $(shell uname -s) +endif + +board_name := STM32H7S78-DK +platform := cortex_m7 +cpp_compiler_options_local := +c_compiler_options_local := + +.PHONY: all clean assets flash intflash + +all: $(filter clean,$(MAKECMDGOALS)) +all clean assets: + @cd "$(application_path)" && $(MAKE) -r -f $(makefile_name) -s $(MFLAGS) _$@_ + +flash intflash: all + @cd "$(application_path)" && $(MAKE) -r -f $(makefile_name) -s $(MFLAGS) _$@_ + +# Directories containing application-specific source and header files. +# Additional components can be added to this list. make will look for +# source files recursively in comp_name/src and setup an include directive +# for comp_name/include. +components := \ + Appli/TouchGFX/gui \ + Appli/TouchGFX/generated/gui_generated + +touchgfx_generator_components := \ + Appli/TouchGFX/target \ + Appli/TouchGFX/App + +# Location of folder containing bmp/png files. +asset_images_input := Appli/TouchGFX/assets/images + +# Location of folder to search for ttf font files +asset_fonts_input := Appli/TouchGFX/assets/fonts + +# Location of folder where the texts.xml is placed +asset_texts_input := Appli/TouchGFX/assets/texts + +# Location of folder where the video.avi is placed +asset_videos_input := Appli/TouchGFX/assets/videos + +build_root_path := Appli/TouchGFX/build +object_output_path := $(build_root_path)/$(board_name) +binary_output_path := $(build_root_path)/bin + +# Location of output folders where autogenerated code from assets is placed +asset_root_path := Appli/TouchGFX/generated +asset_images_output := $(asset_root_path)/images +asset_fonts_output := $(asset_root_path)/fonts +asset_texts_output := $(asset_root_path)/texts +asset_videos_output := $(asset_root_path)/videos + +#include application specific configuration +include $(application_path)/Appli/TouchGFX/config/gcc/app.mk + +# corrects TouchGFX Path +touchgfx_path := Appli/${subst ../,,$(touchgfx_path)} + +os_source_files := \ + $(cubemx_os_path)/Source/croutine.c \ + $(cubemx_os_path)/Source/event_groups.c \ + $(cubemx_os_path)/Source/list.c \ + $(cubemx_os_path)/Source/queue.c \ + $(cubemx_os_path)/Source/stream_buffer.c \ + $(cubemx_os_path)/Source/tasks.c \ + $(cubemx_os_path)/Source/timers.c \ + $(cubemx_os_path)/Source/CMSIS_RTOS_V2/cmsis_os2.c + +os_include_paths := \ + $(cubemx_os_path)/Source/include \ + $(cubemx_os_path)/Source/CMSIS_RTOS_V2 \ + $(touchgfx_os_path)/Source/portable/GCC/ARM_CM4F + +# these paths can be moved to the touchgfx portable dirs in the future +os_source_files += \ + $(cubemx_os_path)/Source/portable/MemMang/heap_4.c \ + $(cubemx_os_path)/Source/portable/Common/mpu_wrappers.c \ + $(touchgfx_os_path)/Source/portable/GCC/ARM_CM4F/port.c + + + +ifeq ($(UNAME), Linux) +imageconvert_executable := $(touchgfx_path)/framework/tools/imageconvert/build/linux/imageconvert.out +fontconvert_executable := $(touchgfx_path)/framework/tools/fontconvert/build/linux/fontconvert.out +else +imageconvert_executable := $(touchgfx_path)/framework/tools/imageconvert/build/win/imageconvert.out +fontconvert_executable := $(touchgfx_path)/framework/tools/fontconvert/build/win/fontconvert.out + +stldr := MX66UW1G45G_STM32H7S78-DK.stldr +include $(application_path)/gcc/include/cube_programmer.mk + +endif + +target_executable := target.elf +target_hex := target.hex + +assembler := arm-none-eabi-gcc +c_compiler := arm-none-eabi-gcc +cpp_compiler := arm-none-eabi-g++ +linker := arm-none-eabi-g++ +objcopy := arm-none-eabi-objcopy +archiver := arm-none-eabi-ar +strip := arm-none-eabi-strip + +assembler_options += \ + -Wall \ + -fno-exceptions \ + -g3 \ + -mthumb \ + -MMD \ + -MP \ + -c \ + -x assembler-with-cpp + +c_compiler_options += \ + --specs=nano.specs \ + -MMD \ + -MP \ + -Os \ + -Wall \ + -fdata-sections \ + -ffunction-sections \ + -fno-exceptions \ + -fstack-usage \ + -g3 \ + -mthumb \ + -std=gnu11 + +cpp_compiler_options += \ + --specs=nano.specs \ + -Os \ + -fdata-sections \ + -fno-exceptions \ + -fno-rtti \ + -g3 \ + -MMD \ + -MP \ + -Wall \ + -femit-class-debug-always \ + -ffunction-sections \ + -fno-use-cxa-atexit \ + -fstack-usage \ + -mthumb \ + -std=gnu++14 + +linker_options += \ + --specs=nosys.specs \ + -Os \ + -Wl,--gc-sections -static \ + -Wl,--print-memory-usage \ + -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group \ + -fno-exceptions \ + -fno-rtti \ + -g3 \ + -mthumb + +# Additional toolchain configuration for Cortex-M7 targets. +float_options := -mfpu=fpv5-d16 -mfloat-abi=hard + +assembler_options += $(float_options) -mcpu=cortex-m7 -DCORE_CM7 +c_compiler_options += $(float_options) -mcpu=cortex-m7 -DCORE_CM7 +cpp_compiler_options += $(float_options) -mcpu=cortex-m7 -DCORE_CM7 +linker_options += $(float_options) -mcpu=cortex-m7 + +c_compiler_options += -DSTM32H7S7xx -DUSE_HAL_DRIVER +cpp_compiler_options += -DSTM32H7S7xx -DUSE_HAL_DRIVER + +# include everything + specific vendor folders +framework_includes := $(touchgfx_path)/framework/include + +# this needs to change when assset include folder changes. +all_components := $(components) \ + $(asset_fonts_output) \ + $(asset_images_output) \ + $(asset_texts_output) \ + $(asset_videos_output) + + +include_paths := $(library_includes) \ + $(foreach comp, $(all_components), $(comp)/include) \ + $(foreach comp, $(touchgfx_generator_components), $(comp)/generated) \ + $(framework_includes) \ + $(cubemx_middlewares_path) \ + $(touchgfx_middlewares_path) \ + $(touchgfx_generator_components) + +source_paths = $(foreach comp, $(all_components), $(comp)/src) \ + $(touchgfx_generator_components) + +# Finds files that matches the specified pattern. The directory list +# is searched recursively. It is safe to invoke this function with an +# empty list of directories. +# +# Param $(1): List of directories to search +# Param $(2): The file pattern to search for +define find + $(foreach dir,$(1),$(foreach d,$(wildcard $(dir)/*),\ + $(call find,$(d),$(2))) $(wildcard $(dir)/$(strip $(2)))) +endef +unexport find + +fontconvert_ttf_lower_files := $(call find, $(asset_fonts_input), *.ttf) +fontconvert_ttf_upper_files := $(call find, $(asset_fonts_input), *.TTF) +fontconvert_otf_lower_files := $(call find, $(asset_fonts_input), *.otf) +fontconvert_otf_upper_files := $(call find, $(asset_fonts_input), *.OTF) +fontconvert_bdf_lower_files := $(call find, $(asset_fonts_input), *.bdf) +fontconvert_bdf_upper_files := $(call find, $(asset_fonts_input), *.BDF) +fontconvert_font_files := \ + $(fontconvert_ttf_lower_files) \ + $(fontconvert_ttf_upper_files) \ + $(fontconvert_otf_lower_files) \ + $(fontconvert_otf_upper_files) \ + $(fontconvert_bdf_lower_files) \ + $(fontconvert_bdf_upper_files) + +source_files := $(call find, $(source_paths),*.cpp) + +video_files := $(call find, $(assets_videos_input),*.avi) + +# Drivers/STM32H7RSxx_HAL_Driver +board_c_files += \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_crc_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma2d.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpu2d.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_i2c_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_icache.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_jpeg.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_ltdc_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_smbus_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c + +board_c_files += \ + Appli/Core/Src/main.c \ + Appli/Core/Src/freertos.c \ + Appli/Core/Src/stm32h7rsxx_it.c \ + Appli/Core/Src/stm32h7rsxx_hal_msp.c \ + Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c \ + Appli/Core/Src/system_stm32h7rsxx.c + +# Drivers +board_include_paths := \ + $(Drivers_path)/CMSIS/Include \ + $(Drivers_path)/CMSIS/Device/ST/STM32H7RSxx/Include \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Inc \ + $(Drivers_path)/CMSIS/RTOS2/Include \ + Appli/Core/Inc \ + $(gpu2d_path)/TouchGFXNema/include \ + $(gpu2d_path)/NemaGFX/include + + +asm_source_files := \ + gcc/startup_stm32h7s7l8hxh_appli.s + +include_paths += platform/os $(board_include_paths) $(os_include_paths) + +video_object_files := $(call find, $(asset_videos_output),*.o) +c_source_files := $(makefile_path_relative)/sysmem.c $(makefile_path_relative)/syscalls.c $(call find, $(source_paths),*.c) $(os_source_files) $(board_c_files) +source_files += $(board_cpp_files) +object_files := $(source_files) $(c_source_files) + +# start converting paths +object_files := $(object_files:$(touchgfx_path)/%.cpp=$(object_output_path)/touchgfx/%.o) +object_files := $(object_files:%.cpp=$(object_output_path)/%.o) +object_files := $(object_files:$(touchgfx_middlewares_path)/%.c=$(object_output_path)/$(touchgfx_middlewares_path)/%.o) +object_files := $(object_files:$(cubemx_middlewares_path)/%.c=$(object_output_path)/$(cubemx_middlewares_path)/%.o) +object_files := $(object_files:$(Drivers_path)/%.c=$(object_output_path)/Drivers/%.o) +object_files := $(object_files:%.c=$(object_output_path)/%.o) + +# remove templates files +object_files := $(filter-out %template.o,$(object_files)) + +dependency_files := $(object_files:%.o=%.d) + +object_asm_files := $(asm_source_files:%.s=$(object_output_path)/%.o) +object_asm_files := $(patsubst $(object_output_path)/%,$(object_output_path)/%,$(object_asm_files)) + +textconvert_script_path := $(touchgfx_path)/framework/tools/textconvert +textconvert_executable := $(call find, $(textconvert_script_path), *.rb) +videoconvert_script_path := $(touchgfx_path)/framework/tools/videoconvert + +text_database := $(asset_texts_input)/texts.xml + +libraries := touchgfx-float-abi-hard +library_include_paths := $(touchgfx_path)/lib/core/$(platform)/gcc \ + +libraries += touchgfxnema-float-abi-hard \ + nemagfx-float-abi-hard + +library_include_paths += $(gpu2d_path)/TouchGFXNema/lib/cortex_m7/gcc \ + $(gpu2d_path)/NemaGFX/lib/core/cortex_m7/gcc + + +.PHONY: _all_ _clean_ _assets_ _flash_ _intflash_ generate_assets build_executable + +# Force linking each time +.PHONY: $(binary_output_path)/$(target_executable) + +_all_: generate_assets + +# if ExtFlashSection or FontFlashSection is detected inside the executable, enable external flash +flash_section_count := 0 +elf_filename := "$(application_path)/$(binary_output_path)/$(target_executable)" +ifeq ($(shell test -e $(elf_filename) && echo -n has_elf_file),has_elf_file) +flash_section_count := $(shell readelf -S $(elf_filename) | grep FlashSection | wc -l) +endif + +ifeq ($(shell test $(flash_section_count) -gt 0; echo $$?),0) +_flash_: _extflash_ +else +_flash_: _intflash_ +endif + +include $(application_path)/gcc/include/flash_sections_int_ext.mk + +generate_assets: _assets_ + @$(MAKE) -f $(makefile_name) -r -s $(MFLAGS) build_executable +build_executable: $(binary_output_path)/$(target_executable) + +$(binary_output_path)/$(target_executable): $(object_files) $(object_asm_files) + @echo Video Objects: $(video_object_files) + @echo Linking $(@) + @mkdir -p $(@D) + @mkdir -p $(object_output_path) + @$(file >$(build_root_path)/objects.tmp) $(foreach F,$(object_files) $(video_object_files),$(file >>$(build_root_path)/objects.tmp,$F)) + @$(linker) \ + $(linker_options) -T $(makefile_path_relative)/../Appli/stm32h7rsxx_RAMxspi1_ROMxspi2.ld -Wl,-Map=$(@D)/application.map $(linker_options_local) \ + $(patsubst %,-L%,$(library_include_paths)) \ + @$(build_root_path)/objects.tmp $(object_asm_files) -o $@ \ + -Wl,--start-group $(patsubst %,-l%,$(libraries)) -Wl,--end-group + @rm -f $(build_root_path)/objects.tmp + @echo "Producing additional output formats..." + @echo " target.hex - Combined internal+external hex" + @$(objcopy) -O ihex $@ $(@D)/target.hex + @echo " intflash.elf - Internal flash, elf debug" + @$(objcopy) --remove-section=ExtFlashSection --remove-section=FontFlashSection --remove-section=TextFlashSection $@ $(@D)/intflash.elf 2>/dev/null + @echo " intflash.hex - Internal flash, hex" + @$(objcopy) -O ihex --remove-section=ExtFlashSection --remove-section=FontFlashSection --remove-section=TextFlashSection $@ $(@D)/intflash.hex + # re-enable if extflash binaries are required in your workflow + # @echo " extflash.bin - External flash, binary" + # @$(objcopy) -O binary --only-section=*FlashSection $@ $(@D)/extflash.bin + +$(object_output_path)/touchgfx/%.o: $(touchgfx_path)/%.cpp Appli/TouchGFX/config/gcc/app.mk + @echo Compiling $< + @mkdir -p $(@D) + @$(cpp_compiler) \ + -MMD -MP $(cpp_compiler_options) $(cpp_compiler_options_local) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/%.o: %.cpp Appli/TouchGFX/config/gcc/app.mk + @echo Compiling $< + @mkdir -p $(@D) + @$(cpp_compiler) \ + -MMD -MP $(cpp_compiler_options) $(cpp_compiler_options_local) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/touchgfx/%.o: $(touchgfx_path)/%.c Appli/TouchGFX/config/gcc/app.mk + @echo Compiling $< + @mkdir -p $(@D) + @$(c_compiler) \ + -MMD -MP $(c_compiler_options) $(c_compiler_options_local) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/%.o: %.c Appli/TouchGFX/config/gcc/app.mk + @echo Compiling $< + @mkdir -p $(@D) + @$(c_compiler) \ + -MMD -MP $(c_compiler_options) $(c_compiler_options_local) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/%.o: %.s Appli/TouchGFX/config/gcc/app.mk + @echo Compiling ASM $< + @mkdir -p $(@D) + @$(assembler) \ + $(assembler_options) \ + $(patsubst %,-I %,$(os_include_paths)) \ + -c $< -o $@ + +ifeq ($(MAKECMDGOALS),build_executable) +$(firstword $(dependency_files)): Appli/TouchGFX/config/gcc/app.mk + @rm -rf $(object_output_path) +-include $(dependency_files) +endif + +_assets_: images texts Videos + +.PHONY: images texts Videos + +images: + @$(imageconvert_executable) -r $(asset_images_input) -w $(asset_images_output) + +Videos: + @ruby $(videoconvert_script_path)/videoconvert.rb $(asset_videos_input) $(asset_videos_output) + +texts: + @ruby $(textconvert_script_path)/main.rb $(text_database) $(fontconvert_executable) $(asset_fonts_output) $(asset_texts_output) $(asset_fonts_input) Appli/TouchGFX + +_clean_: + @echo Cleaning + @rm -rf $(build_root_path) + # Do not remove gui_generated + @rm -rf $(asset_images_output) + @rm -rf $(asset_fonts_output) + @rm -rf $(asset_texts_output) + @rm -rf $(asset_videos_output) + # Create directory to avoid error if it does not exist + @mkdir -p $(asset_root_path) + # Remove assets folder if it is empty (i.e. no gui_generated folder) + @rmdir --ignore-fail-on-non-empty $(asset_root_path) diff --git a/gcc/makefile_boot b/gcc/makefile_boot new file mode 100644 index 0000000..3730fc9 --- /dev/null +++ b/gcc/makefile_boot @@ -0,0 +1,295 @@ +# Helper macros to convert spaces into question marks and back again +e := +sp := $(e) $(e) +qs = $(subst ?,$(sp),$1) +sq = $(subst $(sp),?,$1) + +# Get name of this Makefile (avoid getting word 0 and a starting space) +makefile_name := $(wordlist 1,1000,$(MAKEFILE_LIST)) + +# Get path of this Makefile +makefile_path := $(call qs,$(dir $(call sq,$(abspath $(call sq,$(makefile_name)))))) + +# Get path where the Application is +application_path := $(call qs,$(abspath $(call sq,$(makefile_path)..))) + +# Change makefile_name to a relative path +makefile_name := $(subst $(call sq,$(application_path))/,,$(call sq,$(abspath $(call sq,$(makefile_name))))) + +# Get relative path to makefile from application_path +makefile_path_relative := $(subst $(call sq,$(application_path))/,,$(call sq,$(abspath $(call sq,$(makefile_path))))) + +# Get path to Drivers +Drivers_path := Drivers + +# Get path to ExtMem_Manager +ExtMem_Manager_path := Middlewares/ST/STM32_ExtMem_Manager + +# Get identification of this system +ifeq ($(OS),Windows_NT) +UNAME := MINGW32_NT-6.2 +else +UNAME := $(shell uname -s) +endif + +board_name := STM32H7S78-DK +platform := cortex_m7 + +.PHONY: all clean assets flash intflash + +all: $(filter clean,$(MAKECMDGOALS)) +all clean assets: + @cd "$(application_path)" && $(MAKE) -r -f $(makefile_name) -s $(MFLAGS) _$@_ + +flash intflash: all + @cd "$(application_path)" && $(MAKE) -r -f $(makefile_name) -s $(MFLAGS) _$@_ + +build_root_path := Boot/TouchGFX/build +object_output_path := $(build_root_path)/$(board_name) +binary_output_path := $(build_root_path)/bin + +ifeq ($(UNAME), Linux) +else +stldr := MX66UW1G45G_STM32H7S78-DK.stldr +include $(application_path)/gcc/include/cube_programmer.mk +endif + +target_executable := target.elf +target_hex := target.hex + +assembler := arm-none-eabi-gcc +c_compiler := arm-none-eabi-gcc +cpp_compiler := arm-none-eabi-g++ +linker := arm-none-eabi-g++ +objcopy := arm-none-eabi-objcopy +archiver := arm-none-eabi-ar +strip := arm-none-eabi-strip + +assembler_options += \ + -MMD \ + -MP \ + -Wall \ + -c \ + -fno-exceptions \ + -g \ + -mthumb \ + -x assembler-with-cpp + +c_compiler_options += \ + --specs=nano.specs \ + -MMD \ + -MP \ + -Os \ + -Wall \ + -fdata-sections \ + -fdata-sections \ + -ffunction-sections \ + -fno-exceptions \ + -fstack-usage \ + -g \ + -mthumb \ + -std=gnu11 + +cpp_compiler_options += \ + --specs=nano.specs \ + -MMD \ + -MP \ + -Os \ + -fdata-sections \ + -ffunction-sections \ + -fno-exceptions \ + -fno-rtti \ + -g \ + -mthumb \ + -std=gnu++14 + +linker_options += \ + --specs=nosys.specs \ + -Os \ + -Wl,--gc-sections -static \ + -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group \ + -fno-exceptions \ + -fno-rtti \ + -g \ + -mthumb + +# Additional toolchain configuration for Cortex-M4 targets. +float_options := -mfpu=fpv5-sp-d16 -mfloat-abi=hard + +assembler_options += $(float_options) -mcpu=cortex-m7 -DCORE_CM7 +c_compiler_options += $(float_options) -mcpu=cortex-m7 -DCORE_CM7 +cpp_compiler_options += $(float_options) -mcpu=cortex-m7 -DCORE_CM7 +linker_options += $(float_options) -mcpu=cortex-m7 + +c_compiler_options += -DST -DSTM32H7S7xx -DUSE_HAL_DRIVER -DUSE_STM32H7S78_DK -DUSE_PWR_LDO_SUPPLY__N -DUSE_FLOATING_POINT +cpp_compiler_options += -DST -DSTM32H7S7xx -DUSE_HAL_DRIVER -DUSE_STM32H7S78_DK -DUSE_PWR_LDO_SUPPLY__N -DUSE_FLOATING_POINT + +# Drivers/STM32H7RSxx_HAL_Driver +source_files += \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_cortex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_dma_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_exti.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_flash_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_gpio.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_pwr_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_rcc_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_tim_ex.c \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Src/stm32h7rsxx_hal_xspi.c + +source_files += \ + Boot/Core/Src/main.c \ + Boot/Core/Src/stm32h7rsxx_it.c \ + Boot/Core/Src/stm32h7rsxx_hal_msp.c \ + Boot/Core/Src/system_stm32h7rsxx.c \ + Boot/Core/Src/extmem_manager.c \ + $(ExtMem_Manager_path)/stm32_extmem.c \ + $(ExtMem_Manager_path)/boot/stm32_boot_xip.c \ + $(ExtMem_Manager_path)/nor_sfdp/stm32_sfdp_data.c \ + $(ExtMem_Manager_path)/nor_sfdp/stm32_sfdp_driver.c \ + $(ExtMem_Manager_path)/psram/stm32_psram_driver.c \ + $(ExtMem_Manager_path)/sal/stm32_sal_sd.c \ + $(ExtMem_Manager_path)/sal/stm32_sal_xspi.c \ + $(ExtMem_Manager_path)/sdcard/stm32_sdcard_driver.c \ + $(ExtMem_Manager_path)/user/stm32_user_driver.c + +# Drivers +board_include_paths := \ + $(Drivers_path)/CMSIS/Include \ + $(Drivers_path)/CMSIS/Device/ST/STM32H7RSxx/Include \ + $(Drivers_path)/STM32H7RSxx_HAL_Driver/Inc \ + $(Drivers_path)/CMSIS/RTOS2/Include \ + Boot/Core/Inc \ + $(ExtMem_Manager_path) \ + $(ExtMem_Manager_path)/boot \ + $(ExtMem_Manager_path)/nor_sfdp \ + $(ExtMem_Manager_path)/psram \ + $(ExtMem_Manager_path)/sal \ + $(ExtMem_Manager_path)/sdcard \ + $(ExtMem_Manager_path)/user + +asm_source_files := \ + gcc/startup_stm32h7s7l8hxh_boot.s + +include_paths += platform/os $(board_include_paths) $(os_include_paths) + +c_source_files := $(makefile_path_relative)/sysmem.c $(makefile_path_relative)/syscalls.c $(call find, $(source_paths),*.c) $(os_source_files) $(board_c_files) +source_files += $(board_cpp_files) +object_files := $(source_files) $(c_source_files) + +# start converting paths +object_files := $(object_files:%.cpp=$(object_output_path)/%.o) +object_files := $(object_files:%.c=$(object_output_path)/%.o) +object_files := $(object_files:$(Drivers_path)/%.c=$(object_output_path)/Drivers/%.o) + +# remove templates files +# object_files := $(filter-out %template.o,$(object_files)) + +dependency_files := $(object_files:%.o=%.d) + +object_asm_files := $(asm_source_files:%.s=$(object_output_path)/%.o) +object_asm_files := $(patsubst $(object_output_path)/%,$(object_output_path)/%,$(object_asm_files)) + +.PHONY: _all_ _clean_ _assets_ _flash_ _intflash_ generate_assets build_executable + +# Force linking each time +.PHONY: $(binary_output_path)/$(target_executable) + +_all_: generate_assets + +# if ExtFlashSection or FontFlashSection is detected inside the executable, enable external flash +flash_section_count := 0 +elf_filename := "$(application_path)/$(binary_output_path)/$(target_executable)" +ifeq ($(shell test -e $(elf_filename) && echo -n has_elf_file),has_elf_file) +flash_section_count := $(shell readelf -S $(elf_filename) | grep FlashSection | wc -l) +endif + +ifeq ($(shell test $(flash_section_count) -gt 0; echo $$?),0) +_flash_: _extflash_ +else +_flash_: _intflash_ +endif + +include $(application_path)/gcc/include/flash_sections_int_ext.mk + +generate_assets: _assets_ + @$(MAKE) -f $(makefile_name) -r -s $(MFLAGS) build_executable + +build_executable: $(binary_output_path)/$(target_executable) + +$(binary_output_path)/$(target_executable): $(object_files) $(object_asm_files) + @echo Linking $(@) + @mkdir -p $(@D) + @mkdir -p $(object_output_path) + @$(file >$(build_root_path)/objects.tmp) $(foreach F,$(object_files),$(file >>$(build_root_path)/objects.tmp,$F)) + @$(linker) \ + $(linker_options) -T $(makefile_path_relative)/../Boot/stm32h7s7xx_flash.ld -Wl,-Map=$(@D)/application.map \ + $(patsubst %,-L%,$(library_include_paths)) \ + @$(build_root_path)/objects.tmp $(object_asm_files) -o $@ \ + -Wl,--start-group -Wl,--end-group + @rm -f $(build_root_path)/objects.tmp + @echo "Producing additional output formats..." + @echo " target.hex - Combined internal+external hex" + @$(objcopy) -O ihex $@ $(@D)/target.hex + @echo " intflash.elf - Internal flash, elf debug" + @$(objcopy) $@ $(@D)/intflash.elf 2>/dev/null + @echo " intflash.hex - Internal flash, hex" + @$(objcopy) -O ihex $@ $(@D)/intflash.hex + # Re-enable the lines below if your workflow requires extflash.bin files + # @echo " extflash.bin - External flash, binary" + # @$(objcopy) -O binary $@ $(@D)/extflash.bin + +$(object_output_path)/touchgfx/%.o: $(touchgfx_path)/%.cpp + @echo Compiling $< + @mkdir -p $(@D) + @$(cpp_compiler) \ + -MMD -MP $(cpp_compiler_options) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/%.o: %.cpp + @echo Compiling $< + @mkdir -p $(@D) + @$(cpp_compiler) \ + -MMD -MP $(cpp_compiler_options) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/touchgfx/%.o: $(touchgfx_path)/%.c + @echo Compiling $< + @mkdir -p $(@D) + @$(c_compiler) \ + -MMD -MP $(c_compiler_options) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/%.o: %.c + @echo Compiling $< + @mkdir -p $(@D) + @$(c_compiler) \ + -MMD -MP $(c_compiler_options) $(user_cflags) \ + $(patsubst %,-I%,$(include_paths)) \ + -c $< -o $@ + +$(object_output_path)/%.o: %.s + @echo Compiling ASM $< + @mkdir -p $(@D) + @$(assembler) \ + $(assembler_options) \ + $(patsubst %,-I %,$(os_include_paths)) \ + -c $< -o $@ + +ifeq ($(MAKECMDGOALS),build_executable) +$(firstword $(dependency_files)): + @rm -rf $(object_output_path) +-include $(dependency_files) +endif + +_clean_: + @echo Cleaning: $(board_name) + @rm -rf $(build_root_path) diff --git a/gcc/startup_stm32h7s7l8hxh_appli.s b/gcc/startup_stm32h7s7l8hxh_appli.s new file mode 100644 index 0000000..e6124df --- /dev/null +++ b/gcc/startup_stm32h7s7l8hxh_appli.s @@ -0,0 +1,780 @@ +/** + ****************************************************************************** + * @file startup_stm32h7s7xx.s + * @author MCD Application Team + * @brief STM32H7S7xx Devices vector table for 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 + * - 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-m7 + .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 STM32H7S7xx 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 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + /* External Interrupts */ + .word PVD_PVM_IRQHandler /* PVD/PVM through EXTI Line detection */ + .word 0 /* Reserved */ + .word DTS_IRQHandler /* Digital Temperature Sensor */ + .word IWDG_IRQHandler /* Internal Watchdog */ + .word WWDG_IRQHandler /* Window Watchdog */ + .word RCC_IRQHandler /* RCC global interrupts through EXTI Line detection */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FLASH_IRQHandler /* FLASH interrupts */ + .word RAMECC_IRQHandler /* RAMECC interrupts */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word TAMP_IRQHandler /* Tamper and TimeStamp interrupts */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word EXTI5_IRQHandler /* EXTI Line5 */ + .word EXTI6_IRQHandler /* EXTI Line6 */ + .word EXTI7_IRQHandler /* EXTI Line7 */ + .word EXTI8_IRQHandler /* EXTI Line8 */ + .word EXTI9_IRQHandler /* EXTI Line9 */ + .word EXTI10_IRQHandler /* EXTI Line10 */ + .word EXTI11_IRQHandler /* EXTI Line11 */ + .word EXTI12_IRQHandler /* EXTI Line12 */ + .word EXTI13_IRQHandler /* EXTI Line13 */ + .word EXTI14_IRQHandler /* EXTI Line14 */ + .word EXTI15_IRQHandler /* EXTI Line15 */ + .word RTC_IRQHandler /* RTC wakeup and alarm interrupts */ + .word SAES_IRQHandler /* SAES */ + .word CRYP_IRQHandler /* CRYP */ + .word PKA_IRQHandler /* PKA */ + .word HASH_IRQHandler /* HASH */ + .word RNG_IRQHandler /* RNG */ + .word ADC1_2_IRQHandler /* ADC1 & ADC2 */ + .word GPDMA1_Channel0_IRQHandler /* GPDMA1 Channel 0 */ + .word GPDMA1_Channel1_IRQHandler /* GPDMA1 Channel 1 */ + .word GPDMA1_Channel2_IRQHandler /* GPDMA1 Channel 2 */ + .word GPDMA1_Channel3_IRQHandler /* GPDMA1 Channel 3 */ + .word GPDMA1_Channel4_IRQHandler /* GPDMA1 Channel 4 */ + .word GPDMA1_Channel5_IRQHandler /* GPDMA1 Channel 5 */ + .word GPDMA1_Channel6_IRQHandler /* GPDMA1 Channel 6 */ + .word GPDMA1_Channel7_IRQHandler /* GPDMA1 Channel 7 */ + .word TIM1_BRK_IRQHandler /* TIM1 Break */ + .word TIM1_UP_IRQHandler /* TIM1 Update */ + .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word TIM5_IRQHandler /* TIM5 */ + .word TIM6_IRQHandler /* TIM6 */ + .word TIM7_IRQHandler /* TIM7 */ + .word TIM9_IRQHandler /* TIM9 */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word SPI3_IRQHandler /* SPI3 */ + .word SPI4_IRQHandler /* SPI4 */ + .word SPI5_IRQHandler /* SPI5 */ + .word SPI6_IRQHandler /* SPI6 */ + .word HPDMA1_Channel0_IRQHandler /* HPDMA1 Channel 0 */ + .word HPDMA1_Channel1_IRQHandler /* HPDMA1 Channel 1 */ + .word HPDMA1_Channel2_IRQHandler /* HPDMA1 Channel 2 */ + .word HPDMA1_Channel3_IRQHandler /* HPDMA1 Channel 3 */ + .word HPDMA1_Channel4_IRQHandler /* HPDMA1 Channel 4 */ + .word HPDMA1_Channel5_IRQHandler /* HPDMA1 Channel 5 */ + .word HPDMA1_Channel6_IRQHandler /* HPDMA1 Channel 6 */ + .word HPDMA1_Channel7_IRQHandler /* HPDMA1 Channel 7 */ + .word SAI1_A_IRQHandler /* Serial Audio Interface 1 block A */ + .word SAI1_B_IRQHandler /* Serial Audio Interface 1 block B */ + .word SAI2_A_IRQHandler /* Serial Audio Interface 2 block A */ + .word SAI2_B_IRQHandler /* Serial Audio Interface 2 block B */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word I2C3_EV_IRQHandler /* I2C3 Event */ + .word I2C3_ER_IRQHandler /* I2C3 Error */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word UART7_IRQHandler /* UART7 */ + .word UART8_IRQHandler /* UART8 */ + .word I3C1_EV_IRQHandler /* I3C1 Event */ + .word I3C1_ER_IRQHandler /* I3C1 Error */ + .word OTG_HS_IRQHandler /* USB OTG HS */ + .word ETH_IRQHandler /* Ethernet */ + .word CORDIC_IRQHandler /* CORDIC */ + .word GFXTIM_IRQHandler /* GFXTIM */ + .word DCMIPP_IRQHandler /* DCMIPP */ + .word LTDC_IRQHandler /* LTDC */ + .word LTDC_ER_IRQHandler /* LTDC error */ + .word DMA2D_IRQHandler /* DMA2D */ + .word JPEG_IRQHandler /* JPEG */ + .word GFXMMU_IRQHandler /* GFXMMU */ + .word I3C1_WKUP_IRQHandler /* I3C1 wakeup */ + .word MCE1_IRQHandler /* MCE1 */ + .word MCE2_IRQHandler /* MCE2 */ + .word MCE3_IRQHandler /* MCE3 */ + .word XSPI1_IRQHandler /* XSPI1 */ + .word XSPI2_IRQHandler /* XSPI2 */ + .word FMC_IRQHandler /* FMC */ + .word SDMMC1_IRQHandler /* SDMMC1 */ + .word SDMMC2_IRQHandler /* SDMMC2 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word TIM12_IRQHandler /* TIM12 */ + .word TIM13_IRQHandler /* TIM13 */ + .word TIM14_IRQHandler /* TIM14 */ + .word TIM15_IRQHandler /* TIM15 */ + .word TIM16_IRQHandler /* TIM16 */ + .word TIM17_IRQHandler /* TIM17 */ + .word LPTIM1_IRQHandler /* LP TIM1 */ + .word LPTIM2_IRQHandler /* LP TIM2 */ + .word LPTIM3_IRQHandler /* LP TIM3 */ + .word LPTIM4_IRQHandler /* LP TIM4 */ + .word LPTIM5_IRQHandler /* LP TIM5 */ + .word SPDIF_RX_IRQHandler /* SPDIF_RX */ + .word MDIOS_IRQHandler /* MDIOS */ + .word ADF1_FLT0_IRQHandler /* ADF1 Filter 0 */ + .word CRS_IRQHandler /* CRS */ + .word UCPD1_IRQHandler /* UCPD1 */ + .word CEC_IRQHandler /* HDMI_CEC */ + .word PSSI_IRQHandler /* PSSI */ + .word LPUART1_IRQHandler /* LP UART1 */ + .word WAKEUP_PIN_IRQHandler /* Wake-up pins interrupt */ + .word GPDMA1_Channel8_IRQHandler /* GPDMA1 Channel 8 */ + .word GPDMA1_Channel9_IRQHandler /* GPDMA1 Channel 9 */ + .word GPDMA1_Channel10_IRQHandler /* GPDMA1 Channel 10 */ + .word GPDMA1_Channel11_IRQHandler /* GPDMA1 Channel 11 */ + .word GPDMA1_Channel12_IRQHandler /* GPDMA1 Channel 12 */ + .word GPDMA1_Channel13_IRQHandler /* GPDMA1 Channel 13 */ + .word GPDMA1_Channel14_IRQHandler /* GPDMA1 Channel 14 */ + .word GPDMA1_Channel15_IRQHandler /* GPDMA1 Channel 15 */ + .word HPDMA1_Channel8_IRQHandler /* HPDMA1 Channel 8 */ + .word HPDMA1_Channel9_IRQHandler /* HPDMA1 Channel 9 */ + .word HPDMA1_Channel10_IRQHandler /* HPDMA1 Channel 10 */ + .word HPDMA1_Channel11_IRQHandler /* HPDMA1 Channel 11 */ + .word HPDMA1_Channel12_IRQHandler /* HPDMA1 Channel 12 */ + .word HPDMA1_Channel13_IRQHandler /* HPDMA1 Channel 13 */ + .word HPDMA1_Channel14_IRQHandler /* HPDMA1 Channel 14 */ + .word HPDMA1_Channel15_IRQHandler /* HPDMA1 Channel 15 */ + .word GPU2D_IRQHandler /* GPU2D */ + .word GPU2D_ER_IRQHandler /* GPU2D error */ + .word ICACHE_IRQHandler /* ICACHE */ + .word FDCAN1_IT0_IRQHandler /* FDCAN1 Interrupt 0 */ + .word FDCAN1_IT1_IRQHandler /* FDCAN1 Interrupt 1 */ + .word FDCAN2_IT0_IRQHandler /* FDCAN2 Interrupt 0 */ + .word FDCAN2_IT1_IRQHandler /* FDCAN2 Interrupt 1 */ + +/******************************************************************************* +* +* 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 PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RAMECC_IRQHandler + .thumb_set RAMECC_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_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 RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak SAES_IRQHandler + .thumb_set SAES_IRQHandler,Default_Handler + + .weak CRYP_IRQHandler + .thumb_set CRYP_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak ADC1_2_IRQHandler + .thumb_set ADC1_2_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 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 TIM9_IRQHandler + .thumb_set TIM9_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 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 HPDMA1_Channel0_IRQHandler + .thumb_set HPDMA1_Channel0_IRQHandler,Default_Handler + + .weak HPDMA1_Channel1_IRQHandler + .thumb_set HPDMA1_Channel1_IRQHandler,Default_Handler + + .weak HPDMA1_Channel2_IRQHandler + .thumb_set HPDMA1_Channel2_IRQHandler,Default_Handler + + .weak HPDMA1_Channel3_IRQHandler + .thumb_set HPDMA1_Channel3_IRQHandler,Default_Handler + + .weak HPDMA1_Channel4_IRQHandler + .thumb_set HPDMA1_Channel4_IRQHandler,Default_Handler + + .weak HPDMA1_Channel5_IRQHandler + .thumb_set HPDMA1_Channel5_IRQHandler,Default_Handler + + .weak HPDMA1_Channel6_IRQHandler + .thumb_set HPDMA1_Channel6_IRQHandler,Default_Handler + + .weak HPDMA1_Channel7_IRQHandler + .thumb_set HPDMA1_Channel7_IRQHandler,Default_Handler + + .weak SAI1_A_IRQHandler + .thumb_set SAI1_A_IRQHandler,Default_Handler + + .weak SAI1_B_IRQHandler + .thumb_set SAI1_B_IRQHandler,Default_Handler + + .weak SAI2_A_IRQHandler + .thumb_set SAI2_A_IRQHandler,Default_Handler + + .weak SAI2_B_IRQHandler + .thumb_set SAI2_B_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 I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_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 UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_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 OTG_HS_IRQHandler + .thumb_set OTG_HS_IRQHandler,Default_Handler + + .weak ETH_IRQHandler + .thumb_set ETH_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak GFXTIM_IRQHandler + .thumb_set GFXTIM_IRQHandler,Default_Handler + + .weak DCMIPP_IRQHandler + .thumb_set DCMIPP_IRQHandler,Default_Handler + + .weak LTDC_IRQHandler + .thumb_set LTDC_IRQHandler,Default_Handler + + .weak LTDC_ER_IRQHandler + .thumb_set LTDC_ER_IRQHandler,Default_Handler + + .weak DMA2D_IRQHandler + .thumb_set DMA2D_IRQHandler,Default_Handler + + .weak JPEG_IRQHandler + .thumb_set JPEG_IRQHandler,Default_Handler + + .weak GFXMMU_IRQHandler + .thumb_set GFXMMU_IRQHandler,Default_Handler + + .weak I3C1_WKUP_IRQHandler + .thumb_set I3C1_WKUP_IRQHandler,Default_Handler + + .weak MCE1_IRQHandler + .thumb_set MCE1_IRQHandler,Default_Handler + + .weak MCE2_IRQHandler + .thumb_set MCE2_IRQHandler,Default_Handler + + .weak MCE3_IRQHandler + .thumb_set MCE3_IRQHandler,Default_Handler + + .weak XSPI1_IRQHandler + .thumb_set XSPI1_IRQHandler,Default_Handler + + .weak XSPI2_IRQHandler + .thumb_set XSPI2_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_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 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 LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_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 SPDIF_RX_IRQHandler + .thumb_set SPDIF_RX_IRQHandler,Default_Handler + + .weak MDIOS_IRQHandler + .thumb_set MDIOS_IRQHandler,Default_Handler + + .weak ADF1_FLT0_IRQHandler + .thumb_set ADF1_FLT0_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak PSSI_IRQHandler + .thumb_set PSSI_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak WAKEUP_PIN_IRQHandler + .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler + + .weak GPDMA1_Channel8_IRQHandler + .thumb_set GPDMA1_Channel8_IRQHandler,Default_Handler + + .weak GPDMA1_Channel9_IRQHandler + .thumb_set GPDMA1_Channel9_IRQHandler,Default_Handler + + .weak GPDMA1_Channel10_IRQHandler + .thumb_set GPDMA1_Channel10_IRQHandler,Default_Handler + + .weak GPDMA1_Channel11_IRQHandler + .thumb_set GPDMA1_Channel11_IRQHandler,Default_Handler + + .weak GPDMA1_Channel12_IRQHandler + .thumb_set GPDMA1_Channel12_IRQHandler,Default_Handler + + .weak GPDMA1_Channel13_IRQHandler + .thumb_set GPDMA1_Channel13_IRQHandler,Default_Handler + + .weak GPDMA1_Channel14_IRQHandler + .thumb_set GPDMA1_Channel14_IRQHandler,Default_Handler + + .weak GPDMA1_Channel15_IRQHandler + .thumb_set GPDMA1_Channel15_IRQHandler,Default_Handler + + .weak HPDMA1_Channel8_IRQHandler + .thumb_set HPDMA1_Channel8_IRQHandler,Default_Handler + + .weak HPDMA1_Channel9_IRQHandler + .thumb_set HPDMA1_Channel9_IRQHandler,Default_Handler + + .weak HPDMA1_Channel10_IRQHandler + .thumb_set HPDMA1_Channel10_IRQHandler,Default_Handler + + .weak HPDMA1_Channel11_IRQHandler + .thumb_set HPDMA1_Channel11_IRQHandler,Default_Handler + + .weak HPDMA1_Channel12_IRQHandler + .thumb_set HPDMA1_Channel12_IRQHandler,Default_Handler + + .weak HPDMA1_Channel13_IRQHandler + .thumb_set HPDMA1_Channel13_IRQHandler,Default_Handler + + .weak HPDMA1_Channel14_IRQHandler + .thumb_set HPDMA1_Channel14_IRQHandler,Default_Handler + + .weak HPDMA1_Channel15_IRQHandler + .thumb_set HPDMA1_Channel15_IRQHandler,Default_Handler + + .weak GPU2D_IRQHandler + .thumb_set GPU2D_IRQHandler,Default_Handler + + .weak GPU2D_ER_IRQHandler + .thumb_set GPU2D_ER_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_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 FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak SystemInit \ No newline at end of file diff --git a/gcc/startup_stm32h7s7l8hxh_boot.s b/gcc/startup_stm32h7s7l8hxh_boot.s new file mode 100644 index 0000000..e6124df --- /dev/null +++ b/gcc/startup_stm32h7s7l8hxh_boot.s @@ -0,0 +1,780 @@ +/** + ****************************************************************************** + * @file startup_stm32h7s7xx.s + * @author MCD Application Team + * @brief STM32H7S7xx Devices vector table for 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 + * - 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-m7 + .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 STM32H7S7xx 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 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + /* External Interrupts */ + .word PVD_PVM_IRQHandler /* PVD/PVM through EXTI Line detection */ + .word 0 /* Reserved */ + .word DTS_IRQHandler /* Digital Temperature Sensor */ + .word IWDG_IRQHandler /* Internal Watchdog */ + .word WWDG_IRQHandler /* Window Watchdog */ + .word RCC_IRQHandler /* RCC global interrupts through EXTI Line detection */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FLASH_IRQHandler /* FLASH interrupts */ + .word RAMECC_IRQHandler /* RAMECC interrupts */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word TAMP_IRQHandler /* Tamper and TimeStamp interrupts */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word EXTI5_IRQHandler /* EXTI Line5 */ + .word EXTI6_IRQHandler /* EXTI Line6 */ + .word EXTI7_IRQHandler /* EXTI Line7 */ + .word EXTI8_IRQHandler /* EXTI Line8 */ + .word EXTI9_IRQHandler /* EXTI Line9 */ + .word EXTI10_IRQHandler /* EXTI Line10 */ + .word EXTI11_IRQHandler /* EXTI Line11 */ + .word EXTI12_IRQHandler /* EXTI Line12 */ + .word EXTI13_IRQHandler /* EXTI Line13 */ + .word EXTI14_IRQHandler /* EXTI Line14 */ + .word EXTI15_IRQHandler /* EXTI Line15 */ + .word RTC_IRQHandler /* RTC wakeup and alarm interrupts */ + .word SAES_IRQHandler /* SAES */ + .word CRYP_IRQHandler /* CRYP */ + .word PKA_IRQHandler /* PKA */ + .word HASH_IRQHandler /* HASH */ + .word RNG_IRQHandler /* RNG */ + .word ADC1_2_IRQHandler /* ADC1 & ADC2 */ + .word GPDMA1_Channel0_IRQHandler /* GPDMA1 Channel 0 */ + .word GPDMA1_Channel1_IRQHandler /* GPDMA1 Channel 1 */ + .word GPDMA1_Channel2_IRQHandler /* GPDMA1 Channel 2 */ + .word GPDMA1_Channel3_IRQHandler /* GPDMA1 Channel 3 */ + .word GPDMA1_Channel4_IRQHandler /* GPDMA1 Channel 4 */ + .word GPDMA1_Channel5_IRQHandler /* GPDMA1 Channel 5 */ + .word GPDMA1_Channel6_IRQHandler /* GPDMA1 Channel 6 */ + .word GPDMA1_Channel7_IRQHandler /* GPDMA1 Channel 7 */ + .word TIM1_BRK_IRQHandler /* TIM1 Break */ + .word TIM1_UP_IRQHandler /* TIM1 Update */ + .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word TIM5_IRQHandler /* TIM5 */ + .word TIM6_IRQHandler /* TIM6 */ + .word TIM7_IRQHandler /* TIM7 */ + .word TIM9_IRQHandler /* TIM9 */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word SPI3_IRQHandler /* SPI3 */ + .word SPI4_IRQHandler /* SPI4 */ + .word SPI5_IRQHandler /* SPI5 */ + .word SPI6_IRQHandler /* SPI6 */ + .word HPDMA1_Channel0_IRQHandler /* HPDMA1 Channel 0 */ + .word HPDMA1_Channel1_IRQHandler /* HPDMA1 Channel 1 */ + .word HPDMA1_Channel2_IRQHandler /* HPDMA1 Channel 2 */ + .word HPDMA1_Channel3_IRQHandler /* HPDMA1 Channel 3 */ + .word HPDMA1_Channel4_IRQHandler /* HPDMA1 Channel 4 */ + .word HPDMA1_Channel5_IRQHandler /* HPDMA1 Channel 5 */ + .word HPDMA1_Channel6_IRQHandler /* HPDMA1 Channel 6 */ + .word HPDMA1_Channel7_IRQHandler /* HPDMA1 Channel 7 */ + .word SAI1_A_IRQHandler /* Serial Audio Interface 1 block A */ + .word SAI1_B_IRQHandler /* Serial Audio Interface 1 block B */ + .word SAI2_A_IRQHandler /* Serial Audio Interface 2 block A */ + .word SAI2_B_IRQHandler /* Serial Audio Interface 2 block B */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word I2C3_EV_IRQHandler /* I2C3 Event */ + .word I2C3_ER_IRQHandler /* I2C3 Error */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_IRQHandler /* USART3 */ + .word UART4_IRQHandler /* UART4 */ + .word UART5_IRQHandler /* UART5 */ + .word UART7_IRQHandler /* UART7 */ + .word UART8_IRQHandler /* UART8 */ + .word I3C1_EV_IRQHandler /* I3C1 Event */ + .word I3C1_ER_IRQHandler /* I3C1 Error */ + .word OTG_HS_IRQHandler /* USB OTG HS */ + .word ETH_IRQHandler /* Ethernet */ + .word CORDIC_IRQHandler /* CORDIC */ + .word GFXTIM_IRQHandler /* GFXTIM */ + .word DCMIPP_IRQHandler /* DCMIPP */ + .word LTDC_IRQHandler /* LTDC */ + .word LTDC_ER_IRQHandler /* LTDC error */ + .word DMA2D_IRQHandler /* DMA2D */ + .word JPEG_IRQHandler /* JPEG */ + .word GFXMMU_IRQHandler /* GFXMMU */ + .word I3C1_WKUP_IRQHandler /* I3C1 wakeup */ + .word MCE1_IRQHandler /* MCE1 */ + .word MCE2_IRQHandler /* MCE2 */ + .word MCE3_IRQHandler /* MCE3 */ + .word XSPI1_IRQHandler /* XSPI1 */ + .word XSPI2_IRQHandler /* XSPI2 */ + .word FMC_IRQHandler /* FMC */ + .word SDMMC1_IRQHandler /* SDMMC1 */ + .word SDMMC2_IRQHandler /* SDMMC2 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word TIM12_IRQHandler /* TIM12 */ + .word TIM13_IRQHandler /* TIM13 */ + .word TIM14_IRQHandler /* TIM14 */ + .word TIM15_IRQHandler /* TIM15 */ + .word TIM16_IRQHandler /* TIM16 */ + .word TIM17_IRQHandler /* TIM17 */ + .word LPTIM1_IRQHandler /* LP TIM1 */ + .word LPTIM2_IRQHandler /* LP TIM2 */ + .word LPTIM3_IRQHandler /* LP TIM3 */ + .word LPTIM4_IRQHandler /* LP TIM4 */ + .word LPTIM5_IRQHandler /* LP TIM5 */ + .word SPDIF_RX_IRQHandler /* SPDIF_RX */ + .word MDIOS_IRQHandler /* MDIOS */ + .word ADF1_FLT0_IRQHandler /* ADF1 Filter 0 */ + .word CRS_IRQHandler /* CRS */ + .word UCPD1_IRQHandler /* UCPD1 */ + .word CEC_IRQHandler /* HDMI_CEC */ + .word PSSI_IRQHandler /* PSSI */ + .word LPUART1_IRQHandler /* LP UART1 */ + .word WAKEUP_PIN_IRQHandler /* Wake-up pins interrupt */ + .word GPDMA1_Channel8_IRQHandler /* GPDMA1 Channel 8 */ + .word GPDMA1_Channel9_IRQHandler /* GPDMA1 Channel 9 */ + .word GPDMA1_Channel10_IRQHandler /* GPDMA1 Channel 10 */ + .word GPDMA1_Channel11_IRQHandler /* GPDMA1 Channel 11 */ + .word GPDMA1_Channel12_IRQHandler /* GPDMA1 Channel 12 */ + .word GPDMA1_Channel13_IRQHandler /* GPDMA1 Channel 13 */ + .word GPDMA1_Channel14_IRQHandler /* GPDMA1 Channel 14 */ + .word GPDMA1_Channel15_IRQHandler /* GPDMA1 Channel 15 */ + .word HPDMA1_Channel8_IRQHandler /* HPDMA1 Channel 8 */ + .word HPDMA1_Channel9_IRQHandler /* HPDMA1 Channel 9 */ + .word HPDMA1_Channel10_IRQHandler /* HPDMA1 Channel 10 */ + .word HPDMA1_Channel11_IRQHandler /* HPDMA1 Channel 11 */ + .word HPDMA1_Channel12_IRQHandler /* HPDMA1 Channel 12 */ + .word HPDMA1_Channel13_IRQHandler /* HPDMA1 Channel 13 */ + .word HPDMA1_Channel14_IRQHandler /* HPDMA1 Channel 14 */ + .word HPDMA1_Channel15_IRQHandler /* HPDMA1 Channel 15 */ + .word GPU2D_IRQHandler /* GPU2D */ + .word GPU2D_ER_IRQHandler /* GPU2D error */ + .word ICACHE_IRQHandler /* ICACHE */ + .word FDCAN1_IT0_IRQHandler /* FDCAN1 Interrupt 0 */ + .word FDCAN1_IT1_IRQHandler /* FDCAN1 Interrupt 1 */ + .word FDCAN2_IT0_IRQHandler /* FDCAN2 Interrupt 0 */ + .word FDCAN2_IT1_IRQHandler /* FDCAN2 Interrupt 1 */ + +/******************************************************************************* +* +* 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 PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RAMECC_IRQHandler + .thumb_set RAMECC_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_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 RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak SAES_IRQHandler + .thumb_set SAES_IRQHandler,Default_Handler + + .weak CRYP_IRQHandler + .thumb_set CRYP_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak ADC1_2_IRQHandler + .thumb_set ADC1_2_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 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 TIM9_IRQHandler + .thumb_set TIM9_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 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 HPDMA1_Channel0_IRQHandler + .thumb_set HPDMA1_Channel0_IRQHandler,Default_Handler + + .weak HPDMA1_Channel1_IRQHandler + .thumb_set HPDMA1_Channel1_IRQHandler,Default_Handler + + .weak HPDMA1_Channel2_IRQHandler + .thumb_set HPDMA1_Channel2_IRQHandler,Default_Handler + + .weak HPDMA1_Channel3_IRQHandler + .thumb_set HPDMA1_Channel3_IRQHandler,Default_Handler + + .weak HPDMA1_Channel4_IRQHandler + .thumb_set HPDMA1_Channel4_IRQHandler,Default_Handler + + .weak HPDMA1_Channel5_IRQHandler + .thumb_set HPDMA1_Channel5_IRQHandler,Default_Handler + + .weak HPDMA1_Channel6_IRQHandler + .thumb_set HPDMA1_Channel6_IRQHandler,Default_Handler + + .weak HPDMA1_Channel7_IRQHandler + .thumb_set HPDMA1_Channel7_IRQHandler,Default_Handler + + .weak SAI1_A_IRQHandler + .thumb_set SAI1_A_IRQHandler,Default_Handler + + .weak SAI1_B_IRQHandler + .thumb_set SAI1_B_IRQHandler,Default_Handler + + .weak SAI2_A_IRQHandler + .thumb_set SAI2_A_IRQHandler,Default_Handler + + .weak SAI2_B_IRQHandler + .thumb_set SAI2_B_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 I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_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 UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_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 OTG_HS_IRQHandler + .thumb_set OTG_HS_IRQHandler,Default_Handler + + .weak ETH_IRQHandler + .thumb_set ETH_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak GFXTIM_IRQHandler + .thumb_set GFXTIM_IRQHandler,Default_Handler + + .weak DCMIPP_IRQHandler + .thumb_set DCMIPP_IRQHandler,Default_Handler + + .weak LTDC_IRQHandler + .thumb_set LTDC_IRQHandler,Default_Handler + + .weak LTDC_ER_IRQHandler + .thumb_set LTDC_ER_IRQHandler,Default_Handler + + .weak DMA2D_IRQHandler + .thumb_set DMA2D_IRQHandler,Default_Handler + + .weak JPEG_IRQHandler + .thumb_set JPEG_IRQHandler,Default_Handler + + .weak GFXMMU_IRQHandler + .thumb_set GFXMMU_IRQHandler,Default_Handler + + .weak I3C1_WKUP_IRQHandler + .thumb_set I3C1_WKUP_IRQHandler,Default_Handler + + .weak MCE1_IRQHandler + .thumb_set MCE1_IRQHandler,Default_Handler + + .weak MCE2_IRQHandler + .thumb_set MCE2_IRQHandler,Default_Handler + + .weak MCE3_IRQHandler + .thumb_set MCE3_IRQHandler,Default_Handler + + .weak XSPI1_IRQHandler + .thumb_set XSPI1_IRQHandler,Default_Handler + + .weak XSPI2_IRQHandler + .thumb_set XSPI2_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_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 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 LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_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 SPDIF_RX_IRQHandler + .thumb_set SPDIF_RX_IRQHandler,Default_Handler + + .weak MDIOS_IRQHandler + .thumb_set MDIOS_IRQHandler,Default_Handler + + .weak ADF1_FLT0_IRQHandler + .thumb_set ADF1_FLT0_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak PSSI_IRQHandler + .thumb_set PSSI_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak WAKEUP_PIN_IRQHandler + .thumb_set WAKEUP_PIN_IRQHandler,Default_Handler + + .weak GPDMA1_Channel8_IRQHandler + .thumb_set GPDMA1_Channel8_IRQHandler,Default_Handler + + .weak GPDMA1_Channel9_IRQHandler + .thumb_set GPDMA1_Channel9_IRQHandler,Default_Handler + + .weak GPDMA1_Channel10_IRQHandler + .thumb_set GPDMA1_Channel10_IRQHandler,Default_Handler + + .weak GPDMA1_Channel11_IRQHandler + .thumb_set GPDMA1_Channel11_IRQHandler,Default_Handler + + .weak GPDMA1_Channel12_IRQHandler + .thumb_set GPDMA1_Channel12_IRQHandler,Default_Handler + + .weak GPDMA1_Channel13_IRQHandler + .thumb_set GPDMA1_Channel13_IRQHandler,Default_Handler + + .weak GPDMA1_Channel14_IRQHandler + .thumb_set GPDMA1_Channel14_IRQHandler,Default_Handler + + .weak GPDMA1_Channel15_IRQHandler + .thumb_set GPDMA1_Channel15_IRQHandler,Default_Handler + + .weak HPDMA1_Channel8_IRQHandler + .thumb_set HPDMA1_Channel8_IRQHandler,Default_Handler + + .weak HPDMA1_Channel9_IRQHandler + .thumb_set HPDMA1_Channel9_IRQHandler,Default_Handler + + .weak HPDMA1_Channel10_IRQHandler + .thumb_set HPDMA1_Channel10_IRQHandler,Default_Handler + + .weak HPDMA1_Channel11_IRQHandler + .thumb_set HPDMA1_Channel11_IRQHandler,Default_Handler + + .weak HPDMA1_Channel12_IRQHandler + .thumb_set HPDMA1_Channel12_IRQHandler,Default_Handler + + .weak HPDMA1_Channel13_IRQHandler + .thumb_set HPDMA1_Channel13_IRQHandler,Default_Handler + + .weak HPDMA1_Channel14_IRQHandler + .thumb_set HPDMA1_Channel14_IRQHandler,Default_Handler + + .weak HPDMA1_Channel15_IRQHandler + .thumb_set HPDMA1_Channel15_IRQHandler,Default_Handler + + .weak GPU2D_IRQHandler + .thumb_set GPU2D_IRQHandler,Default_Handler + + .weak GPU2D_ER_IRQHandler + .thumb_set GPU2D_ER_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_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 FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak SystemInit \ No newline at end of file diff --git a/gcc/syscalls.c b/gcc/syscalls.c new file mode 100644 index 0000000..c6f50f2 --- /dev/null +++ b/gcc/syscalls.c @@ -0,0 +1,176 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 +#include +#include +#include +#include +#include +#include +#include + + +/* Variables */ +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + + +char *__env[1] = { 0 }; +char **environ = __env; + + +/* Functions */ +void initialise_monitor_handles() +{ +} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit (int status) +{ + _kill(status, -1); + while (1) {} /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + (void)file; + return -1; +} + + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/gcc/sysmem.c b/gcc/sysmem.c new file mode 100644 index 0000000..17a2c3a --- /dev/null +++ b/gcc/sysmem.c @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Generated by STM32CubeIDE + * @brief STM32CubeIDE System Memory calls file + * + * For more information about which C functions + * need which of these lowlevel functions + * please consult the newlib libc manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in 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 +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc + * and others from the C library + * + * @verbatim + * ############################################################################ + * # .data # .bss # newlib heap # MSP stack # + * # # # # Reserved by _Min_Stack_Size # + * ############################################################################ + * ^-- RAM start ^-- _end _estack, RAM end --^ + * @endverbatim + * + * This implementation starts allocating at the '_end' linker symbol + * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack + * The implementation considers '_estack' linker symbol to be RAM end + * NOTE: If the MSP stack, at any point during execution, grows larger than the + * reserved size, please increase the '_Min_Stack_Size'. + * + * @param incr Memory size + * @return Pointer to allocated memory + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + const uint8_t *max_heap = (uint8_t *)stack_limit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) + { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into the reserved MSP stack */ + if (__sbrk_heap_end + incr > max_heap) + { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..bd74586 --- /dev/null +++ b/readme.md @@ -0,0 +1,22 @@ +# STM32H7S78-DK TBS + +Performance testing can be done using the GPIO pins designated with the following signals in CN10 connector on the underside of the board: + +- VSYNC_FREQ - CN14-D2 (PF1) +- RENDER_TIME - CN14-D4 (PF2) +- FRAME_RATE - CN14-D7 (PF3) +- MCU_ACTIVE - CN15-D8 (PF4) + +## Debugging in STM32CubeIDE +Debugging the code in an IDE can be complex because of the Bootloader and Application structure of the TBS for STM32H7S78-DK. To step through the code of the TouchGFX application in STM32CubeIDE, follow these steps: +1. Generate code in TouchGFX Designer +2. Open the project in STM32CubeIDE +3. Launch a debug session for the Boot project +4. Wait for the compilation and flashing to complete +5. Terminate the debug session (Ctrl + F2) +6. Launch a debug session for the Appli project +7. Wait for the compilation and flashing to complete +8. Click Resume (F8) +9. Press the black NRST button on the STM32H7S7-DK board +10. The application is now at a break point at the first line of main() in the Appli project. If not, click Resume (F8) once more +11. Proceed by e.g. clicking Resume (F8) or Step Over (F6) \ No newline at end of file

    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%0D}I;}Gw6 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 z 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�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,Hm7Hhvvtn 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

S5oEk`P8ZWGMs7qga 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

+
+
+

Release Notes for BSP Common Components Drivers

+

Copyright © 2014-2023 STMicroelectronics
+

+
+
+

Purpose

+

This directory contains the BSP Common components drivers.

+
+
+

Update History

+
+ +
+

Main Changes

+

Component release

+
    +
  • Add Frequency, Exposure and Gain configuration function pointers in camera.h
  • +
+
+
+
+ +
+

Main Changes

+

Component release

+
    +
  • Update licensing
  • +
+
+
+
+ +
+

Main Changes

+

Component release

+
    +
  • Add hybrid_sensor.h to support hybrid (env and motion) sensors
  • +
+
+
+
+ +
+

Main Changes

+

Component release

+
    +
  • Add ranging_sensor.h to support ranging sensors
  • +
  • Add light_sensor.h to support ambient light sensors
  • +
  • Rename UTILS_LCD_Drv_t structure into LCD_UTILS_Drv_t
  • +
  • Code spelling and formatting
  • +
+

Backward Compatibility

+
    +
  • This release breaks compatibility with previous versions.
  • +
+
+
+
+ +
+

Main Changes

+

Component release

+
    +
  • Rename GUI_Drv_t structure into UTILS_LCD_Drv_t
  • +
+

Backward Compatibility

+
    +
  • This release breaks compatibility with previous versions.
  • +
+
+
+
+ +
+

Main Changes

+

Component release

+
    +
  • Update st_logo.png inclusion path in Release notes.
  • +
+
+
+
+ +
+

Main Changes

+

Component release

+

Official release of BSP Common components drivers in line with STM32Cube BSP drivers development guidelines (UM2298).

+

Backward Compatibility

+

This release breaks compatibility with previous versions.

+
+
+
+ +
+

Main Changes

+

Reformat the BSD 3-Clause license declaration in the files header (replace license terms by a web reference to OSI website where those terms lie)
+Correct sensor names in headers files hsensor.h and psensor.h

+
+
+
+ +
+

Main Changes

+

Add dpredriver.h: support of DP redriver class
+Add pwrmon.h: support of power monitor class
+Add usbtypecswitch.h: support of USB type C switch class

+
+
+
+ +
+

Main Changes

+

Add hsensor.h: support of humidity class
+Add psensor.h: support of pressure class
+Update tsensor.h: Temperature can be negative
+Update accelero.h: LowPower API can enable or disable the low power mode
+Update magneto.h: LowPower API can enable or disable the low power mode

+

Backward Compatibility

+

This release breaks compatibility with previous versions.

+
+
+
+ +
+

Main Changes

+

tsensor.h: Fix compilation issue on TSENSOR_InitTypeDef

+
+
+
+ +
+

Main Changes

+

accelero.h: add DeInit field in ACCELERO_DrvTypeDef structure
+audio.h: add DeInit field in AUDIO_DrvTypeDef structure
+idd.h:

+
    +
  • add Shunt0StabDelay, Shunt1StabDelay, Shunt2StabDelay, Shunt3StabDelay, Shunt4StabDelay and ShuntNbOnBoard fields in IDD_ConfigTypeDef structure
    +
  • +
  • rename ShuntNumber field to ShuntNbUsed in IDD_ConfigTypeDef structure
  • +
+

magneto.h: add DeInit field in MAGNETO_DrvTypeDef structure

+

Backward Compatibility

+

This release breaks compatibility with previous versions.

+
+
+
+ +
+

Main Changes

+

accelero.h: add LowPower field in ACCELERO_DrvTypeDef structure
+magneto.h: add LowPower field in MAGNETO_DrvTypeDef structure
+gyro.h: add DeInit and LowPower fields in GYRO_DrvTypeDef structure
+camera.h: add CAMERA_COLOR_EFFECT_NONE define
+idd.h:

+
    +
  • add MeasureNb, DeltaDelayUnit and DeltaDelayValue fields in IDD_ConfigTypeDef structure
    +
  • +
  • rename PreDelay field to PreDelayUnit in IDD_ConfigTypeDef structure
  • +
+

Backward Compatibility

+

This release breaks compatibility with previous versions.

+
+
+
+ +
+

Main Changes

+

Magnetometer driver function prototypes added (magneto.h file)
+Update “idd.h” file to provide DeInit() and WakeUp() services in IDD current measurement driver

+
+
+
+ +
+

Main Changes

+

IDD current measurement driver function prototypes added (idd.h file)
+io.h: add new typedef enum IO_PinState with IO_PIN_RESET and IO_PIN_SET values

+
+
+
+ +
+

Main Changes

+

Update “io.h” file to support MFX (Multi Function eXpander) device available on some STM32 boards

+
    +
  • add new entries for IO_ModeTypedef enumeration structure
  • +
  • update the IO_DrvTypeDef structure
  • +
  • Update all return values and function parameters to uint32_t
  • +
  • Add a return value for Config field
  • +
+

Backward Compatibility

+

This release breaks compatibility with previous versions.

+
+
+
+ +
+

Main Changes

+

gyro.h: change “__GIRO_H” by “__GYRO_H” to fix compilation issue under Mac OS

+
+
+
+ +
+

Main Changes

+

EPD (E Paper Display) driver function prototype added (epd.h file)

+
+
+
+ +
+

Main Changes

+

Temperature Sensor driver function prototype added

+
+
+
+ +
+

Main Changes

+

First official release with Accelerometer, Audio, Camera, Gyroscope, IO, LCD and Touch Screen drivers function prototypes

+
+
+
+